//this function is used only by USB interrupt. //It fills user receiving buffer with received data BOOL HidToBufferFromHost() { BYTE * pEP1; BYTE nTmp1; BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt if (HidReadCtrl.nBytesToReceiveLeft == 0) // do we have somtething to receive? { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending return bWakeUp; } // No data to receive... if (!((tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX | tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY) & 0x80)) { return bWakeUp; } if (HidReadCtrl.bCurrentBufferXY == X_BUFFER) //X is current buffer { //this is the active EP buffer pEP1 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; } // how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl.pCT1; if(nTmp1 & EPBCNT_NAK) { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } pEP1 += 2; // here starts user data HidCopyUsbToBuff(pEP1, HidReadCtrl.pCT1); nTmp1 = *HidReadCtrl.pCT2; //try read data from second buffer if ((HidReadCtrl.nBytesToReceiveLeft > 0) && // do we have more data to send? (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data? { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(pEP1+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } HidReadCtrl.pEP2 += 2; // here starts user data HidCopyUsbToBuff(HidReadCtrl.pEP2, HidReadCtrl.pCT2); HidReadCtrl.pCT1 = HidReadCtrl.pCT2; } } if (HidReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent) { bWakeUp = USBHID_handleReceiveCompleted(1); } if (HidReadCtrl.nBytesInEp) // Is not read data still available in the EP? { if (wUsbEventMask & kUSB_dataReceivedEvent) { bWakeUp = USBHID_handleDataReceived(1); } } } return bWakeUp; }
//this function is used only by USB interrupt. //It fills user receiving buffer with received data BOOL HidToBufferFromHost (BYTE intfNum) { BYTE * pEP1; BYTE nTmp1; BYTE bWakeUp = FALSE; //per default we do not wake up after interrupt BYTE edbIndex; edbIndex = stUsbHandle[intfNum].edb_Index; if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //do we have somtething to receive? HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending return (bWakeUp); } //No data to receive... if (!((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX | tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY) & 0x80)){ return (bWakeUp); } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //X is current buffer //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; } //how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1; if (nTmp1 & EPBCNT_NAK){ nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1 + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } pEP1 += 2; //here starts user data HidCopyUsbToBuff(pEP1, HidReadCtrl[INTFNUM_OFFSET( intfNum)].pCT1,intfNum); nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; //try read data from second buffer if ((HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && //do we have more data to send? (nTmp1 & EPBCNT_NAK)){ //if the second buffer has received data? nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(pEP1 + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2; //here starts user data HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pEP2, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum); HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; } } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent){ bWakeUp = USBHID_handleReceiveCompleted(intfNum); } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //Is not read data still available in the EP? if (wUsbEventMask & kUSB_dataReceivedEvent){ bWakeUp = USBHID_handleDataReceived(intfNum); } } } return (bWakeUp); }
/* Receives data over interface intfNum, of size size, into memory starting at address data. Returns: kUSBHID_receiveStarted if the receiving process started. kUSBHID_receiveCompleted all requested date are received. kUSBHID_receiveInProgress previous receive opereation is in progress. The requested receive operation can be not started. kUSBHID_generalError error occurred. */ BYTE USBHID_receiveData(BYTE* data, WORD size, BYTE intfNum) { BYTE nTmp1; if ((size == 0) || // read size is 0 (data == NULL)) { return kUSBHID_generalError; } // atomic operation - disable interrupts __disable_interrupt(); // Disable global interrupts // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR if ((bFunctionSuspended) || (bEnumerationStatus != ENUMERATION_COMPLETE)) { __enable_interrupt(); // interrupts enable return kUSBHID_busNotAvailable; } if (HidReadCtrl.pUserBuffer != NULL) // receive process already started { __enable_interrupt(); // interrupts enable return kUSBHID_receiveInProgress; } HidReadCtrl.nBytesToReceive = size; // bytes to receive HidReadCtrl.nBytesToReceiveLeft = size; // left bytes to receive HidReadCtrl.pUserBuffer = data; // set user receive buffer //read rest of data from buffer, if any if (HidReadCtrl.nBytesInEp > 0) { // copy data from pEP-endpoint into User's buffer HidCopyUsbToBuff(HidReadCtrl.pCurrentEpPos, HidReadCtrl.pCT1); if (HidReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending USBHID_handleReceiveCompleted(1); // call event handler in interrupt context __enable_interrupt(); // interrupts enable return kUSBHID_receiveCompleted; // receive completed } // check other EP buffer for data - exchange pCT1 with pCT2 if (HidReadCtrl.pCT1 == &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX) { HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_Y_BUFFER_ADDRESS; } else { HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_X_BUFFER_ADDRESS; } nTmp1 = *HidReadCtrl.pCT1; //try read data from second buffer if (nTmp1 & EPBCNT_NAK) // if the second buffer has received data? { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(HidReadCtrl.pCurrentEpPos+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } HidReadCtrl.pCurrentEpPos += 2; // here starts user data HidCopyUsbToBuff(HidReadCtrl.pCurrentEpPos, HidReadCtrl.pCT1); } if (HidReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending USBHID_handleReceiveCompleted(1); // call event handler in interrupt context __enable_interrupt(); // interrupts enable return kUSBHID_receiveCompleted; // receive completed } } //read rest of data from buffer, if any //read 'fresh' data, if available nTmp1 = 0; if (HidReadCtrl.bCurrentBufferXY == X_BUFFER) //this is current buffer { if (tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet { //this is the active EP buffer //pEP1 HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; nTmp1 = 1; //indicate that data is available } } else // Y_BUFFER if (tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY & EPBCNT_NAK) { //this is the active EP buffer HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; nTmp1 = 1; //indicate that data is available } if (nTmp1) { // how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl.pCT1; if(nTmp1 & EPBCNT_NAK) { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(HidReadCtrl.pCurrentEpPos+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } HidReadCtrl.pCurrentEpPos += 2; // here starts user data HidCopyUsbToBuff(HidReadCtrl.pCurrentEpPos, HidReadCtrl.pCT1); nTmp1 = *HidReadCtrl.pCT2; //try read data from second buffer if ((HidReadCtrl.nBytesToReceiveLeft > 0) && // do we have more data to receive? (nTmp1 & EPBCNT_NAK)) // if the second buffer has received data? { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = *(HidReadCtrl.pEP2+1); // holds how many valid bytes in the EP buffer if (HidReadCtrl.nBytesInEp > nTmp1-2) { HidReadCtrl.nBytesInEp = nTmp1-2; } HidReadCtrl.pEP2 += 2; // here starts user data HidCopyUsbToBuff(HidReadCtrl.pEP2, HidReadCtrl.pCT2); HidReadCtrl.pCT1 = HidReadCtrl.pCT2; } } } if (HidReadCtrl.nBytesToReceiveLeft == 0) // the Receive opereation is completed { HidReadCtrl.pUserBuffer = NULL; // no more receiving pending USBHID_handleReceiveCompleted(1); // call event handler in interrupt context __enable_interrupt(); // interrupts enable return kUSBHID_receiveCompleted; } //interrupts enable __enable_interrupt(); return kUSBHID_receiveStarted; }
/* * Receives data over interface intfNum, of size size, into memory starting at address data. * Returns: * kUSBHID_receiveStarted if the receiving process started. * kUSBHID_receiveCompleted all requested date are received. * kUSBHID_receiveInProgress previous receive opereation is in progress. The requested receive operation can be not started. * kUSBHID_generalError error occurred. */ BYTE USBHID_receiveData (BYTE* data, WORD size, BYTE intfNum) { BYTE nTmp1; WORD state; BYTE edbIndex; edbIndex = stUsbHandle[intfNum].edb_Index; if ((size == 0) || //read size is 0 (data == NULL)){ return (kUSBHID_generalError); } state = usbDisableOutEndpointInterrupt(edbIndex); //atomic operation - disable interrupts //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR if ((bFunctionSuspended) || (bEnumerationStatus != ENUMERATION_COMPLETE)){ usbRestoreOutEndpointInterrupt(state); return (kUSBHID_busNotAvailable); } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){ //receive process already started usbRestoreOutEndpointInterrupt(state); return (kUSBHID_receiveInProgress); } HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size; //bytes to receive HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size; //left bytes to receive HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data; //set user receive buffer //read rest of data from buffer, if any if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){ //copy data from pEP-endpoint into User's buffer HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum); if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending USBHID_handleReceiveCompleted(intfNum); //call event handler in interrupt context usbRestoreOutEndpointInterrupt(state); return (kUSBHID_receiveCompleted); //receive completed } //check other EP buffer for data - exchange pCT1 with pCT2 if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 == &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; } else { HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; } nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1; //try read data from second buffer if (nTmp1 & EPBCNT_NAK){ //if the second buffer has received data? nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2; //here starts user data HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum); } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent){ USBHID_handleReceiveCompleted(intfNum); //call event handler in interrupt context } usbRestoreOutEndpointInterrupt(state); return (kUSBHID_receiveCompleted); //receive completed } } //read rest of data from buffer, if any //read 'fresh' data, if available nTmp1 = 0; if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //this is current buffer if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){ //this buffer has a valid data packet //this is the active EP buffer //pEP1 HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; nTmp1 = 1; //indicate that data is available } } else { //Y_BUFFER if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){ //this is the active EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY; //second EP buffer HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer; HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX; nTmp1 = 1; //indicate that data is available } } if (nTmp1){ //how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1; if (nTmp1 & EPBCNT_NAK){ nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2; //here starts user data HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pCurrentEpPos, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum); nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; //try read data from second buffer if ((HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > 0) && //do we have more data to receive? (nTmp1 & EPBCNT_NAK)){ //if the second buffer has received data? nTmp1 = nTmp1 & 0x7f; //clear NAK bit HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 + 1); //holds how many valid bytes in the EP buffer if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){ HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2; } HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2; //here starts user data HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET( intfNum)].pEP2, HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum); HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2; } } } if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL; //no more receiving pending if (wUsbEventMask & kUSB_receiveCompletedEvent){ USBHID_handleReceiveCompleted(intfNum); //call event handler in interrupt context } usbRestoreOutEndpointInterrupt(state); return (kUSBHID_receiveCompleted); } //interrupts enable usbRestoreOutEndpointInterrupt(state); return (kUSBHID_receiveStarted); }