/*
Sends a pre-built report reportData to the host.
  Returns:  kUSBHID_sendComplete
            kUSBHID_intfBusyError
            kUSBCDC_busNotAvailable
*/
BYTE USBHID_sendReport(const BYTE * reportData, BYTE intfNum)
{
    BYTE byte_count;
    BYTE * pEP1;
    BYTE * pCT1;
    
    BYTE edbIndex;
    edbIndex = stUsbHandle[intfNum].edb_Index;

    // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE))
    {
        return kUSBHID_busNotAvailable;
    }

    if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER)
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    }
    else
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)stUsbHandle[intfNum].iep_Y_Buffer;
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
    }

    byte_count = USBHID_REPORT_LENGTH;  // we support only one length of report

    if(*pCT1 & EPBCNT_NAK)              // if this EP is empty
    {
        USB_TX_memcpy(pEP1, reportData, byte_count);  // copy data into IEP X or Y buffer
        *pCT1 = byte_count;                           // Set counter for usb In-Transaction
        HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1)&0x01; //switch buffer
        return kUSBHID_sendComplete;
    }
    return kUSBHID_intfBusyError;
}
Exemple #2
0
//this function is used only by USB interrupt
BOOL HidToHostFromBuffer()
{
    BYTE byte_count, nTmp2;
    BYTE * pEP1;
    BYTE * pEP2;
    BYTE * pCT1;
    BYTE * pCT2;
    BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt

    if (HidWriteCtrl.nHidBytesToSendLeft == 0)           // do we have somtething to send?
    {

        HidWriteCtrl.nHidBytesToSend = 0;

        //call event callback function
        if (wUsbEventMask & kUSB_sendCompletedEvent)
        {
            bWakeUp = USBHID_handleSendCompleted(1);
        }
        return bWakeUp;
    }

    if(!(tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPCNF & EPCNF_TOGGLE))
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)IEP1_X_BUFFER_ADDRESS;
        pCT1 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX;

        //second EP buffer
        pEP2 = (BYTE*)IEP1_Y_BUFFER_ADDRESS;
        pCT2 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY;
    }
    else
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)IEP1_Y_BUFFER_ADDRESS;
        pCT1 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY;

        //second EP buffer
        pEP2 = (BYTE*)IEP1_X_BUFFER_ADDRESS;
        pCT2 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX;
    }

    // how many byte we can send over one endpoint buffer
    //  2 bytes a reserved: [0] - HID Report Descriptor, [1] - count of valid bytes
    byte_count = (HidWriteCtrl.nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl.nHidBytesToSendLeft;
    nTmp2 = *pCT1;

    if(nTmp2 & EPBCNT_NAK)
    {
        USB_TX_memcpy(pEP1+2, HidWriteCtrl.pHidBufferToSend, byte_count);  // copy data into IEP3 X or Y buffer
        pEP1[0] = 0x3F;                                     // set HID report descriptor: 0x3F
        pEP1[1] = byte_count;                               // set HID report descriptor

        // 64 bytes will be send: we use only one HID report descriptor
        *pCT1 = 0x40;                                       // Set counter for usb In-Transaction

        HidWriteCtrl.nHidBytesToSendLeft -= byte_count;
        HidWriteCtrl.pHidBufferToSend += byte_count;        // move buffer pointer

        //try to send data over second buffer
        nTmp2 = *pCT2;
        if ((HidWriteCtrl.nHidBytesToSendLeft > 0) &&       // do we have more data to send?
            (nTmp2 & EPBCNT_NAK)) // if the second buffer is free?
        {
            // how many byte we can send over one endpoint buffer
            byte_count = (HidWriteCtrl.nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl.nHidBytesToSendLeft;

            USB_TX_memcpy(pEP2+2, HidWriteCtrl.pHidBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
            pEP2[0] = 0x3F;                                 // set HID report descriptor: 0x3F
            pEP2[1] = byte_count;                           // set byte count of valid data

            // 64 bytes will be send: we use only one HID report descriptor
            *pCT2 = 0x40;                                   // Set counter for usb In-Transaction

            HidWriteCtrl.nHidBytesToSendLeft -= byte_count;
            HidWriteCtrl.pHidBufferToSend += byte_count;    // move buffer pointer
        }
    }
    return bWakeUp;
}
Exemple #3
0
//this function is used only by USB interrupt
int16_t PHDCToHostFromBuffer (uint8_t intfNum)
{
    uint8_t byte_count, nTmp2;
    uint8_t * pEP1;
    uint8_t * pEP2;
    uint8_t * pCT1;
    uint8_t * pCT2;
    uint8_t bWakeUp = FALSE;                                                   //TRUE for wake up after interrupt
    uint8_t edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft == 0){  //do we have somtething to send?
        if (!PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent){       //zero packet was not yet sent
            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = TRUE;

            if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend ==
                EP_MAX_PACKET_SIZE_PHDC){
                if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY ==
                    X_BUFFER){
                    if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTX &
                        EPBCNT_NAK){
                    tInputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;
                        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY
                            = Y_BUFFER;                                     //switch buffer
                    }
                } else   {
                    if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTY &
                        EPBCNT_NAK){
                    tInputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;
                        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY
                            = X_BUFFER;                                     //switch buffer
                }
                }
            }

            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend = 0;    //nothing to send

            //call event callback function
            if (wUsbEventMask & USB_SEND_COMPLETED_EVENT){
                bWakeUp = USBPHDC_handleSendCompleted(intfNum);
            }
        } //if (!bSentZeroPacket)

        return (bWakeUp);
    }

    PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = FALSE;         //zero packet will be not sent: we have data

    if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){
        //this is the active EP buffer
        pEP1 = (uint8_t*)stUsbHandle[intfNum].iep_X_Buffer;
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;

        //second EP buffer
        pEP2 = (uint8_t*)stUsbHandle[intfNum].iep_Y_Buffer;
        pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
    } else   {
        //this is the active EP buffer
        pEP1 = (uint8_t*)stUsbHandle[intfNum].iep_Y_Buffer;
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;

        //second EP buffer
        pEP2 = (uint8_t*)stUsbHandle[intfNum].iep_X_Buffer;
        pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    }

    //how many byte we can send over one endpoint buffer
    byte_count =
        (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft >
         EP_MAX_PACKET_SIZE_PHDC) ? EP_MAX_PACKET_SIZE_PHDC : PHDCWriteCtrl[
            INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft;
    nTmp2 = *pCT1;

    if (nTmp2 & EPBCNT_NAK){
        USB_TX_memcpy(pEP1, PHDCWriteCtrl[INTFNUM_OFFSET(
                                              intfNum)].pUsbBufferToSend,
            byte_count);                                                        //copy data into IEP3 X or Y buffer
        *pCT1 = byte_count;                                                     //Set counter for usb In-Transaction
        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
            (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
             1) & 0x01;                                                         //switch buffer
        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft -=
            byte_count;
        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count;  //move buffer pointer
        PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;

        //try to send data over second buffer
        nTmp2 = *pCT2;
        if ((PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft >
             0) &&                                                              //do we have more data to send?
            (nTmp2 & EPBCNT_NAK)){ //if the second buffer is free?
            //how many byte we can send over one endpoint buffer
            byte_count =
                (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft >
                 EP_MAX_PACKET_SIZE_PHDC) ? EP_MAX_PACKET_SIZE_PHDC :
                PHDCWriteCtrl[
                    INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft;

            USB_TX_memcpy(pEP2, PHDCWriteCtrl[INTFNUM_OFFSET(
                                                  intfNum)].pUsbBufferToSend,
                byte_count);                                                    //copy data into IEP3 X or Y buffer
            *pCT2 = byte_count;                                                 //Set counter for usb In-Transaction
            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
                (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
                 1) & 0x01;                                                     //switch buffer
            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft -=
                byte_count;
            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend +=
                byte_count;                                                     //move buffer pointer
            PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count;
        }
    }
    return (bWakeUp);
}
Exemple #4
0
//this function is used only by USB interrupt
BOOL CdcToHostFromBuffer()
{
    BYTE byte_count, nTmp2;
    BYTE * pEP1;
    BYTE * pEP2;
    BYTE * pCT1;
    BYTE * pCT2;
    BYTE bWakeUp = FALSE; //TRUE for wake up after interrupt
    static BYTE bZeroPacketSent; // = FALSE;

    if (CdcWriteCtrl.nCdcBytesToSendLeft == 0)           // do we have somtething to send?
    {
        if (!bZeroPacketSent)               // zero packet was not yet sent
        {
            bZeroPacketSent = TRUE;

            CdcWriteCtrl.nCdcBytesToSend = 0;   // nothing to send

            //call event callback function
            if (wUsbEventMask & kUSB_sendCompletedEvent)
            {
                bWakeUp = USBCDC_handleSendCompleted(1);
            }

        } // if (!bSentZeroPacket)

        return bWakeUp;
    }

    bZeroPacketSent = FALSE;    // zero packet will be not sent: we have data

    if (CdcWriteCtrl.bCurrentBufferXY == X_BUFFER)
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)IEP3_X_BUFFER_ADDRESS;
        pCT1 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX;

        //second EP buffer
        pEP2 = (BYTE*)IEP3_Y_BUFFER_ADDRESS;
        pCT2 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY;
    }
    else
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)IEP3_Y_BUFFER_ADDRESS;
        pCT1 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY;

        //second EP buffer
        pEP2 = (BYTE*)IEP3_X_BUFFER_ADDRESS;
        pCT2 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX;
    }

    // how many byte we can send over one endpoint buffer
    byte_count = (CdcWriteCtrl.nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl.nCdcBytesToSendLeft;
    nTmp2 = *pCT1;

    if(nTmp2 & EPBCNT_NAK)
    {
        USB_TX_memcpy(pEP1, CdcWriteCtrl.pBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
        *pCT1 = byte_count;                      // Set counter for usb In-Transaction
        CdcWriteCtrl.bCurrentBufferXY = (CdcWriteCtrl.bCurrentBufferXY+1)&0x01; //switch buffer
        CdcWriteCtrl.nCdcBytesToSendLeft -= byte_count;
        CdcWriteCtrl.pBufferToSend += byte_count;             // move buffer pointer

        //try to send data over second buffer
        nTmp2 = *pCT2;
        if ((CdcWriteCtrl.nCdcBytesToSendLeft > 0) &&                                  // do we have more data to send?
            (nTmp2 & EPBCNT_NAK)) // if the second buffer is free?
        {
            // how many byte we can send over one endpoint buffer
            byte_count = (CdcWriteCtrl.nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl.nCdcBytesToSendLeft;

            USB_TX_memcpy(pEP2, CdcWriteCtrl.pBufferToSend, byte_count); // copy data into IEP3 X or Y buffer
            *pCT2 = byte_count;                      // Set counter for usb In-Transaction
            CdcWriteCtrl.bCurrentBufferXY = (CdcWriteCtrl.bCurrentBufferXY+1)&0x01; //switch buffer
            CdcWriteCtrl.nCdcBytesToSendLeft -= byte_count;
            CdcWriteCtrl.pBufferToSend += byte_count;            //move buffer pointer
        }
    }
    return bWakeUp;
}