Ejemplo n.º 1
0
//this function is used only by USB interrupt.
//It fills user receiving buffer with received data
BOOL CdcToBufferFromHost()
{
    BYTE * pEP1;
    BYTE nTmp1;
    BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt

    if (CdcReadCtrl.nBytesToReceiveLeft == 0)       // do we have somtething to receive?
    {
        CdcReadCtrl.pUserBuffer = NULL;             // no more receiving pending
        return bWakeUp;
    }

    // No data to receive...
    if (!((tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX |
           tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY)
           & 0x80))
    {
        return bWakeUp;
    }

    if (CdcReadCtrl.bCurrentBufferXY == X_BUFFER)   //X is current buffer
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)OEP3_X_BUFFER_ADDRESS;
        CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX;

        //second EP buffer
        CdcReadCtrl.pEP2 = (BYTE*)OEP3_Y_BUFFER_ADDRESS;
        CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY;
    }
    else
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)OEP3_Y_BUFFER_ADDRESS;
        CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY;

        //second EP buffer
        CdcReadCtrl.pEP2 = (BYTE*)OEP3_X_BUFFER_ADDRESS;
        CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX;
    }

    // how many byte we can get from one endpoint buffer
    nTmp1 = *CdcReadCtrl.pCT1;
    while(nTmp1 == 0)
    {
        nTmp1 = *CdcReadCtrl.pCT1;
    }

    if(nTmp1 & EPBCNT_NAK)
    {
        nTmp1 = nTmp1 &0x7f;            // clear NAK bit
        CdcReadCtrl.nBytesInEp = nTmp1; // holds how many valids bytes in the EP buffer

        CopyUsbToBuff(pEP1, CdcReadCtrl.pCT1);

        nTmp1 = *CdcReadCtrl.pCT2;
        //try read data from second buffer
        if ((CdcReadCtrl.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
            CdcReadCtrl.nBytesInEp = nTmp1;       // holds how many valids bytes in the EP buffer
            CopyUsbToBuff(CdcReadCtrl.pEP2, CdcReadCtrl.pCT2);
            CdcReadCtrl.pCT1 = CdcReadCtrl.pCT2;
        }
    }

    if (CdcReadCtrl.nBytesToReceiveLeft == 0)     // the Receive opereation is completed
    {
        CdcReadCtrl.pUserBuffer = NULL;   // no more receiving pending
        if (wUsbEventMask & kUSB_receiveCompletedEvent)
        {
            bWakeUp = USBCDC_handleReceiveCompleted(1);
        }

        if (CdcReadCtrl.nBytesInEp)       // Is not read data still available in the EP?
        {
            if (wUsbEventMask & kUSB_dataReceivedEvent)
            {
                bWakeUp = USBCDC_handleDataReceived(1);
            }
        }
    }
    return bWakeUp;
}
Ejemplo n.º 2
0
/*
Receives data over interface intfNum, of size size, into memory starting at address data.
Returns:
    kUSBCDC_receiveStarted  if the receiving process started.
    kUSBCDC_receiveCompleted  all requested date are received.
    kUSBCDC_receiveInProgress  previous receive opereation is in progress. The requested receive operation can be not started.
    kUSBCDC_generalError  error occurred.
*/
BYTE USBCDC_receiveData(BYTE* data, WORD size, BYTE intfNum)
{
    BYTE nTmp1;

    if (CdcReadCtrl.pUserBuffer != NULL)        // receive process already started
    {
        return kUSBCDC_intfBusyError;
    }

    if ((size == 0) ||                          // read size is 0
        (data == NULL))
    {
        return kUSBCDC_generalError;
    }

    // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE))
    {
        // data can not be read because of USB suspended
        return kUSBCDC_busNotAvailable;
    }

    __disable_interrupt();                      //interrupts disable

    CdcReadCtrl.nBytesToReceive = size;         // bytes to receive
    CdcReadCtrl.nBytesToReceiveLeft = size;     // left bytes to receive
    CdcReadCtrl.pUserBuffer = data;             // set user receive buffer

    //read rest of data from buffer, if any
    if (CdcReadCtrl.nBytesInEp > 0)
    {
        // copy data from pEP-endpoint into User's buffer
        CopyUsbToBuff(CdcReadCtrl.pCurrentEpPos, CdcReadCtrl.pCT1);

        if (CdcReadCtrl.nBytesToReceiveLeft == 0)     // the Receive opereation is completed
        {
            CdcReadCtrl.pUserBuffer = NULL;     // no more receiving pending
            USBCDC_handleReceiveCompleted(1);      // call event handler in interrupt context
            __enable_interrupt();               // interrupts enable
            return kUSBCDC_receiveCompleted;    // receive completed
        }

        // check other EP buffer for data - exchange pCT1 with pCT2
        if (CdcReadCtrl.pCT1 == &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX)
        {
            CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY;
            CdcReadCtrl.pCurrentEpPos = (BYTE*)OEP3_Y_BUFFER_ADDRESS;
        }
        else
        {
            CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX;
            CdcReadCtrl.pCurrentEpPos = (BYTE*)OEP3_X_BUFFER_ADDRESS;
        }

        nTmp1 = *CdcReadCtrl.pCT1;
        //try read data from second buffer
        if (nTmp1 & EPBCNT_NAK)                 // if the second buffer has received data?
        {
            nTmp1 = nTmp1 &0x7f;                // clear NAK bit
            CdcReadCtrl.nBytesInEp = nTmp1;     // holds how many valids bytes in the EP buffer
            CopyUsbToBuff(CdcReadCtrl.pCurrentEpPos, CdcReadCtrl.pCT1);
        }

        if (CdcReadCtrl.nBytesToReceiveLeft == 0)     // the Receive opereation is completed
        {
            CdcReadCtrl.pUserBuffer = NULL;     // no more receiving pending
            __enable_interrupt();               // interrupts enable
            return kUSBCDC_receiveCompleted;    // receive completed
        }
    } //read rest of data from buffer, if any

    //read 'fresh' data, if available
    nTmp1 = 0;
    if (CdcReadCtrl.bCurrentBufferXY == X_BUFFER)  //this is current buffer
    {
        if (tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
        {
            //this is the active EP buffer
            //pEP1
            CdcReadCtrl.pCurrentEpPos = (BYTE*)OEP3_X_BUFFER_ADDRESS;
            CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX;

            //second EP buffer
            CdcReadCtrl.pEP2 = (BYTE*)OEP3_Y_BUFFER_ADDRESS;
            CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY;
            nTmp1 = 1;    //indicate that data is available
        }
    }
    else // Y_BUFFER
    if (tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY & EPBCNT_NAK)
    {
        //this is the active EP buffer
        CdcReadCtrl.pCurrentEpPos = (BYTE*)OEP3_Y_BUFFER_ADDRESS;
        CdcReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY;

        //second EP buffer
        CdcReadCtrl.pEP2 = (BYTE*)OEP3_X_BUFFER_ADDRESS;
        CdcReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX;
        nTmp1 = 1;    //indicate that data is available
    }

    if (nTmp1)
    {
        // how many byte we can get from one endpoint buffer
        nTmp1 = *CdcReadCtrl.pCT1;
        while(nTmp1 == 0)
        {
            nTmp1 = *CdcReadCtrl.pCT1;
        }

        if(nTmp1 & EPBCNT_NAK)
        {
            nTmp1 = nTmp1 &0x7f;            // clear NAK bit
            CdcReadCtrl.nBytesInEp = nTmp1; // holds how many valids bytes in the EP buffer

            CopyUsbToBuff(CdcReadCtrl.pCurrentEpPos, CdcReadCtrl.pCT1);

            nTmp1 = *CdcReadCtrl.pCT2;
            //try read data from second buffer
            if ((CdcReadCtrl.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
                CdcReadCtrl.nBytesInEp = nTmp1;       // holds how many valids bytes in the EP buffer
                CopyUsbToBuff(CdcReadCtrl.pEP2, CdcReadCtrl.pCT2);
                CdcReadCtrl.pCT1 = CdcReadCtrl.pCT2;
            }
        }
    }

    if (CdcReadCtrl.nBytesToReceiveLeft == 0)     // the Receive opereation is completed
    {
        CdcReadCtrl.pUserBuffer = NULL;           // no more receiving pending
        USBCDC_handleReceiveCompleted(1);                // call event handler in interrupt context
        __enable_interrupt();                     // interrupts enable
        return kUSBCDC_receiveCompleted;
    }

    //interrupts enable
    __enable_interrupt();
    return kUSBCDC_receiveStarted;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
/*
Reset USB-SIE and global variables.
*/
BYTE USB_reset()
{
    USBKEYPID = 0x9628;                   // set KEY and PID to 0x9628 -> access to configuration registers enabled

    //reset should be on the bus after this!
    bEnumerationStatus = 0x00;            // Device not enumerated yet
    bFunctionSuspended = FALSE;           // Device is not in suspend mode

    bRemoteWakeup = DISABLE;

    bConfigurationNumber    = 0x00;       // device unconfigured
    bInterfaceNumber        = 0x00;

    // FRSTE Workaround:
    // Clear FRSTE in the RESRIFG interrupt service routine before re-configuring USB control registers.
    // Set FRSTE at the beginning of SUSRIFG, SETUP, IEPIFG.EP0 and OEPIFG.EP0 interrupt service routines. 
    USBCTL = 0;                           // Function Reset Connection disable (FRSTE)

    wBytesRemainingOnIEP0   = NO_MORE_DATA;
    wBytesRemainingOnOEP0   = NO_MORE_DATA;
    bStatusAction           = STATUS_ACTION_NOTHING;

    //The address reset normally will be done automatically during bus function reset
    USBFUNADR   =     0x00;               // reset address of USB device (unconfigured)

    /* Set settings for EP0 */
    // NAK both 0 endpoints and enable endpoint 0 interrupt
    tEndPoint0DescriptorBlock.bIEPBCNT = EPBCNT_NAK;
    tEndPoint0DescriptorBlock.bOEPBCNT = EPBCNT_NAK;
    tEndPoint0DescriptorBlock.bIEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet
    tEndPoint0DescriptorBlock.bOEPCNFG = EPCNF_USBIE | EPCNF_UBME | EPCNF_STALL;    // 8 byte data packet

    USBOEPIE = BIT0 | BIT1 | BIT3;                // enable EP0, and EP3 output IRQ
    USBIEPIE = BIT0 | BIT1 | BIT2 | BIT3;         // enable EP0, EP1, EP2 and EP3 input IRQ


  #ifdef _HID_
    /* Set settings for IEP1 */
    // enable endpoint 1 interrupt, input
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF; //double buffering
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBBAX  = (BYTE)(((IEP1_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBBAY  = (BYTE)(((IEP1_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX  = EPBCNT_NAK;
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY  = EPBCNT_NAK;
    tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;

    /* Set settings for OEP1 */
    // enable endpoint 1 interrupt, output
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPCNF   = EPCNF_USBIE | EPCNF_UBME | EPCNF_DBUF ; //double buffering
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBBAX  = (BYTE)(((OEP1_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBBAY  = (BYTE)(((OEP1_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX  = 0x00;
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY  = 0x00; // EPBCT_NAK for one buffer (no double)
    tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;

    HidResetData();                     // reset CDC specific data structures
  #endif // _HID_

  #ifdef _CDC_
    /* Set settings for IEP2 */
    // enable endpoint 2 interrupt, input
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPCNF   = EPCNF_USBIE       // use Interrupt for this EP
                                                | EPCNF_UBME      // enable this EP
                                                | EPCNF_DBUF;     // use double buffering (X and Y buffers)
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBBAX  = (BYTE)(((IEP2_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBBAY  = (BYTE)(((IEP2_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBCTX  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPBCTY  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    tInputEndPointDescriptorBlock[EDB(CDC_INTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;

    /* Set settings for IEP3 */
    // enable endpoint 3 bulk, input
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPCNF   = EPCNF_USBIE       // use Interrupt for this EP
                                                | EPCNF_UBME      // enable this EP
                                                | EPCNF_DBUF;     // use double buffering (X and Y buffers)
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBBAX  = (BYTE)(((IEP3_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBBAY  = (BYTE)(((IEP3_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY  = EPBCNT_NAK;       // NAK: the buffer has no valid data to send to host
    tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;

    /* Set settings for OEP3 */
    // enable endpoint 3 bulk, output
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPCNF   = EPCNF_USBIE      // use Interrupt for this EP
                                                 | EPCNF_UBME     // enable this EP
                                                 | EPCNF_DBUF;    // use double buffering (X and Y buffers)
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBBAX  = (BYTE)(((OEP3_X_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBBAY  = (BYTE)(((OEP3_Y_BUFFER_ADDRESS - START_OF_USB_BUFFER) >> 3) & 0x00ff);
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTX  = 0x00;
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPBCTY  = 0x00;
    tOutputEndPointDescriptorBlock[EDB(CDC_OUTEP_ADDR)].bEPSIZXY = MAX_PACKET_SIZE;

    CdcResetData();                     // reset CDC specific data structures

  #endif // _CDC_

    USBCTL |= FEN;                      // enable function
    USBIFG = 0;                         // make sure no interrupts are pending

    USBIE = SETUPIE | RSTRIE | SUSRIE;  // enable USB specific interrupts (setup, reset, suspend)
    USBKEYPID = 0x9600;                 // access to configuration registers disabled
    return kUSB_succeed;
}
Ejemplo n.º 5
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 HID report descriptor

            // 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;
}
Ejemplo n.º 6
0
/*
Receives report reportData from the host.
Return:     kUSBHID_receiveCompleted
            kUSBHID_receiveError
            kUSBCDC_busNotAvailable
*/
BYTE USBHID_receiveReport(BYTE * reportData, BYTE intfNum)
{
    BYTE ret = kUSBHID_receiveError;
    BYTE nTmp1 = 0;

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

    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 = nTmp1; // holds how many valids bytes in the EP buffer

            USB_RX_memcpy(reportData, HidReadCtrl.pCurrentEpPos, nTmp1);
            //memcpy(reportData, HidReadCtrl.pEP1, nTmp1);
            HidReadCtrl.bCurrentBufferXY = (HidReadCtrl.bCurrentBufferXY+1) &0x01;
            HidReadCtrl.nBytesInEp = 0;
            *HidReadCtrl.pCT1 = 0;          // clear NAK, EP ready to receive data

            ret = kUSBHID_receiveCompleted;
        }
    }
    return ret;
}