/* 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; // do not access USB memory if suspended (PLL off). It may produce BUS_ERROR if ((bFunctionSuspended) || (bEnumerationStatus != ENUMERATION_COMPLETE)) { return kUSBHID_busNotAvailable; } if (HidReadCtrl.bCurrentBufferXY == X_BUFFER) //this is current buffer { if (tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX & EPBCNT_NAK) //this buffer has a valid data packet { //this is the active EP buffer //pEP1 HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; nTmp1 = 1; //indicate that data is available } } else // Y_BUFFER if (tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY & EPBCNT_NAK) { //this is the active EP buffer HidReadCtrl.pCurrentEpPos = (BYTE*)OEP1_Y_BUFFER_ADDRESS; HidReadCtrl.pCT1 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTY; //second EP buffer HidReadCtrl.pEP2 = (BYTE*)OEP1_X_BUFFER_ADDRESS; HidReadCtrl.pCT2 = &tOutputEndPointDescriptorBlock[EDB(HID_OUTEP_ADDR)].bEPBCTX; nTmp1 = 1; //indicate that data is available } if (nTmp1) { // how many byte we can get from one endpoint buffer nTmp1 = *HidReadCtrl.pCT1; if(nTmp1 & EPBCNT_NAK) { nTmp1 = nTmp1 &0x7f; // clear NAK bit HidReadCtrl.nBytesInEp = nTmp1; // holds how many valid bytes in the EP buffer USB_RX_memcpy(reportData, HidReadCtrl.pCurrentEpPos, nTmp1); HidReadCtrl.bCurrentBufferXY = (HidReadCtrl.bCurrentBufferXY+1) &0x01; HidReadCtrl.nBytesInEp = 0; *HidReadCtrl.pCT1 = 0; // clear NAK, EP ready to receive data ret = kUSBHID_receiveCompleted; } } return ret; }
//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 PHDCCopyUsbToBuff (uint8_t* pEP, uint8_t* pCT, uint8_t intfNum) { uint8_t nCount; //how many byte we can get from one endpoint buffer nCount = (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft > PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp) ? PHDCReadCtrl[ INTFNUM_OFFSET(intfNum)].nBytesInEp : PHDCReadCtrl[INTFNUM_OFFSET( intfNum)]. nBytesToReceiveLeft; USB_RX_memcpy(PHDCReadCtrl[INTFNUM_OFFSET( intfNum)].pUserBuffer, pEP, nCount); //copy data from OEP3 X or Y buffer PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesToReceiveLeft -= nCount; PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pUserBuffer += nCount; //move buffer pointer //to read rest of data next time from this place if (nCount == PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp){ //all bytes are copied from receive buffer? //switch current buffer PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01; PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp = 0; //clear NAK, EP ready to receive data *pCT = 0x00; } else { PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].nBytesInEp -= nCount; PHDCReadCtrl[INTFNUM_OFFSET(intfNum)].pCurrentEpPos = pEP + nCount; } }
// 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 copies data from OUT endpoint into user's buffer // Arguments: // pEP - pointer to EP to copy from // pCT - pointer to pCT control reg // VOID CopyUsbToBuff(BYTE* pEP, BYTE* pCT) { BYTE nCount; // how many byte we can get from one endpoint buffer nCount = (CdcReadCtrl.nBytesToReceiveLeft > CdcReadCtrl.nBytesInEp) ? CdcReadCtrl.nBytesInEp : CdcReadCtrl.nBytesToReceiveLeft; USB_RX_memcpy(CdcReadCtrl.pUserBuffer, pEP, nCount); // copy data from OEP3 X or Y buffer CdcReadCtrl.nBytesToReceiveLeft -= nCount; CdcReadCtrl.pUserBuffer += nCount; // move buffer pointer // to read rest of data next time from this place if (nCount == CdcReadCtrl.nBytesInEp) // all bytes are copied from receive buffer? { //switch current buffer CdcReadCtrl.bCurrentBufferXY = (CdcReadCtrl.bCurrentBufferXY+1) &0x01; CdcReadCtrl.nBytesInEp = 0; //clear NAK, EP ready to receive data *pCT = 0x00; } else { // set correct rest_data available in EP buffer if (CdcReadCtrl.nBytesInEp > nCount) { CdcReadCtrl.nBytesInEp -= nCount; CdcReadCtrl.pCurrentEpPos = pEP + nCount; } else { CdcReadCtrl.nBytesInEp = 0; } } }