pUsbApi->core->RegisterClassHandler(hUsb, EP0_hdlr, NULL); |
ErrorCode_t EP0_hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event) { evnts[numEvt++] = event; if (event == USB_EVT_SETUP) { USB_SETUP_PACKET packet; uint32_t len = pUsbApi->hw->ReadSetupPkt(hUsb, USB_ENDPOINT_OUT(0), (uint32_t*)&packet); if ((packet.bmRequestType.B & 0x7F) == 0x21) { // Type=Class, Recipient=Interface if (packet.wIndex.W == 2) { // OSC CDC CIF interface (2) switch (packet.bRequest) { case 0x20: { // SET_LINE_CODING if (packet.wLength != 7) return ERR_USBD_INVALID_REQ; return LPC_OK; } case 0x21: { // GET_LINE_CODING if (packet.wLength != 7) return ERR_USBD_INVALID_REQ; uint8_t lcs[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }; pUsbApi->hw->WriteEP(pUsbHandle, USB_ENDPOINT_IN(0), lcs, 7); return LPC_OK; } case 0x22: { // SET_CONTROL_LINE_STATE if (packet.wLength != 0) return ERR_USBD_INVALID_REQ; pUsbApi->hw->WriteEP(pUsbHandle, USB_ENDPOINT_IN(0), NULL, 0); return LPC_OK; } } } } } else if (event == USB_EVT_OUT) { numEvtOut++; lenEvtOut += pUsbApi->hw->ReadEP(hUsb, USB_ENDPOINT_OUT(0), (uint8_t*)tmpStpBuf); } else if (event == USB_EVT_IN) { } return ERR_USBD_UNHANDLED; } |
ErrorCode_t EP0_hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event) { if (numEvt < 100) evnts[numEvt] = event; numEvt++; USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb; static USB_SETUP_PACKET setup; pUsbApi->hw->ReadSetupPkt( hUsb, USB_ENDPOINT_OUT(0), (uint32_t *)&setup ); switch (event) { case USB_EVT_SETUP: pCtrl->EP0Data.Count = setup.wLength; // Number of bytes to transfer if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_HOST_TO_DEVICE,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == 0x20 ) // SetLineCoding && (setup.wValue.W == (0<<8) ) // descriptor type | index && (setup.wIndex.W == 2) ) { numEvtSetLineCoding++; tmpStpBuf[0] = 0xFE; pCtrl->EP0Data.pData = (uint8_t*)tmpStpBuf; pCtrl->EP0Data.Count = 7; //pUsbApi->core->DataOutStage( hUsb ); pUsbApi->core->StatusInStage(hUsb); return LPC_OK; } if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_DEVICE_TO_HOST,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == 0x21 ) // GetLineCoding && (setup.wValue.W == (0<<8) ) // Report type | Report ID && (setup.wIndex.W == 2 ) ) { uint8_t lcs[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }; pCtrl->EP0Data.Count = 7; pCtrl->EP0Data.pData = (uint8_t*)&lcs; pUsbApi->core->DataInStage(hUsb); return LPC_OK; } if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_HOST_TO_DEVICE,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == 0x22 ) // SetControlLineState && (setup.wIndex.W == 2) ) { numEvtSetControlLineState++; pUsbApi->core->StatusInStage(hUsb); return LPC_OK; } break; case USB_EVT_OUT: numEvtOut++; if (pCtrl->EP0Data.Count > 0) { pUsbApi->core->DataOutStage(hUsb); return LPC_OK; } else { pUsbApi->core->StatusInStage(hUsb); return LPC_OK; } break; case USB_EVT_IN: if (pCtrl->EP0Data.Count > 0) { pUsbApi->core->DataInStage( hUsb ); return LPC_OK; } else { pUsbApi->core->StatusOutStage( hUsb ); return LPC_OK; } break; default: break; } return ERR_USBD_UNHANDLED; } |
pUsbApi->core->DataOutStage( hUsb ); // receive data |
pCtrl->EP0Data.Count |
pCtrl->EP0Data.pData |
pUsbApi->core->DataOutStage( hUsb ); |
ErrorCode_t EP0_hdlr(USBD_HANDLE_T hUsb, void* data, uint32_t event) { evnts[numEvt++] = event; USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb; static USB_SETUP_PACKET setup; switch( event ) { case USB_EVT_SETUP: // Get SETUP packet pUsbApi->hw->ReadSetupPkt( hUsb, USB_ENDPOINT_OUT(0), (uint32_t *)&setup ); // pick up Control Read transfer: Get_Descriptor(HID_REPORT) pCtrl->EP0Data.Count = setup.wLength; // Number of bytes to transfer if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_HOST_TO_DEVICE,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == 0x20 ) // SetLineCoding && (setup.wValue.W == (0<<8) ) // descriptor type | index && (setup.wIndex.W == 2) ) { numEvtSetLineCoding++; tmpStpBuf[0] = 0xFE; pCtrl->EP0Data.pData = (uint8_t*)tmpStpBuf; req_num = REQ_CTRL_WRITE; //pUsbApi->core->DataOutStage( hUsb ); return LPC_OK; } if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_DEVICE_TO_HOST,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == 0x21 ) // GetLineCoding && (setup.wValue.W == (0<<8) ) // Report type | Report ID && (setup.wIndex.W == 2 ) ) { uint8_t lcs[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }; Control_Read( hUsb, (uint8_t*)&lcs, 7 ); return LPC_OK; } break; case USB_EVT_OUT: numEvtOut++; //lenEvtOut += pUsbApi->hw->ReadEP(hUsb, USB_ENDPOINT_OUT(0), (uint8_t*)tmpStpBuf); if ( req_num == REQ_CTRL_WRITE ) { if (pCtrl->EP0Data.Count) { // still data to receive ? pUsbApi->core->DataOutStage( hUsb ); // receive data } if (pCtrl->EP0Data.Count == 0) { // data complete ? // // process data on the buffer, here // pUsbApi->core->StatusInStage( hUsb ); //pUsbApi->hw->WriteEP(pUsbHandle, USB_ENDPOINT_IN(0), NULL, 0); req_num = REQ_NO_REQ; } return LPC_OK; } break; case USB_EVT_IN: if ( req_num == REQ_CTRL_READ ) { if ( pCtrl->EP0Data.Count ) { pUsbApi->core->DataInStage( hUsb ); } else { pUsbApi->core->StatusOutStage( hUsb ); req_num = REQ_NO_REQ; } return LPC_OK; } break; default: break; } req_num = REQ_NO_REQ; return ERR_USBD_UNHANDLED; } |
/* local data */ typedef enum { REQ_NO_REQ, REQ_CTRL_READ, REQ_CTRL_WRITE, REQ_NO_DATA_CTRL, } REQ_NUM_T; static REQ_NUM_T req_num = REQ_NO_REQ; static void Control_Read( USBD_HANDLE_T hUsb, uint8_t* pData, uint16_t count ) { ((USB_CORE_CTRL_T*)hUsb)->EP0Data.pData = pData; if ( ((USB_CORE_CTRL_T*)hUsb)->SetupPacket.wLength > HID_ReportDescSize ) { ((USB_CORE_CTRL_T*)hUsb)->EP0Data.Count = count; } pUsbApi->core->DataInStage( hUsb ); req_num = REQ_CTRL_READ; } #define REQ_TYPE( direction, type, recipient ) ((direction<<7)|(type<<5)|recipient) #define HID_INTERFACE_NUM 0 ErrorCode_t request_Hdlr( USBD_HANDLE_T hUsb, void* data, uint32_t event ) { USB_CORE_CTRL_T* pCtrl = (USB_CORE_CTRL_T*)hUsb; static USB_SETUP_PACKET setup; switch( event ) { case USB_EVT_SETUP: // Get SETUP packet pUsbApi->hw->ReadSetupPkt( hUsb, USB_ENDPOINT_OUT(0), (uint32_t *)&setup ); // pick up Control Read transfer: Get_Descriptor(HID_REPORT) pCtrl->EP0Data.Count = setup.wLength; // Number of bytes to transfer if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_DEVICE_TO_HOST,REQUEST_STANDARD,REQUEST_TO_INTERFACE) ) && (setup.bRequest == USB_REQUEST_GET_DESCRIPTOR ) && (setup.wValue.W == (HID_REPORT_DESCRIPTOR_TYPE<<8) ) // descriptor type | index && (setup.wIndex.W == HID_INTERFACE_NUM ) // && (setup.wLength == 0 ) ) { Control_Read( hUsb, (uint8_t*)HID_ReportDescriptor, HID_ReportDescSize ); return LPC_OK; } // pick up Control Read transfer: GET_REPORT if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_DEVICE_TO_HOST,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == HID_REQUEST_GET_REPORT ) && (setup.wValue.W == (HID_REPORT_INPUT<<8) ) // Report type | Report ID && (setup.wIndex.W == HID_INTERFACE_NUM ) // && (setup.wLength == 1 ) ) { Control_Read( hUsb, &loopback_report, 1 ); return LPC_OK; } // pick up Control Write transfer: SET_REPORT if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_HOST_TO_DEVICE,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == HID_REQUEST_SET_REPORT ) && (setup.wValue.W == (HID_REPORT_OUTPUT<<8) ) // Report type | Report ID && (setup.wIndex.W == HID_INTERFACE_NUM ) && (setup.wLength == 1 ) ) { // set a buffer to receive the data // pCtrl->EP0Data.pData = pCtrl->EP0Buf; pCtrl->EP0Data.pData = &loopback_report; req_num = REQ_CTRL_WRITE; return LPC_OK; } // pick up no-data Control transfer if ( (setup.bmRequestType.B == REQ_TYPE(REQUEST_HOST_TO_DEVICE,REQUEST_CLASS,REQUEST_TO_INTERFACE) ) && (setup.bRequest == HID_REQUEST_SET_IDLE ) && (setup.wValue.W == 0 ) // 0 | Report ID && (setup.wIndex.W == HID_INTERFACE_NUM ) && (setup.wLength == 0 ) ) { // // process this request, here // if (1) { // when processed successfully, pUsbApi->core->StatusInStage( hUsb ); // move to STATUS stage } else { pUsbApi->core->StallEp0( hUsb ); // reject this request } req_num = REQ_NO_REQ; return LPC_OK; // The process of this request finishes by this code } break; case USB_EVT_OUT: if ( req_num == REQ_CTRL_WRITE ) { if (pCtrl->EP0Data.Count) { // still data to receive ? pUsbApi->core->DataOutStage( hUsb ); // receive data } if (pCtrl->EP0Data.Count == 0) { // data complete ? // // process data on the buffer, here // pUsbApi->core->StatusInStage( hUsb ); req_num = REQ_NO_REQ; } return LPC_OK; } break; case USB_EVT_IN: if ( req_num == REQ_CTRL_READ ) { if ( pCtrl->EP0Data.Count ) { pUsbApi->core->DataInStage( hUsb ); } else { pUsbApi->core->StatusOutStage( hUsb ); req_num = REQ_NO_REQ; } return LPC_OK; } break; default: break; } req_num = REQ_NO_REQ; return ERR_USBD_UNHANDLED; } |