/* * 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); }
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); }
/* * 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); }
/* * 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); }
/* * 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); }
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); }
/* * 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); }
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); }