Exemple #1
0
//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;
}
Exemple #2
0
//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);
}
Exemple #3
0
/*
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;
}
Exemple #4
0
/*
 * 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);
}