/*
This function indicates the status of the interface intfNum.
  If a send operation is active for this interface,
  the function also returns the number of bytes that have been transmitted to the host.
  If a receiver operation is active for this interface, the function also returns
  the number of bytes that have been received from the host and are waiting at the assigned address.

returns kUSBHID_waitingForSend (indicates that a call to USBHID_SendData()
  has been made, for which data transfer has not been completed)

returns kUSBHID_waitingForReceive (indicates that a receive operation
  has been initiated, but not all data has yet been received)

returns kUSBHID_dataWaiting (indicates that data has been received
  from the host, waiting in the USB receive buffers)
*/
BYTE USBHID_intfStatus(BYTE intfNum, WORD* bytesSent, WORD* bytesReceived)
{
    BYTE ret = 0;
	unsigned short bGIE;
    BYTE edbIndex;
		
    *bytesSent = 0;
    *bytesReceived = 0;
    
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    bGIE  = (__get_SR_register() &GIE);  //save interrupt status
    __disable_interrupt(); //disable interrupts - atomic operation

    // Is send operation underway?
    if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft != 0)
    {
        ret |= kUSBHID_waitingForSend;
        *bytesSent = HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend - HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;
    }

    //Is receive operation underway?
    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL)
    {
        ret |= kUSBHID_waitingForReceive;
        *bytesReceived = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
    }
    else // not receive operation started
    {
        // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
        if (!bFunctionSuspended)
        {
            if((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK)  | //any of buffers has a valid data packet
               (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK))
            {
                ret |= kUSBHID_dataWaiting;
            }
        }
    }

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE))
    {
        // if suspended or not enumerated  - report no other tasks pending
        ret = kUSBHID_busNotAvailable;
    }

     //restore interrupt status
    __bis_SR_register(bGIE); //restore interrupt status

    return ret;
}
/*
Aborts an active send operation on interface intfNum.
Returns the number of bytes that were sent prior to the abort, in size.
*/
BYTE USBHID_abortSend(WORD* size, BYTE intfNum)
{
    unsigned short bGIE;
    bGIE  = (__get_SR_register() &GIE);  //save interrupt status

    __disable_interrupt(); //disable interrupts - atomic operation

    *size = (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend - HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft);
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = 0;
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft = 0;

    __bis_SR_register(bGIE); //restore interrupt status
    return kUSB_succeed;
}
Exemple #3
0
/*
 * Aborts an active send operation on interface intfNum.
 * Returns the number of bytes that were sent prior to the abort, in size.
 */
uint8_t USBPHDC_abortSend (uint16_t* size, uint8_t intfNum)
{
    uint8_t edbIndex;
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;
    state = usbDisableInEndpointInterrupt(edbIndex);

    *size =
        (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend -
         PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft);
    PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend = 0;
    PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft = 0;

    usbRestoreInEndpointInterrupt(state);
    return (USB_SUCCEED);
}
Exemple #4
0
/*
 * Aborts an active send operation on interface intfNum.
 * Returns the number of bytes that were sent prior to the abort, in size.
 */
BYTE USBPHDC_abortSend (WORD* size, BYTE intfNum)
{
    BYTE edbIndex;
    WORD state;

    edbIndex = stUsbHandle[intfNum].edb_Index;
    state = usbDisableInEndpointInterrupt(edbIndex);

    *size =
        (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend -
         PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft);
    PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend = 0;
    PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft = 0;

    usbRestoreInEndpointInterrupt(state);
    return (kUSB_succeed);
}
/*
Sends data over interface intfNum, of size size and starting at address data.
Returns: kUSBHID_sendStarted
         kUSBHID_sendComplete
         kUSBHID_intBusyError
*/
BYTE USBHID_sendData(const BYTE* data, WORD size, BYTE intfNum)
{
    unsigned short bGIE;
    BYTE edbIndex;
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    if (size == 0)
    {
        return kUSBHID_generalError;
    }

    bGIE  = (__get_SR_register() &GIE);  //save interrupt status

    // 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))
    {        
        // data can not be read because of USB suspended
        __bis_SR_register(bGIE); //restore interrupt status
        return kUSBHID_busNotAvailable;
    }

    if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft != 0)
    {
        // the USB still sends previous data, we have to wait
        __bis_SR_register(bGIE); //restore interrupt status
        return kUSBHID_intfBusyError;
    }

    //This function generate the USB interrupt. The data will be sent out from interrupt

    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = size;
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft = size;
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend = data;

    //trigger Endpoint Interrupt - to start send operation
    USBIEPIFG |= 1<<(edbIndex+1);   //IEPIFGx;

    __bis_SR_register(bGIE); //restore interrupt status

    return kUSBHID_sendStarted;
}
Exemple #6
0
/*
 * Aborts an active send operation on interface intfNum.
 * Returns the number of bytes that were sent prior to the abort, in size.
 */
BYTE USBCDC_abortSend (WORD* size, BYTE intfNum)
{
    BYTE edbIndex;
    WORD state;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    state = usbDisableInEndpointInterrupt(edbIndex);                                                         //disable interrupts - atomic operation

    *size =
        (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend -
         CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft);
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0;
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = 0;

    usbRestoreInEndpointInterrupt(state);
    return (kUSB_succeed);
}
Exemple #7
0
//this function is used only by USB interrupt.
//It fills user receiving buffer with received data
BOOL CdcToBufferFromHost_Bridge (BYTE intfNum)
{
    BYTE *pEP1, *pCT1;
    BYTE nTmp1;
    BYTE bWakeUp = FALSE;                                                   //per default we do not wake up after interrupt
    BYTE i;    
    BYTE edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

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

    if (CdcBridgeCtrl.ctsState == 0) {
    	return (bWakeUp);
    }
            
    //this is the active EP buffer
    pEP1 = (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
    pCT1 = &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    
    __no_operation();
    __no_operation();
    
    //how many byte we can get from endpoint buffer
    nTmp1 = *pCT1;

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

        if (nTmp1 > 0) {
            //Start DMA
            if (nTmp1 > 5 ) {
                //Start DMA
                while (!(*CdcBridgeCtrl.uartIFG & UCTXIFG));
                *CdcBridgeCtrl.uartTx = *pEP1;
                *CdcBridgeCtrl.usbToUartDmaChSz = nTmp1 - 1;                // Block size
                *CdcBridgeCtrl.usbToUartDmaChCtl = DMADT_0 + DMASRCINCR_3 + DMASBDB + DMAEN + DMAIE;// Rpt, inc src, enable
            }
            else {
                for (i = 0; i < nTmp1; i++) {                
                    while (!(*CdcBridgeCtrl.uartIFG & UCTXIFG));          // USCI_A0 TX buffer ready?
                        *CdcBridgeCtrl.uartTx = *pEP1++;                  // TX -> RXed character 
                }
                *pCT1 = 0x00;
            }
        }
        else {
             *pCT1 = 0x00;
        }        
    }
    
    return (bWakeUp);
}
Exemple #8
0
uint8_t USBCDC_abortSend (uint16_t* size, uint8_t intfNum)
{
    uint8_t edbIndex;
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    state = usbDisableInEndpointInterrupt(edbIndex);                                                         //disable interrupts - atomic operation

    *size =
        (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend -
         CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft);
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = 0;
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = 0;

    usbRestoreInEndpointInterrupt(state);
    return (USB_SUCCEED);
}
Exemple #9
0
/*
 * Sends data over interface intfNum, of size size and starting at address data.
 * Returns: kUSBHID_sendStarted
 *       kUSBHID_sendComplete
 *       kUSBHID_intBusyError
 */
BYTE USBHID_sendData (const BYTE* data, WORD size, BYTE intfNum)
{
	WORD state;
    BYTE edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    if (size == 0){
        return (kUSBHID_generalError);
    }

    state = usbDisableInEndpointInterrupt(edbIndex);

    //atomic operation - disable interrupts

    //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
    	usbRestoreInEndpointInterrupt(state);
        return (kUSBHID_busNotAvailable);
    }

    if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft != 0){
        //the USB still sends previous data, we have to wait
    	usbRestoreInEndpointInterrupt(state);
        return (kUSBHID_intfBusyError);
    }

    //This function generate the USB interrupt. The data will be sent out from interrupt

    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = size;
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft = size;
    HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend = data;

    //trigger Endpoint Interrupt - to start send operation
    USBIEPIFG |= 1 << (edbIndex + 1);                                       //IEPIFGx;

    usbRestoreInEndpointInterrupt(state);

    return (kUSBHID_sendStarted);
}
Exemple #10
0
/*
 * This function rejects payload data that has been received from the host.
 */
BYTE USBHID_rejectData (BYTE intfNum)
{
	WORD state;
    BYTE edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    state = usbDisableOutEndpointInterrupt(edbIndex);

    //interrupts disable

    //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
    if (bFunctionSuspended){
    	usbRestoreOutEndpointInterrupt(state);
        return (kUSBHID_busNotAvailable);
    }

    //Is receive operation underway?
    //- do not flush buffers if any operation still active.
    if (!HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
        BYTE tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
                    EPBCNT_NAK;
        BYTE tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
                    EPBCNT_NAK;

        if (tmp1 ^ tmp2){                                                       //switch current buffer if any and only ONE of the
                                                                                //buffers is full
            //switch current buffer
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
                (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
                 1) & 0x01;
        }

        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;                   //flush buffer X
        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;                   //flush buffer Y
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;                    //indicates that no more data available in the EP
    }

    usbRestoreOutEndpointInterrupt(state);
    return (kUSB_succeed);
}
Exemple #11
0
/*
 * Aborts an active receive operation on interface intfNum.
 * Returns the number of bytes that were received and transferred
 * to the data location established for this receive operation.
 */
BYTE USBCDC_abortReceive (WORD* size, BYTE intfNum)
{
    //interrupts disable
	BYTE edbIndex;
	WORD state;

    edbIndex = stUsbHandle[intfNum].edb_Index;
    state = usbDisableOutEndpointInterrupt(edbIndex);

    *size = 0;                                                              //set received bytes count to 0

    //is receive operation underway?
    if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
        //how many bytes are already received?
        *size = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
                CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;

        CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
        CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
        CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
    }

    //restore interrupt status
    usbRestoreOutEndpointInterrupt(state);
    return (kUSB_succeed);
}
Exemple #12
0
uint8_t USBCDC_rejectData (uint8_t intfNum)
{
    uint8_t edbIndex;
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;
    state = usbDisableOutEndpointInterrupt(edbIndex);

    //atomic operation - disable interrupts

    //do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
    if (bFunctionSuspended){
    	usbRestoreOutEndpointInterrupt(state);
        return (USBCDC_BUS_NOT_AVAILABLE);
    }

    //Is receive operation underway?
    //- do not flush buffers if any operation still active.
    if (!CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
        uint8_t tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
                    EPBCNT_NAK;
        uint8_t tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
                    EPBCNT_NAK;

        if (tmp1 ^ tmp2){                                                   //switch current buffer if any and only ONE of buffers
                                                                            //is full
            //switch current buffer
            CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
                (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY +
                 1) & 0x01;
        }

        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;               //flush buffer X
        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;               //flush buffer Y
        CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;                //indicates that no more data available in the EP
    }

    usbRestoreOutEndpointInterrupt(state);
    return (USB_SUCCEED);
}
Exemple #13
0
uint8_t USBCDC_sendData (const uint8_t* data, uint16_t size, uint8_t intfNum)
{
    uint8_t edbIndex;
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    if (size == 0){
        return (USBCDC_GENERAL_ERROR);
    }

    state = usbDisableInEndpointInterrupt(edbIndex);

    //do not access USB memory if suspended (PLL uce BUS_ERROR
    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE)){
        //data can not be read because of USB suspended
    	usbRestoreInEndpointInterrupt(state);                                            //restore interrupt status
        return (USBCDC_BUS_NOT_AVAILABLE);
    }

    if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0){
        //the USB still sends previous data, we have to wait
    	usbRestoreInEndpointInterrupt(state);                                           //restore interrupt status
        return (USBCDC_INTERFACE_BUSY_ERROR);
    }

    //This function generate the USB interrupt. The data will be sent out from interrupt

    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend = size;
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft = size;
    CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend = data;

    //trigger Endpoint Interrupt - to start send operation
    USBIEPIFG |= 1 << (edbIndex + 1);                                       //IEPIFGx;

    usbRestoreInEndpointInterrupt(state);

    return (USBCDC_SEND_STARTED);
}
Exemple #14
0
/*
 * Aborts an active receive operation on interface intfNum.
 * Returns the number of bytes that were received and transferred
 * to the data location established for this receive operation.
 */
uint8_t USBPHDC_abortReceive (uint16_t* size, uint8_t intfNum)
{
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;


    state = usbDisableOutEndpointInterrupt(edbIndex);

    *size = 0;                                                  //set received bytes count to 0

    //is receive operation underway?
    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer){
        //how many bytes are already received?
        *size = PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
                PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;

        PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
        PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
        PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
    }

    //restore interrupt status
    usbRestoreOutEndpointInterrupt(state);
    return (USB_SUCCEED);
}
/*
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;
}
/*
This function rejects payload data that has been received from the host.
*/
BYTE USBHID_rejectData(BYTE intfNum)
{
    unsigned short bGIE;
    BYTE edbIndex;
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    bGIE  = (__get_SR_register() &GIE);  //save interrupt status

    //interrupts disable
    __disable_interrupt();  
  
    // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR
    if (bFunctionSuspended)
    {
        __bis_SR_register(bGIE); //restore interrupt status
        return kUSBHID_busNotAvailable;
    }

    //Is receive operation underway?
    // - do not flush buffers if any operation still active.
    if (!HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
    {
        BYTE tmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK;
        BYTE tmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK;

        if (tmp1 ^ tmp2) // switch current buffer if any and only ONE of the buffers is full
        {
            //switch current buffer
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;
        }

        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0;  //flush buffer X
        tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0;  //flush buffer Y
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;                     // indicates that no more data available in the EP
    }

    __bis_SR_register(bGIE); //restore interrupt status
    return kUSB_succeed;
}
Exemple #17
0
/*
 * Returns how many bytes are in the buffer are received and ready to be read.
 */
BYTE USBHID_bytesInUSBBuffer (BYTE intfNum)
{
    BYTE bTmp1 = 0;
    BYTE bTmp2;

    BYTE edbIndex;
    WORD state;


    edbIndex = stUsbHandle[intfNum].edb_Index;

    //interrupts disable
    state = usbDisableOutEndpointInterrupt(edbIndex);

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE)){
        //if suspended or not enumerated - report 0 bytes available
    	usbRestoreOutEndpointInterrupt(state);
        return (0);
    }

    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){                   //If a RX operation is underway, part of data may
                                                                                //was read of the OEP buffer
        bTmp1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
        if (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK){           //the next buffer has a valid data packet
            bTmp2 = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 + 1);           //holds how many valid bytes in the EP buffer
            if (bTmp2 >
                (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) - 2){       //check if all data received correctly
                bTmp1 +=
                    (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) - 2;
            } else {
                bTmp1 += bTmp2;
            }
        }
    } else {
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){     //this buffer has a valid data packet
            bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
            bTmp1 = *((BYTE*)stUsbHandle[intfNum].oep_X_Buffer + 1);
            if (bTmp2 - 2 < bTmp1){                                             //check if the count (second byte) is valid
                bTmp1 = bTmp2 - 2;
            }
        }
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){     //this buffer has a valid data packet
            bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
            if (bTmp2 - 2 > *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer + 1)){   //check if the count (second byte) is valid
                bTmp1 += *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer + 1);
            } else {
                bTmp1 += bTmp2 - 2;
            }
        }
    }

    //interrupts enable
    usbRestoreOutEndpointInterrupt(state);
    return (bTmp1);
}
Exemple #18
0
/*
 * Returns how many bytes are in the buffer are received and ready to be read.
 */
uint8_t USBPHDC_bytesInUSBBuffer (uint8_t intfNum)
{
    uint8_t bTmp1 = 0;
    uint16_t state;
    uint8_t edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    state = usbDisableOutEndpointInterrupt(edbIndex);
    //atomic operation - disable interrupts

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE)){
    	usbRestoreOutEndpointInterrupt(state);
        //if suspended or not enumerated - report 0 bytes available
        return (0);
    }

    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){  //If a RX operation is underway, part of data may was read of the
                                                                //OEP buffer
        bTmp1 = PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
        if (*PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK){ //the next buffer has a valid data packet
            bTmp1 += *PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F;
        }
    } else   {
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){ //this buffer has a valid data packet
            bTmp1 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
        }
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){ //this buffer has a valid data packet
            bTmp1 += tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
        }
    }

    usbRestoreOutEndpointInterrupt(state);
    return (bTmp1);
}
Exemple #19
0
/*
 * This function indicates the status of the itnerface intfNum.
 * If a send operation is active for this interface,
 * the function also returns the number of bytes that have been transmitted to the host.
 * If a receiver operation is active for this interface, the function also returns
 * the number of bytes that have been received from the host and are waiting at the assigned address.
 *
 * returns kUSBPHDC_waitingForSend (indicates that a call to USBPHDC_SendData()
 * has been made, for which data transfer has not been completed)
 *
 * returns kUSBPHDC_waitingForReceive (indicates that a receive operation
 * has been initiated, but not all data has yet been received)
 *
 * returns kUSBPHDC_dataWaiting (indicates that data has been received
 * from the host, waiting in the USB receive buffers)
 */
uint8_t USBPHDC_intfStatus (uint8_t intfNum, uint16_t* bytesSent, uint16_t* bytesReceived)
{
    uint8_t ret = 0;
    uint16_t stateIn, stateOut;
    uint8_t edbIndex;

    *bytesSent = 0;
    *bytesReceived = 0;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    stateIn = usbDisableInEndpointInterrupt(edbIndex);
    stateOut = usbDisableOutEndpointInterrupt(edbIndex);

    //Is send operation underway?
    if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft != 0){
        ret |= kUSBPHDC_waitingForSend;
        *bytesSent = PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend -
                     PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].
                     nPHDCBytesToSendLeft;
    }

    //Is receive operation underway?
    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){
        ret |= kUSBPHDC_waitingForReceive;
        *bytesReceived =
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;
    } else   { //receive operation not started
                                                                //do not access USB memory if suspended (PLL off). It may produce
                                                                //BUS_ERROR
        if (!bFunctionSuspended){
            if ((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
                 EPBCNT_NAK)  |                                 //any of buffers has a valid data packet
                (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
                 EPBCNT_NAK)){
                ret |= kUSBPHDC_dataWaiting;
            }
        }
    }

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE)){
        //if suspended or not enumerated - report no other tasks pending
        ret = kUSBPHDC_busNotAvailable;
    }

    //restore interrupt status
    usbRestoreInEndpointInterrupt(stateIn);
    usbRestoreOutEndpointInterrupt(stateOut);

    __no_operation();
    return (ret);
}
Exemple #20
0
uint8_t USBCDC_getInterfaceStatus (uint8_t intfNum, uint16_t* bytesSent, uint16_t* bytesReceived)
{
    uint8_t ret = 0;
    uint16_t stateIn, stateOut;
    uint8_t edbIndex;

    *bytesSent = 0;
    *bytesReceived = 0;

    edbIndex = stUsbHandle[intfNum].edb_Index;

    stateIn = usbDisableInEndpointInterrupt(edbIndex);
    stateOut = usbDisableOutEndpointInterrupt(edbIndex);

    //Is send operation underway?
    if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft != 0){
        ret |= USBCDC_WAITING_FOR_SEND;
        *bytesSent = CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSend -
                     CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
    }

    //Is receive operation underway?
    if (CdcReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){
        ret |= USBCDC_WAITING_FOR_RECEIVE;
        *bytesReceived = CdcReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive -
                         CdcReadCtrl[INTFNUM_OFFSET(intfNum)].
                         nBytesToReceiveLeft;
    } else {                                                                //receive operation not started
        //do not access USB memory if suspended (PLL off).
        //It may produce BUS_ERROR
        if (!bFunctionSuspended){
            if ((tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX &
                 EPBCNT_NAK)  |                                             //any of buffers has a valid data packet
                (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY &
                 EPBCNT_NAK)){
                ret |= USBCDC_DATA_WAITING;
            }
        }
    }

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE)){
        //if suspended or not enumerated - report no other tasks pending
        ret = USBCDC_BUS_NOT_AVAILABLE;
    }

    //restore interrupt status
    usbRestoreInEndpointInterrupt(stateIn);
    usbRestoreOutEndpointInterrupt(stateOut);

    __no_operation();
    return (ret);
}
Exemple #21
0
//this function is used only by USB interrupt
BOOL CdcToHostFromBuffer_Bridge (BYTE intfNum)
{
    BYTE byte_count, nTmp2;
    BYTE * pCT1;
    BYTE bWakeUp = FALSE;                                                   //TRUE for wake up after interrupt
    BYTE edbIndex;

    if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft == 0){
        return (bWakeUp);
    }
    
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    //this is the active EP buffer
    pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;

    if (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    } else {
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;
    }
    
    //how many byte we can send over one endpoint buffer
    byte_count =
        (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft >
         EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl[
            INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft;
    nTmp2 = *pCT1;

   CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY =
        (CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01; 
            
    if (nTmp2 & EPBCNT_NAK){                                                            //copy data into IEP3 X or Y buffer
        *pCT1 = byte_count;                                                         //Set counter for usb In-Transaction
        CdcWriteCtrl[INTFNUM_OFFSET(intfNum)].nCdcBytesToSendLeft -= byte_count;
    }
    
    return (bWakeUp);
}
/*
Aborts an active receive operation on interface intfNum.
  Returns the number of bytes that were received and transferred
  to the data location established for this receive operation.
*/
BYTE USBHID_abortReceive(WORD* size, BYTE intfNum)
{
    unsigned short bGIE;
    
    bGIE  = (__get_SR_register() &GIE);  //save interrupt status
    __disable_interrupt(); //disable interrupts - atomic operation

    *size = 0;    //set received bytes count to 0

    //is receive operation underway?
    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer)
    {
        //how many bytes are already received?
        *size = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive - HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;

        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = 0;
    }

     //restore interrupt status
    __bis_SR_register(bGIE); //restore interrupt status
    return kUSB_succeed;
}
/*
Returns how many bytes are in the buffer are received and ready to be read.
*/
BYTE USBHID_bytesInUSBBuffer(BYTE intfNum)
{
    BYTE bTmp1 = 0;
    BYTE bTmp2;

    BYTE edbIndex;
    unsigned short bGIE;
    
    bGIE  = (__get_SR_register() &GIE);  //save interrupt status
    
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    //interrupts disable
    __disable_interrupt();

    if ((bFunctionSuspended) ||
        (bEnumerationStatus != ENUMERATION_COMPLETE))
    {
        // if suspended or not enumerated - report 0 bytes available
       __bis_SR_register(bGIE); //restore interrupt status
        return 0;
    }

    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0)         // If a RX operation is underway, part of data may was read of the OEP buffer
    {
        bTmp1 = HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp;
        if (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & EPBCNT_NAK) // the next buffer has a valid data packet
        {
            bTmp2 = *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2+1);  // holds how many valid bytes in the EP buffer
            if (bTmp2 > (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) -2) // check if all data received correctly
            {
                bTmp1 += (*HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 & 0x7F) -2;
            }
            else
            {
                bTmp1 += bTmp2;
            }
        }
    }
    else
    {
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet
        {
            bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX & 0x7F;
            bTmp1 = *((BYTE*)stUsbHandle[intfNum].oep_X_Buffer+1);
            if (bTmp2-2 < bTmp1)	// check if the count (second byte) is valid
            {
                bTmp1 = bTmp2 - 2;
            }
        }
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK) //this buffer has a valid data packet
        {
            bTmp2 = tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & 0x7F;
            if (bTmp2-2 > *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer+1)) // check if the count (second byte) is valid
            {
                bTmp1 += *((BYTE*)stUsbHandle[intfNum].oep_Y_Buffer+1);
            }
            else
            {
                bTmp1 += bTmp2 - 2;
            }
        }
    }

    //interrupts enable
   __bis_SR_register(bGIE); //restore interrupt status
    return bTmp1;
}
// helper for USB interrupt handler
BOOL HidIsReceiveInProgress(BYTE intfNum)
{
    return (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL);
}
//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;
    unsigned short bGIE;
    BYTE edbIndex;
    edbIndex = stUsbHandle[intfNum].edb_Index;

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

    bGIE  = (__get_SR_register() &GIE);  //save interrupt status

    // 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))
    {
         __bis_SR_register(bGIE); //restore interrupt status
        return kUSBHID_busNotAvailable;
    }

    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL)        // receive process already started
    {
        __bis_SR_register(bGIE); //restore interrupt status
        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
            __bis_SR_register(bGIE); //restore interrupt status
            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
            USBHID_handleReceiveCompleted(intfNum);   // call event handler in interrupt context
            __bis_SR_register(bGIE); //restore interrupt status
            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
        USBHID_handleReceiveCompleted(intfNum);            // call event handler in interrupt context
        __bis_SR_register(bGIE); //restore interrupt status
        return kUSBHID_receiveCompleted;
    }

    //interrupts enable
    __bis_SR_register(bGIE); //restore interrupt status
    return kUSBHID_receiveStarted;
}
// This function copies data from OUT endpoint into user's buffer
// Arguments:
//    pEP - pointer to EP to copy from
//    pCT - pointer to pCT control reg
//
VOID HidCopyUsbToBuff(BYTE* pEP, BYTE* pCT,BYTE intfNum)
{
    BYTE nCount;

    // how many byte we can get from one endpoint buffer
    nCount = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) ? HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp : HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft;

    USB_RX_memcpy(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer, pEP, nCount); // copy data from OEPx X or Y buffer
    HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft -= nCount;
    HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer += nCount;          // move buffer pointer
                                                // to read rest of data next time from this place

    if (nCount == HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp)       // all bytes are copied from receive buffer?
    {
        //switch current buffer
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (HidReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY+1) &0x01;

        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0;

        //clear NAK, EP ready to receive data
        *pCT = 0;
    }
    else
    {
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp -= nCount;
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = pEP + nCount;
    }
}
//this function is used only by USB interrupt
BOOL HidToHostFromBuffer(BYTE intfNum)
{
    BYTE byte_count, nTmp2;
    BYTE * pEP1;
    BYTE * pEP2;
    BYTE * pCT1;
    BYTE * pCT2;
    BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt
    
    BYTE edbIndex;
    edbIndex = stUsbHandle[intfNum].edb_Index;
    
    if (HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft == 0)           // do we have somtething to send?
    {

        HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSend = 0;

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

    if(!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF & EPCNF_TOGGLE))
    {
        //this is the active EP buffer
        pEP1 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
        pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;

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

        //second EP buffer
        pEP2 = (BYTE*)stUsbHandle[intfNum].iep_X_Buffer;
        pCT2 = &tInputEndPointDescriptorBlock[edbIndex].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[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;
    nTmp2 = *pCT1;

    if(nTmp2 & EPBCNT_NAK)
    {
        USB_TX_memcpy(pEP1+2, HidWriteCtrl[INTFNUM_OFFSET(intfNum)].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[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft -= byte_count;
        HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend += byte_count;        // move buffer pointer

        //try to send data over second buffer
        nTmp2 = *pCT2;
        if ((HidWriteCtrl[INTFNUM_OFFSET(intfNum)].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[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft;

            USB_TX_memcpy(pEP2+2, HidWriteCtrl[INTFNUM_OFFSET(intfNum)].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[INTFNUM_OFFSET(intfNum)].nHidBytesToSendLeft -= byte_count;
            HidWriteCtrl[INTFNUM_OFFSET(intfNum)].pHidBufferToSend += byte_count;    // move buffer pointer
        }
    }
    return bWakeUp;
}
/*
Receives report reportData from the host.
Return:     kUSBHID_receiveCompleted
            kUSBHID_generalError
            kUSBCDC_busNotAvailable
*/
BYTE USBHID_receiveReport(BYTE * reportData, BYTE intfNum)
{
    BYTE ret = kUSBHID_generalError;
    BYTE nTmp1 = 0;

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

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

            ret = kUSBHID_receiveCompleted;
        }
    }
    return ret;
}
Exemple #30
0
//helper for USB interrupt handler
int16_t PHDCIsReceiveInProgress (uint8_t intfNum)
{
    return (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL);
}