Example #1
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);
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
Example #5
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);
}
Example #6
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);
}
Example #7
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);
}
Example #8
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);
}
Example #9
0
/*
 * Receives data over interface intfNum, of size size, into memory starting at address data.
 * Returns:
 *  kUSBPHDC_receiveStarted  if the receiving process started.
 *  kUSBPHDC_receiveCompleted  all requested date are received.
 *  kUSBPHDC_receiveInProgress  previous receive opereation is in progress. The requested receive operation can be not started.
 *  kUSBPHDC_generalError  error occurred.
 */
uint8_t USBPHDC_receiveData (uint8_t* data, uint16_t size, uint8_t intfNum)
{
    uint8_t nTmp1;
    uint8_t edbIndex;
    uint16_t state;

    edbIndex = stUsbHandle[intfNum].edb_Index;

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

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

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

    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){             //receive process already started
    	usbRestoreOutEndpointInterrupt(state);
        return (kUSBPHDC_intfBusyError);
    }

    PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size;               //bytes to receive
    PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size;           //left bytes to receive
    PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data;                   //set user receive buffer

    //read rest of data from buffer, if any4
    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){
        //copy data from pEP-endpoint into User's buffer
        PHDCCopyUsbToBuff(PHDCReadCtrl[INTFNUM_OFFSET(
                                           intfNum)].pCurrentEpPos,
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);

        if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){    //the Receive opereation is completed
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;           //no more receiving pending
            if (wUsbEventMask & USB_RECEIVED_COMPLETED_EVENT){
                USBPHDC_handleReceiveCompleted(intfNum);                        //call event handler in interrupt context
            }
            usbRestoreOutEndpointInterrupt(state);
            return (kUSBPHDC_receiveCompleted);                                 //receive completed
        }

        //check other EP buffer for data - exchange pCT1 with pCT2
        if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 ==
            &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX){
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (uint8_t*)stUsbHandle[intfNum].oep_Y_Buffer;
        } else   {
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (uint8_t*)stUsbHandle[intfNum].oep_X_Buffer;
        }

        nTmp1 = *PHDCReadCtrl[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
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1;           //holds how many valid bytes in the EP buffer
            PHDCCopyUsbToBuff(PHDCReadCtrl[INTFNUM_OFFSET(
                                               intfNum)].pCurrentEpPos,
                PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);
        }

        if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){    //the Receive opereation is completed
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;           //no more receiving pending
            if (wUsbEventMask & USB_RECEIVED_COMPLETED_EVENT){
                USBPHDC_handleReceiveCompleted(intfNum);                        //call event handler in interrupt context
            }
            usbRestoreOutEndpointInterrupt(state);
            return (kUSBPHDC_receiveCompleted);                                 //receive completed
        }
    } //read rest of data from buffer, if any

    //read 'fresh' data, if available
    nTmp1 = 0;
    if (PHDCReadCtrl[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
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (uint8_t*)stUsbHandle[intfNum].oep_X_Buffer;
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;

            //second EP buffer
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
                (uint8_t*)stUsbHandle[intfNum].oep_Y_Buffer;
            PHDCReadCtrl[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
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (uint8_t*)stUsbHandle[intfNum].oep_Y_Buffer;
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;

            //second EP buffer
            PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
                (uint8_t*)stUsbHandle[intfNum].oep_X_Buffer;
            PHDCReadCtrl[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 = *PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
        while (nTmp1 == 0)
        {
            nTmp1 = *PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
        }

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

            PHDCCopyUsbToBuff(PHDCReadCtrl[INTFNUM_OFFSET(
                                               intfNum)].pCurrentEpPos,
                PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1, intfNum);

            nTmp1 = *PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
            //try read data from second buffer
            if ((PHDCReadCtrl[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
                PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1;       //holds how many valid bytes in the EP buffer
                PHDCCopyUsbToBuff(PHDCReadCtrl[INTFNUM_OFFSET(
                                                   intfNum)].pEP2,
                    PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2, intfNum);
                PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                    PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
            }
        }
    }

    if (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){        //the Receive opereation is completed
        PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;               //no more receiving pending
        if (wUsbEventMask & USB_RECEIVED_COMPLETED_EVENT){
            USBPHDC_handleReceiveCompleted(intfNum);                            //call event handler in interrupt context
        }
        usbRestoreOutEndpointInterrupt(state);
        return (kUSBPHDC_receiveCompleted);
    }

    //interrupts enable
    usbRestoreOutEndpointInterrupt(state);
    return (kUSBPHDC_receiveStarted);
}
Example #10
0
uint8_t USBMSC_pollCommand ()
{
	uint16_t state;
    uint8_t edbIndex;
    uint8_t * pCT1;
    uint8_t * pCT2;

    edbIndex = stUsbHandle[MSC0_INTFNUM].edb_Index;
    pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX;
    pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY;

    //check if currently transmitting data..
    if (MscReadControl.bReadProcessing == TRUE){
    	state = usbDisableOutEndpointInterrupt(edbIndex);
        //atomic operation - disable interrupts
        if ((MscReadControl.dwBytesToSendLeft == 0) &&
            (MscReadControl.lbaCount == 0)){
            //data is no more processing - clear flags..
            MscReadControl.bReadProcessing = FALSE;
            usbRestoreOutEndpointInterrupt(state);
        } else {
            if (!(tInputEndPointDescriptorBlock[edbIndex].bEPCNF &
                  EPCNF_STALL)){                    //if it is not stalled - contiune communication
                USBIEPIFG |= 1 << (edbIndex + 1);   //trigger IN interrupt to finish data tranmition
            }
            usbRestoreOutEndpointInterrupt(state);
            return (USBMSC_PROCESS_BUFFER);
        }
    }

    if (MscState.isMSCConfigured == FALSE){
        return (USBMSC_OK_TO_SLEEP);
    }

    if (!MscState.bMscSendCsw){
        if (MscState.bMscCbwReceived){
            if (Scsi_Verify_CBW() == SUCCESS){
                //Successful reception of CBW
                //Parse the CBW opcode and invoke the right command handler function
                Scsi_Cmd_Parser(MSC0_INTFNUM);
                MscState.bMscSendCsw = TRUE;
            }
            MscState.bMscCbwReceived = FALSE;       //CBW is performed!
        } else {
            return (USBMSC_OK_TO_SLEEP);
        }
        //check if any of out pipes has pending data and trigger interrupt

        if ((MscWriteControl.pCT1 != NULL)   &&
            ((*MscWriteControl.pCT1 & EPBCNT_NAK ) ||
             (*MscWriteControl.pCT2 & EPBCNT_NAK ))){
            USBOEPIFG |= 1 << (edbIndex + 1);       //trigger OUT interrupt again
            return (USBMSC_PROCESS_BUFFER);            //do not asleep, as data is coming in
            //and follow up data perform will be required.
        }
    }

    if (MscState.bMscSendCsw){
        if (MscState.bMcsCommandSupported == TRUE){
            //watiting till transport is finished!
            if ((MscWriteControl.bWriteProcessing == FALSE) &&
                (MscReadControl.bReadProcessing == FALSE) &&
                (MscReadControl.lbaCount == 0)){
                //Send CSW
                if (MscState.stallAtEndofTx == TRUE) {
                	if ((*pCT1 & EPBCNT_NAK) && (*pCT2 & EPBCNT_NAK)) {
                		MscState.stallAtEndofTx = FALSE;
                		usbStallInEndpoint(MSC0_INTFNUM);
                	}
                }
                else if (SUCCESS == Scsi_Send_CSW(MSC0_INTFNUM)){
                    MscState.bMscSendCsw = FALSE;
                    return (USBMSC_OK_TO_SLEEP);
                }
            }		
            else {
            	MSCFromHostToBuffer();
            }
        }
    }

    return (USBMSC_PROCESS_BUFFER);                 //When MscState.bMcsCommandSupported = FALSE, bReadProcessing became true, and
                                                    //bWriteProcessing = true.
}
Example #11
0
/*
 * Receives data over interface intfNum, of size size, into memory starting at address data.
 * Returns:
 *  kUSBHID_receiveStarted  if the receiving process started.
 *  kUSBHID_receiveCompleted  all requested date are received.
 *  kUSBHID_receiveInProgress  previous receive opereation is in progress. The requested receive operation can be not started.
 *  kUSBHID_generalError  error occurred.
 */
BYTE USBHID_receiveData (BYTE* data, WORD size, BYTE intfNum)
{
    BYTE nTmp1;
    WORD state;
    BYTE edbIndex;

    edbIndex = stUsbHandle[intfNum].edb_Index;

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

    state = usbDisableOutEndpointInterrupt(edbIndex);

    //atomic operation - disable interrupts

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

    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer != NULL){          //receive process already started
    	usbRestoreOutEndpointInterrupt(state);
        return (kUSBHID_receiveInProgress);
    }

    HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceive = size;            //bytes to receive
    HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft = size;        //left bytes to receive
    HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = data;                //set user receive buffer

    //read rest of data from buffer, if any
    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > 0){
        //copy data from pEP-endpoint into User's buffer
        HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(
                                         intfNum)].pCurrentEpPos,
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);

        if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;        //no more receiving pending
            USBHID_handleReceiveCompleted(intfNum);                         //call event handler in interrupt context
            usbRestoreOutEndpointInterrupt(state);
            return (kUSBHID_receiveCompleted);                              //receive completed
        }

        //check other EP buffer for data - exchange pCT1 with pCT2
        if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 ==
            &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX){
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
        } else {
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
        }
        nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;
        //try read data from second buffer
        if (nTmp1 & EPBCNT_NAK){                                            //if the second buffer has received data?
            nTmp1 = nTmp1 & 0x7f;                                           //clear NAK bit
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp =
                *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos + 1);  //holds how many valid bytes in the EP buffer
            if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2;
            }
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2;        //here starts user data
            HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(
                                             intfNum)].pCurrentEpPos,
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);
        }

        if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){ //the Receive opereation is completed
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;        //no more receiving pending
            if (wUsbEventMask & kUSB_receiveCompletedEvent){
                USBHID_handleReceiveCompleted(intfNum);                     //call event handler in interrupt context
            }
            usbRestoreOutEndpointInterrupt(state);
            return (kUSBHID_receiveCompleted);                              //receive completed
        }
    } //read rest of data from buffer, if any

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

            //second EP buffer
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
                (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;
            nTmp1 = 1;                                                      //indicate that data is available
        }
    } else {                                                                //Y_BUFFER
        if (tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){
            //this is the active EP buffer
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos =
                (BYTE*)stUsbHandle[intfNum].oep_Y_Buffer;
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTY;

            //second EP buffer
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 =
                (BYTE*)stUsbHandle[intfNum].oep_X_Buffer;
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2 =
                &tOutputEndPointDescriptorBlock[edbIndex].bEPBCTX;
            nTmp1 = 1;                                                      //indicate that data is available
        }
    }

    if (nTmp1){
        //how many byte we can get from one endpoint buffer
        nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1;

        if (nTmp1 & EPBCNT_NAK){
            nTmp1 = nTmp1 & 0x7f;                                           //clear NAK bit
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp =
                *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos + 1);  //holds how many valid bytes in the EP buffer
            if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 - 2){
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2;
            }
            HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos += 2;        //here starts user data
            HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(
                                             intfNum)].pCurrentEpPos,
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1,intfNum);

            nTmp1 = *HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
            //try read data from second buffer
            if ((HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft >
                 0) &&                                                      //do we have more data to receive?
                (nTmp1 & EPBCNT_NAK)){                                      //if the second buffer has received data?
                nTmp1 = nTmp1 & 0x7f;                                       //clear NAK bit
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp =
                    *(HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 + 1);       //holds how many valid bytes in the EP buffer
                if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp > nTmp1 -
                    2){
                    HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = nTmp1 - 2;
                }
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].pEP2 += 2;             //here starts user data
                HidCopyUsbToBuff(HidReadCtrl[INTFNUM_OFFSET(
                                                 intfNum)].pEP2,
                    HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2,intfNum);
                HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT1 =
                    HidReadCtrl[INTFNUM_OFFSET(intfNum)].pCT2;
            }
        }
    }

    if (HidReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft == 0){     //the Receive opereation is completed
        HidReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer = NULL;            //no more receiving pending
        if (wUsbEventMask & kUSB_receiveCompletedEvent){
            USBHID_handleReceiveCompleted(intfNum);                         //call event handler in interrupt context
        }
        usbRestoreOutEndpointInterrupt(state);
        return (kUSBHID_receiveCompleted);
    }

    //interrupts enable
    usbRestoreOutEndpointInterrupt(state);
    return (kUSBHID_receiveStarted);
}