Example #1
0
/* This construct implements pre-call polling to ensure the sending completes before the function
 * returns.  It provides simple coding while also taking advantage of the efficiencies of background
 * processing.  If a previous send operation is underway, this function does waste cycles polling,
 * like xxxsendDataWaitTilDone(); however it's less likely to do so since much of the sending
 * presumably took place in the background since the last call to xxxsendDataInBackground().
 * The function also checks all valid return codes, and returns non-zero if an error occurred.
 * It assumes no previous send operation is underway; also assumes size is non-zero.
 * This call assumes a previous send operation might be underway; also assumes size is non-zero.
 * Returns zero if send completed; non-zero if it failed, with 1 = timeout and 2 = bus is gone. */
BYTE cdcSendDataInBackground (BYTE* dataBuf,
    WORD size,
    BYTE intfNum,
    ULONG ulTimeout)
{
    ULONG sendCounter = 0;
    WORD bytesSent, bytesReceived;

    while (USBCDC_intfStatus(intfNum,&bytesSent,
               &bytesReceived) & kUSBCDC_waitingForSend){
        if (ulTimeout && ((sendCounter++) > ulTimeout)){    /* A send operation is underway; incr counter & try again */
            return ( 1) ;                                   /* Timed out                */
        }
    }

    /* The interface is now clear.  Call sendData().   */
    switch (USBCDC_sendData(dataBuf,size,intfNum)){
        case kUSBCDC_sendStarted:
            return ( 0) ;
        case kUSBCDC_busNotAvailable:
            return ( 2) ;
        default:
            return ( 4) ;
    }
}
Example #2
0
/* This construct implements post-call polling to ensure the sending completes before the function
returns.  It provides the simplest coding, at the expense of wasted cycles and potentially
allowing MCU execution to become "locked" to the host, a disadvantage if the host (or bus) is
slow.  The function also checks all valid return codes, and returns non-zero if an error occurred.
It assumes no previous send operation is underway; also assumes size is non-zero.  */
BYTE cdcSendDataWaitTilDone(BYTE* dataBuf, WORD size, BYTE intfNum, ULONG ulTimeout)
{
  ULONG sendCounter = 0;
  WORD bytesSent, bytesReceived;

  switch(USBCDC_sendData(dataBuf,size,intfNum))
  {
     case kUSBCDC_sendStarted:
          break;
     case kUSBCDC_busNotAvailable:
          return 2;
     case kUSBCDC_intfBusyError:
          return 3;
     case kUSBCDC_generalError:
          return 4;
     default:;
  }

  /* If execution reaches this point, then the operation successfully started.  Now wait til it's finished. */
  while(1) {
    BYTE ret = USBCDC_intfStatus(intfNum,&bytesSent,&bytesReceived);
    if(ret & kUSBCDC_busNotAvailable)                /* This may happen at any time */
      return 2;
    if(ret & kUSBCDC_waitingForSend) {
      if(ulTimeout && (sendCounter++ >= ulTimeout))  /* Incr counter & try again */
        return 1 ;                                   /* Timed out */
    }
    else
      return 0;                                   /* If neither busNotAvailable nor waitingForSend, it succeeded */
  }
}
Example #3
0
/* This construct implements post-call polling to ensure the sending completes before the function
 * returns.  It provides the simplest coding, at the expense of wasted cycles and potentially
 * allowing MCU execution to become "locked" to the host, a disadvantage if the host (or bus) is
 * slow.  The function also checks all valid return codes, and returns non-zero if an error occurred.
 * It assumes no previous send operation is underway; also assumes size is non-zero.  */
uint8_t cdcSendDataWaitTilDone (uint8_t* dataBuf,
    uint16_t size,
    uint8_t intfNum,
    uint32_t ulTimeout)
{
    uint32_t sendCounter = 0;
    uint16_t bytesSent, bytesReceived;

    switch (USBCDC_sendData(dataBuf,size,intfNum))
    {
        case kUSBCDC_sendStarted:
            break;
        case kUSBCDC_busNotAvailable:
            return ( 2) ;
        case kUSBCDC_intfBusyError:
            return ( 3) ;
        case kUSBCDC_generalError:
            return ( 4) ;
        default:;
    }

    /* If execution reaches this point, then the operation successfully started.  Now wait til it's finished. */
    while (1){
        uint8_t ret = USBCDC_intfStatus(intfNum,&bytesSent,&bytesReceived);
        if (ret & kUSBCDC_busNotAvailable){                 /* This may happen at any time */
            return ( 2) ;
        }
        if (ret & kUSBCDC_waitingForSend){
            if (ulTimeout && (sendCounter++ >= ulTimeout)){ /* Incr counter & try again */
                return ( 1) ;                               /* Timed out */
            }
        } else {
            return ( 0) ;                                   /* If neither busNotAvailable nor waitingForSend, it succeeded */
        }
    }
}
Example #4
0
/*----------------------------------------------------------------------------+
| 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()