?? usb.c
字號(hào):
/* enable reset interrupt by zeroing the mask bit */ REG_SET(®isters->UDCCR, ((REG_GET(®isters->UDCCR)) & ~UDC_UDCCR_REM)); /* enable endpoint interupts */ REG_SET(®isters->UICR0, UDC_ENABLE_ALL_INT); /* 0..7 */ REG_SET(®isters->UICR1, UDC_ENABLE_ALL_INT); /* 8..15 */ /* don't enable the Start-Of-Frame interrupt by default */ REG_SET(®isters->UFNHR, UDC_UFNHR_SIM); /* set device index */ device->deviceIndex = lastDeviceIndex++; /* hook interrupt handler ixUSBInterruptHandler(device) to UDC IRQ */ INT_BIND_MACRO(device->interruptLevel, ixUSBInterruptHandlerWrapper, device); { UINT32 i = 0; for (; i < 16 ; i++) ixOsalMutexInit(&usbBufferSubmitMutex[i]); }#ifndef IX_USB_HAS_DUMMY_MBLK /* init pool */ if ((pNetPool = IX_OSAL_MBUF_POOL_INIT(NUM_MBLKS, BLK_SIZE * 2, "USB Pool")) == NULL) { ixOsalLog (IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "IxUSBDriverInit: netPoolInit failure\n", 0, 0, 0, 0, 0, 0); return IX_FAIL; }#endif /* IX_USB_HAS_DUMMY_MBLK */ RETURN_OK(device);}PUBLIC IX_STATUSixUSBDeviceEnable(USBDevice *device, BOOL enableDevice){ UINT32 UDCCR; UDCRegisters *registers; USBDeviceContext *context; CHECK_DEVICE(device); context = CONTEXT(device); registers = context->registers; UDCCR = REG_GET(®isters->UDCCR); if (context->enabled == enableDevice) { /* device is already in desired state */ RETURN_REDUNDANT(device); } if (enableDevice) { /* enable UDC */ REG_SET(®isters->UDCCR, (UDCCR | UDC_UDCCR_UDE)); /* mark as enabled */ context->enabled = TRUE; } else { UINT16 epIndex; /* mark as disabled */ context->enabled = FALSE; /* disable UDC */ REG_SET(®isters->UDCCR, UDCCR & ~UDC_UDCCR_UDE); /* clear queue and buffers */ ixUSBEP0StateReset(device); /* Endpoint 0 is special, there's more to clean up */ for (epIndex = ENDPOINT_0 ; epIndex < NUM_ENDPOINTS ; epIndex++) { ixUSBEndpointClear(device, epIndex); } } RETURN_OK(device);}PUBLIC IX_STATUSixUSBEndpointStall(USBDevice *device, UINT16 endpointNumber, BOOL stallFlag){ volatile UINT32 *UDCCS_ptr; /* pointer to the endpoint UDCCS */ UINT32 UDCCS; /* UDCCS snapshot */ CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); CHECK_ENDPOINT(device, endpointNumber); UDCCS_ptr = EPSTATUS(device, endpointNumber)->UDCCS; UDCCS = REG_GET(UDCCS_ptr); /* take register snapshot */ /* check endpoint type - isochronous endpoints cannot be stalled according to the protocol */ if (EP_TYPE(EPDescriptorTable[endpointNumber]) == USB_ISOCHRONOUS) { RETURN_NO_STALL_CAPABILITY(device); } /* the FST (force stall) bit is in different places depending on the endpoint */ if (endpointNumber == ENDPOINT_0) /* endpoint 0 has UDC_UDCCS0_FST */ { if (stallFlag) { if (((UDCCS & UDC_UDCCS0_FST) != 0) == stallFlag) { RETURN_REDUNDANT(device); } REG_SET(UDCCS_ptr, UDC_UDCCS0_FST); } else /* cannot 'unstall' endpoint 0, this happens automatically */ { RETURN_INVALID_PARMS(device); } } else if (EP_DIRECTION(EPDescriptorTable[endpointNumber]) == USB_IN) /* USB_IN endpoints */ { if (((UDCCS & UDC_UDCCS_FST_IN) != 0) == stallFlag) { RETURN_REDUNDANT(device); } if (stallFlag) { REG_SET(UDCCS_ptr, UDC_UDCCS_FST_IN); /* stall endpoint */ } else { REG_SET(UDCCS_ptr, UDCCS & ~UDC_UDCCS_FST_IN); /* unstall endpoint */ } } else /* USB_OUT endpoints */ { IX_USB_ASSERT(EP_DIRECTION(EPDescriptorTable[endpointNumber]) == USB_OUT); if (((UDCCS & UDC_UDCCS_FST_OUT) != 0) == stallFlag) { RETURN_REDUNDANT(device); } if (stallFlag) { REG_SET(UDCCS_ptr, UDC_UDCCS_FST_OUT); /* stall endpoint */ } else { REG_SET(UDCCS_ptr, UDCCS & ~UDC_UDCCS_FST_OUT); /* unstall endpoint */ } } RETURN_OK(device);}PUBLIC IX_STATUSixUSBIsEndpointStalled(USBDevice *device, UINT16 endpointNumber, BOOL *stallState){ UINT32 UDCCS; UINT16 direction; CHECK_DEVICE(device); CHECK_ENDPOINT(device, endpointNumber); if (stallState == NULL) { RETURN_INVALID_PARMS(device); } UDCCS = REG_GET(EPSTATUS(device, endpointNumber)->UDCCS); direction = EP_DIRECTION(EPDescriptorTable[endpointNumber]); if (direction == USB_IN) { *stallState = (UDCCS & UDC_UDCCS_FST_IN) != 0; } else if (direction == USB_OUT) { *stallState = (UDCCS & UDC_UDCCS_FST_OUT) != 0; } else { IX_USB_ASSERT(direction == USB_IN_OUT); *stallState = (UDCCS & UDC_UDCCS0_FST) != 0; } RETURN_OK(device);}PUBLIC IX_STATUS ixUSBEndpointClear(USBDevice *device, UINT16 endpointNumber){ EPStatusData *epData; CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); CHECK_ENDPOINT(device, endpointNumber); epData = EPSTATUS(device, endpointNumber); /* discard data queue */ ixUSBQueueDiscard(epData); /* discard current transfer */ ixUSBTransferAbort(epData); RETURN_OK(device);}PUBLIC IX_STATUS ixUSBSignalResume(USBDevice *device){ UDCRegisters *registers; CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); registers = REGISTERS(device); /* check if the device was enabled to signal resume */ if ((REG_GET(®isters->UDCCS0) & UDC_UDCCS0_DRWF) == 0) { RETURN_NO_PERMISSION(device); } REG_SET(®isters->UDCCR, ((REG_GET(®isters->UDCCR)) | UDC_UDCCR_RSM)); RETURN_OK(device);}PUBLIC IX_STATUS ixUSBFrameCounterGet(USBDevice *device, UINT16 *counter){ UDCRegisters *registers; UINT32 UFNHR, UFNLR; /* frame number high (3 bits) and low (8 bits) */ CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); if (counter == NULL) { RETURN_INVALID_PARMS(device); } registers = REGISTERS(device); UFNHR = REG_GET(®isters->UFNHR); UFNLR = REG_GET(®isters->UFNLR); /* (UFNHR[2:0] & 0x7) << 8) + UFNLR[7..0] & 0xFF */ *counter = (((UFNHR & UDC_UFNHR_FN_MASK) << UDC_UFNHR_FN_SHIFT) | (UFNLR & UDC_UFNLR_FN_MASK)); RETURN_OK(device);}PUBLIC IX_STATUS ixUSBReceiveCallbackRegister(USBDevice *device, USBReceiveCallback callbackFunction){ CHECK_DEVICE(device); if (callbackFunction != NULL) { EVENTS(device)->receiveCallback = callbackFunction; } else { EVENTS(device)->receiveCallback = ixUSBNullReceiveCallback; } RETURN_OK(device);}PUBLIC IX_STATUS ixUSBSetupCallbackRegister(USBDevice *device, USBSetupCallback callbackFunction){ CHECK_DEVICE(device); if (callbackFunction != NULL) { EVENTS(device)->setupCallback = callbackFunction; } else { EVENTS(device)->setupCallback = ixUSBNullSetupCallback; } RETURN_OK(device);}PUBLIC voidixUSBDataSendAllow(USBDevice *device){ EPStatusData *epData = EPSTATUS(device, 1); dataSendAllowed = TRUE; IX_USB_VERBOSE4_TRACE("USB: Resuming data transfers\n", 0, 0, 0, 0, 0, 0); ixUSBRequestSend(epData);}PUBLIC voidixUSBDataSendBlock(){ dataSendAllowed = FALSE;}PUBLIC IX_STATUS ixUSBBufferSubmit(USBDevice *device, UINT16 destinationEndpoint, IX_USB_MBLK *sendBuffer){ EPStatusData *epData; IxOsalMutex *lock = &usbBufferSubmitMutex[destinationEndpoint]; CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); CHECK_ENDPOINT(device, destinationEndpoint); CHECK_ENDPOINT_STALL(device, destinationEndpoint); if (sendBuffer == NULL) { RETURN_INVALID_PARMS(device); } epData = EPSTATUS(device, destinationEndpoint); CHECK_ENDPOINT_IN_CAPABILITY(epData, device); IX_USB_VERBOSE4_TRACE("USB: Submitted %d bytes on endpoint %d, %d packets in queue\n", IX_USB_MBLK_LEN(sendBuffer), destinationEndpoint, epData->queue.len, 0, 0, 0); ixOsalMutexLock(lock, IX_OSAL_WAIT_FOREVER); if (ixUSBBufferEnqueue(epData, sendBuffer)) { if (destinationEndpoint == ENDPOINT_0) { ixUSBEP0RequestSend(device); } else { if (dataSendAllowed || destinationEndpoint != 1) { ixUSBRequestSend(epData); } else { IX_USB_TRACE("USB: Oops, packet queued, data transfers blocked\n", 0, 0, 0, 0, 0, 0); } } ixOsalMutexUnlock(lock);
RETURN_OK(device); } else { IX_USB_TRACE("USB: RETURN SEND QUEUE FULL\n", 0, 0, 0, 0, 0, 0); ixOsalMutexUnlock(lock);
RETURN_SEND_QUEUE_FULL(device); }}PUBLIC IX_STATUS ixUSBBufferCancel(USBDevice *device, UINT16 destinationEndpoint, IX_USB_MBLK *sendBuffer){ USBDataQueue *queue; UINT32 local_index;#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS UINT32 irqStatus;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */ CHECK_DEVICE(device); CHECK_DEVICE_ENABLED(device); CHECK_ENDPOINT(device, destinationEndpoint); queue = EPQUEUE(device, destinationEndpoint);#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS /* lock section */ irqStatus = IX_USB_LOCK;#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */ for (local_index = 0 ; local_index < queue->len ; local_index++) { UINT32 offset = QUEUE_WRAP(queue->head + local_index); if (queue->base[offset] == sendBuffer) { queue->base [offset] = NULL; IX_USB_MBLK_FREE(sendBuffer); } }#ifdef IX_USB_HAS_CRITICAL_DATA_LOCKS /* unlock section */ IX_USB_UNLOCK(irqStatus);#endif /* IX_USB_HAS_CRITICAL_DATA_LOCKS */ if (local_index == queue->len) { IX_USB_TRACE("USB: BUFFER NOT FOUND\n", 0, 0, 0, 0, 0, 0); RETURN_ERROR(device); /* buffer not found */ } else { RETURN_OK(device); }}PUBLIC IX_STATUS ixUSBEventCallbackRegister(USBDevice *device,
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -