/* 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 is used only by USB interrupt BOOL HidToHostFromBuffer() { BYTE byte_count, nTmp2; BYTE * pEP1; BYTE * pEP2; BYTE * pCT1; BYTE * pCT2; BYTE bWakeUp = FALSE; // per default we do not wake up after interrupt if (HidWriteCtrl.nHidBytesToSendLeft == 0) // do we have somtething to send? { HidWriteCtrl.nHidBytesToSend = 0; //call event callback function if (wUsbEventMask & kUSB_sendCompletedEvent) { bWakeUp = USBHID_handleSendCompleted(1); } return bWakeUp; } if(!(tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPCNF & EPCNF_TOGGLE)) { //this is the active EP buffer pEP1 = (BYTE*)IEP1_X_BUFFER_ADDRESS; pCT1 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX; //second EP buffer pEP2 = (BYTE*)IEP1_Y_BUFFER_ADDRESS; pCT2 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)IEP1_Y_BUFFER_ADDRESS; pCT1 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTY; //second EP buffer pEP2 = (BYTE*)IEP1_X_BUFFER_ADDRESS; pCT2 = &tInputEndPointDescriptorBlock[EDB(HID_INEP_ADDR)].bEPBCTX; } // how many byte we can send over one endpoint buffer // 2 bytes a reserved: [0] - HID Report Descriptor, [1] - count of valid bytes byte_count = (HidWriteCtrl.nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl.nHidBytesToSendLeft; nTmp2 = *pCT1; if(nTmp2 & EPBCNT_NAK) { USB_TX_memcpy(pEP1+2, HidWriteCtrl.pHidBufferToSend, byte_count); // copy data into IEP3 X or Y buffer pEP1[0] = 0x3F; // set HID report descriptor: 0x3F pEP1[1] = byte_count; // set HID report descriptor // 64 bytes will be send: we use only one HID report descriptor *pCT1 = 0x40; // Set counter for usb In-Transaction HidWriteCtrl.nHidBytesToSendLeft -= byte_count; HidWriteCtrl.pHidBufferToSend += byte_count; // move buffer pointer //try to send data over second buffer nTmp2 = *pCT2; if ((HidWriteCtrl.nHidBytesToSendLeft > 0) && // do we have more data to send? (nTmp2 & EPBCNT_NAK)) // if the second buffer is free? { // how many byte we can send over one endpoint buffer byte_count = (HidWriteCtrl.nHidBytesToSendLeft > EP_MAX_PACKET_SIZE-2) ? EP_MAX_PACKET_SIZE-2 : HidWriteCtrl.nHidBytesToSendLeft; USB_TX_memcpy(pEP2+2, HidWriteCtrl.pHidBufferToSend, byte_count); // copy data into IEP3 X or Y buffer pEP2[0] = 0x3F; // set HID report descriptor: 0x3F pEP2[1] = byte_count; // set byte count of valid data // 64 bytes will be send: we use only one HID report descriptor *pCT2 = 0x40; // Set counter for usb In-Transaction HidWriteCtrl.nHidBytesToSendLeft -= byte_count; HidWriteCtrl.pHidBufferToSend += byte_count; // move buffer pointer } } return bWakeUp; }
//this function is used only by USB interrupt int16_t PHDCToHostFromBuffer (uint8_t intfNum) { uint8_t byte_count, nTmp2; uint8_t * pEP1; uint8_t * pEP2; uint8_t * pCT1; uint8_t * pCT2; uint8_t bWakeUp = FALSE; //TRUE for wake up after interrupt uint8_t edbIndex; edbIndex = stUsbHandle[intfNum].edb_Index; if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft == 0){ //do we have somtething to send? if (!PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent){ //zero packet was not yet sent PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = TRUE; if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend == EP_MAX_PACKET_SIZE_PHDC){ if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTX & EPBCNT_NAK){ tInputEndPointDescriptorBlock[edbIndex].bEPBCTX = 0; PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = Y_BUFFER; //switch buffer } } else { if (tInputEndPointDescriptorBlock[edbIndex].bEPBCTY & EPBCNT_NAK){ tInputEndPointDescriptorBlock[edbIndex].bEPBCTY = 0; PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = X_BUFFER; //switch buffer } } } PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSend = 0; //nothing to send //call event callback function if (wUsbEventMask & USB_SEND_COMPLETED_EVENT){ bWakeUp = USBPHDC_handleSendCompleted(intfNum); } } //if (!bSentZeroPacket) return (bWakeUp); } PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bZeroPacketSent = FALSE; //zero packet will be not sent: we have data if (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY == X_BUFFER){ //this is the active EP buffer pEP1 = (uint8_t*)stUsbHandle[intfNum].iep_X_Buffer; pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX; //second EP buffer pEP2 = (uint8_t*)stUsbHandle[intfNum].iep_Y_Buffer; pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY; } else { //this is the active EP buffer pEP1 = (uint8_t*)stUsbHandle[intfNum].iep_Y_Buffer; pCT1 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTY; //second EP buffer pEP2 = (uint8_t*)stUsbHandle[intfNum].iep_X_Buffer; pCT2 = &tInputEndPointDescriptorBlock[edbIndex].bEPBCTX; } //how many byte we can send over one endpoint buffer byte_count = (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft > EP_MAX_PACKET_SIZE_PHDC) ? EP_MAX_PACKET_SIZE_PHDC : PHDCWriteCtrl[ INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft; nTmp2 = *pCT1; if (nTmp2 & EPBCNT_NAK){ USB_TX_memcpy(pEP1, PHDCWriteCtrl[INTFNUM_OFFSET( intfNum)].pUsbBufferToSend, byte_count); //copy data into IEP3 X or Y buffer *pCT1 = byte_count; //Set counter for usb In-Transaction PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01; //switch buffer PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft -= byte_count; PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count; //move buffer pointer PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count; //try to send data over second buffer nTmp2 = *pCT2; if ((PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft > 0) && //do we have more data to send? (nTmp2 & EPBCNT_NAK)){ //if the second buffer is free? //how many byte we can send over one endpoint buffer byte_count = (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft > EP_MAX_PACKET_SIZE_PHDC) ? EP_MAX_PACKET_SIZE_PHDC : PHDCWriteCtrl[ INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft; USB_TX_memcpy(pEP2, PHDCWriteCtrl[INTFNUM_OFFSET( intfNum)].pUsbBufferToSend, byte_count); //copy data into IEP3 X or Y buffer *pCT2 = byte_count; //Set counter for usb In-Transaction PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY = (PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].bCurrentBufferXY + 1) & 0x01; //switch buffer PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].nPHDCBytesToSendLeft -= byte_count; PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].pUsbBufferToSend += byte_count; //move buffer pointer PHDCWriteCtrl[INTFNUM_OFFSET(intfNum)].last_ByteSend = byte_count; } } return (bWakeUp); }
//this function is used only by USB interrupt BOOL CdcToHostFromBuffer() { BYTE byte_count, nTmp2; BYTE * pEP1; BYTE * pEP2; BYTE * pCT1; BYTE * pCT2; BYTE bWakeUp = FALSE; //TRUE for wake up after interrupt static BYTE bZeroPacketSent; // = FALSE; if (CdcWriteCtrl.nCdcBytesToSendLeft == 0) // do we have somtething to send? { if (!bZeroPacketSent) // zero packet was not yet sent { bZeroPacketSent = TRUE; CdcWriteCtrl.nCdcBytesToSend = 0; // nothing to send //call event callback function if (wUsbEventMask & kUSB_sendCompletedEvent) { bWakeUp = USBCDC_handleSendCompleted(1); } } // if (!bSentZeroPacket) return bWakeUp; } bZeroPacketSent = FALSE; // zero packet will be not sent: we have data if (CdcWriteCtrl.bCurrentBufferXY == X_BUFFER) { //this is the active EP buffer pEP1 = (BYTE*)IEP3_X_BUFFER_ADDRESS; pCT1 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX; //second EP buffer pEP2 = (BYTE*)IEP3_Y_BUFFER_ADDRESS; pCT2 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY; } else { //this is the active EP buffer pEP1 = (BYTE*)IEP3_Y_BUFFER_ADDRESS; pCT1 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTY; //second EP buffer pEP2 = (BYTE*)IEP3_X_BUFFER_ADDRESS; pCT2 = &tInputEndPointDescriptorBlock[EDB(CDC_INEP_ADDR)].bEPBCTX; } // how many byte we can send over one endpoint buffer byte_count = (CdcWriteCtrl.nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl.nCdcBytesToSendLeft; nTmp2 = *pCT1; if(nTmp2 & EPBCNT_NAK) { USB_TX_memcpy(pEP1, CdcWriteCtrl.pBufferToSend, byte_count); // copy data into IEP3 X or Y buffer *pCT1 = byte_count; // Set counter for usb In-Transaction CdcWriteCtrl.bCurrentBufferXY = (CdcWriteCtrl.bCurrentBufferXY+1)&0x01; //switch buffer CdcWriteCtrl.nCdcBytesToSendLeft -= byte_count; CdcWriteCtrl.pBufferToSend += byte_count; // move buffer pointer //try to send data over second buffer nTmp2 = *pCT2; if ((CdcWriteCtrl.nCdcBytesToSendLeft > 0) && // do we have more data to send? (nTmp2 & EPBCNT_NAK)) // if the second buffer is free? { // how many byte we can send over one endpoint buffer byte_count = (CdcWriteCtrl.nCdcBytesToSendLeft > EP_MAX_PACKET_SIZE_CDC) ? EP_MAX_PACKET_SIZE_CDC : CdcWriteCtrl.nCdcBytesToSendLeft; USB_TX_memcpy(pEP2, CdcWriteCtrl.pBufferToSend, byte_count); // copy data into IEP3 X or Y buffer *pCT2 = byte_count; // Set counter for usb In-Transaction CdcWriteCtrl.bCurrentBufferXY = (CdcWriteCtrl.bCurrentBufferXY+1)&0x01; //switch buffer CdcWriteCtrl.nCdcBytesToSendLeft -= byte_count; CdcWriteCtrl.pBufferToSend += byte_count; //move buffer pointer } } return bWakeUp; }