/* This call only retrieves data that is already waiting in the USB buffer -- that is, data that has * already been received by the MCU. It assumes a previous, open receive operation (began by a direct * call to USBxxx_receiveData()) is NOT underway on this interface; and no receive operation remains * open after this call returns. It doesn't check for kUSBxxx_busNotAvailable, because it doesn't * matter if it's not. size is the maximum that is allowed to be received before exiting; i.e., it * is the size allotted to dataBuf. Returns the number of bytes received. */ WORD cdcReceiveDataInBuffer (BYTE* dataBuf, WORD size, BYTE intfNum) { WORD bytesInBuf; WORD rxCount = 0; BYTE* currentPos = dataBuf; while (bytesInBuf = USBCDC_bytesInUSBBuffer(intfNum)){ if ((WORD)(currentPos - dataBuf + bytesInBuf) <= size){ rxCount = bytesInBuf; USBCDC_receiveData(currentPos,rxCount,intfNum); currentPos += rxCount; } else { rxCount = size - (currentPos - dataBuf); USBCDC_receiveData(currentPos,rxCount,intfNum); currentPos += rxCount; return (currentPos - dataBuf); } } return (currentPos - dataBuf); }
/* This call only retrieves data that is already waiting in the USB buffer -- that is, data that has * already been received by the MCU. It assumes a previous, open receive operation (began by a direct * call to USBxxx_receiveData()) is NOT underway on this interface; and no receive operation remains * open after this call returns. It doesn't check for kUSBxxx_busNotAvailable, because it doesn't * matter if it's not. size is the maximum that is allowed to be received before exiting; i.e., it * is the size allotted to dataBuf. Returns the number of bytes received. */ uint16_t cdcReceiveDataInBuffer (uint8_t* dataBuf, uint16_t size, uint8_t intfNum) { uint16_t bytesInBuf; uint16_t rxCount = 0; uint8_t* currentPos = dataBuf; while (bytesInBuf = USBCDC_bytesInUSBBuffer(intfNum)){ if ((uint16_t)(currentPos - dataBuf + bytesInBuf) <= size){ rxCount = bytesInBuf; USBCDC_receiveData(currentPos,rxCount,intfNum); currentPos += rxCount; } else { rxCount = size - (currentPos - dataBuf); USBCDC_receiveData(currentPos,rxCount,intfNum); currentPos += rxCount; return (currentPos - dataBuf); } } return (currentPos - dataBuf); }
/* * ======== rxData ======== */ static unsigned int rxData(unsigned char *pStr, unsigned int length, unsigned int timeout) { unsigned char recvResult; unsigned int ret = 0; recvResult = USBCDC_receiveData(pStr, length, USBCDCD_INTFNUM); /* * We will pend on a Semaphore_pend() if we received a * USBCDC_RECEIVE_STARTED and block until we received all the data. If it * returned a USBCDC_RECEIVE_COMPLETED; a callback has already occurred * so we call Semaphore_post() to just consume it but it won't cause a * context switch. */ if ((recvResult == USBCDC_RECEIVE_STARTED) || (recvResult == USBCDC_RECEIVE_COMPLETED)) { if (!Semaphore_pend(semRxSerial, timeout)) { USBCDC_abortReceive(&length, USBCDCD_INTFNUM); } ret = length; } return (ret); }
/*----------------------------------------------------------------------------+ | Main Routine | +----------------------------------------------------------------------------*/ VOID main(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); USB_init(); USB_setEnabledEvents(kUSB_VbusOnEvent+kUSB_VbusOffEvent+kUSB_receiveCompletedEvent +kUSB_dataReceivedEvent+kUSB_UsbSuspendEvent+kUSB_UsbResumeEvent+kUSB_UsbResetEvent); // Check if we're already physically attached to USB, and if so, connect to it // This is the same function that gets called automatically when VBUS gets attached. if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); //PWRVBUSonHandler(); while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: if(!bCommandBeingProcessed) // If no command is being processed, then make sure there's a rcv operation { // open to receive the start of the "packet" if(!(USBCDC_intfStatus(0,&x,&y) & kUSBCDC_waitingForReceive)) // Only open it if we haven't already done so if(USBCDC_receiveData(buffer,1,0) == kUSBCDC_busNotAvailable) // Start a receive operation for a single byte -- the "size" byte of the "packet" { USBCDC_abortReceive(&x,0); // Abort receive break; // If bus is no longer available, escape out of the loop } } __bis_SR_register(LPM0_bits + GIE); // Wait in LPM0 until a receive operation has completed //__bis_SR_register(LPM0_bits + GIE); if(bDataReceiveCompleted_event) { bDataReceiveCompleted_event = FALSE; if(!bCommandBeingProcessed) // This means that the incoming byte is the start of the "packet" -- the "size" byte { if ((buffer[0]>=0x31) && (buffer[0]<= 0x39)) { size = buffer[0]-0x30; // It's in ASCII, so convert it to a number if(USBCDC_receiveData(buffer,size,0) == kUSBCDC_busNotAvailable) // And then open a rcv operation for that size { USBCDC_abortReceive(&x,0); // Abort receive break; // If bus is no longer available, escape out of the loop } bCommandBeingProcessed = TRUE; // Now we're waiting for the "data" part of the "packet" } else { strcpy(outString,"\r\nEnter a valid number between 1 and 9\r\n\r\n"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) // Send the response over USB { USBCDC_abortSend(&x,0); // Operation may still be open; cancel it break; // If the send fails, escape the main loop } bCommandBeingProcessed = FALSE; // Now we're back to waiting for the "size" byte } } else // This means that the incoming data is the "data" part of the "packet" { strcpy(outString,"\r\nI received your packet with size of "); // Prepare the outgoing string buffer[bufferLen-1]= 0; c[0] = (char)(size+'0'); c[1] = 0; outString[64] = 0; // Convert the size back to ASCII strcat(outString,c); strcat(outString," bytes.\r\n\r\n"); if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) // Send the response over USB { USBCDC_abortSend(&x,0); // Operation may still be open; cancel it break; // If the send fails, escape the main loop } bCommandBeingProcessed = FALSE; // Now we're back to waiting for the "size" byte } } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()
VOID main(VOID) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer Init_StartUp(); //initialize device USB_init(); USB_setEnabledEvents(USBEVIE); // See if we're already attached physically to USB, and if so, connect to it // Normally applications don't invoke the event handlers, but this is an exception. if (USB_connectionInfo() & kUSB_vbusPresent) USB_handleVbusOnEvent(); while(1) { switch(USB_connectionState()) { case ST_USB_DISCONNECTED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/interrupt _NOP(); break; case ST_USB_CONNECTED_NO_ENUM: break; case ST_ENUM_ACTIVE: __bis_SR_register(LPM0_bits + GIE); // Enter LPM0 until an event occurs. // This flag would have been set by the handleDataReceived event; this event is only enabled when waiting // for 'press any key' if(bCDCDataReceived_event) { bCDCDataReceived_event = FALSE; // Change the event flags, in preparation for receiving 1K data USBEVIE &= ~kUSB_dataReceivedEvent; // No more data-received. We only used this for 'press any key' USBEVIE |= kUSB_receiveCompletedEvent; // But enable receive-completed; we want to be prompted when 1K data has been received USB_setEnabledEvents(USBEVIE); USBCDC_rejectData(0); // We don't care what char the key-press was // Prompt user for 1K data strcpy(outString,"I'm ready to receive 1K of data.\r\n"); // Prepare the outgoing string if(cdcSendDataWaitTilDone((BYTE*)outString,strlen(outString),0,0)) // Send it over USB { USBCDC_abortSend(&x,0); // It failed for some reason; abort and leave the main loop break; } // Set up rcv operation for 1K data if(USBCDC_receiveData(dataBuff,1024,0) == kUSBCDC_busNotAvailable) //first USBCDC_receiveData { USBCDC_abortReceive(&x,0); // It failed because of surprise removal or suspended by host; break; // abort and leave the main loop } } // This flag would have been set by the handleReceiveCompleted event; this event is only enabled // while receiving 1K data, and signals that all 1K has been received if(bDataReceiveCompleted_event) { bDataReceiveCompleted_event = FALSE; strcpy(outString,"Thanks for the data.\r\n"); // Prepare the outgoing string if(cdcSendDataInBackground((BYTE*)outString,strlen(outString),0,0)) //Send the response over USB { USBCDC_abortSend(&x,0); // It failed for some reason; abort and leave the main loop break; } // Change the event flags, in preparation for 'press any key' USBEVIE &= ~kUSB_receiveCompletedEvent; // No more receive-completed. USBEVIE |= kUSB_dataReceivedEvent; // This will tell us that data -- any data -- has arrived (i.e., a key-press) USB_setEnabledEvents(USBEVIE); } break; case ST_ENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 w/ interrupts _NOP(); break; case ST_ENUM_IN_PROGRESS: break; case ST_NOENUM_SUSPENDED: __bis_SR_register(LPM3_bits + GIE); _NOP(); break; case ST_ERROR: _NOP(); break; default:; } } // while(1) } //main()