This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430 USBCDC_handleReceiveCompleted not working?

Other Parts Discussed in Thread: MSP-EXP430F5529LP

Hello,

I have just started playing with USB communication with the MSP-EXP430F5529LP launchpad.  I wrote a very simple program to receive three 'serial'  bytes, but I'm not getting the behavior I expected.

The starting point for my code was the 'C4_PacketProtocol'  example (which works fine).  My version is much simpler.  I changed the initial receiveData function to receive three bytes (instead of just one) and then it just polls for the bDataReceiveCompleted_event flag, which is set inside USBCDC_handleReceiveCompleted per the original example. The example is a state machine that receives packets, but this version simply stops once the bDataReceiveCompleted flag is set.

When I run the code, execution gets to the while loop that polls for bDataReceiveCompleted, but it is never set to TRUE.  Just like the example, this flag is set in the USBCDC_handleReceiveCompleted event handler (the event handler or its code were not modified).  I do know other events are firing, since the code moves out of LPM0 and into the while loop.

Also, USBCDC_getInterfaceStatus is returning 0x04 (USBCDC_DATA_WAITING) and USBCDC_getBytesInUSBBuffer returns the number of bytes I sent, so the data is there - but for some reason I can't get the USBCDC_hangleReceiveCompleted to trigger.   

I've gone through the API documentation a few times, but I'm obviously still missing a key concept here...any ideas?

Thanks!

_______________

#include "hal.h"

// Global flags set by events
volatile uint8_t bDataReceiveCompleted_event = FALSE; // from USBCDC_handleReceiveCompleted in usbEventHandling.c
volatile uint8_t bCommandBeingProcessed = FALSE; //

// Application globals
uint16_t x,y;
uint8_t size;
char c[2] = "";

// The "size" byte can only be a single ASCII numerical digit, which means 1-9
#define bufferLen 11
uint8_t buffer[bufferLen];
char outString[65]; // Holds outgoing strings to be sent
uint16_t packetSize; // Packet Size - can be anywhere from 1-65535 bytes but for now set to a char

void main (void)

{

volatile uint8_t status;
volatile uint8_t bytesatPort;
WDT_A_hold(WDT_A_BASE); // Stop watchdog timer

// Minumum Vcore setting required for the USB API is PMM_CORE_LEVEL_2 .
PMM_setVCore(PMM_CORE_LEVEL_2);
USBHAL_initPorts(); // Config GPIOS for low-power (output low)
USBHAL_initClocks(8000000); // Config clocks. MCLK=SMCLK=FLL=8MHz; ACLK=REFO=32kHz
USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect

__enable_interrupt(); // Enable interrupts globally

while (1)
{
// Check the USB state and directly main loop accordingly
switch (USB_getConnectionState())
{
// This case is executed while your device is enumerated on the
// USB host
case ST_ENUM_ACTIVE:

// If no command is being processed, then open to receive the
// start of the "packet"

GPIO_setOutputLowOnPin(LED_PORT4,LED_PIN7); // Turn OFF green LED
// Only open it if we haven't already done so


if (!(USBCDC_getInterfaceStatus(CDC0_INTFNUM,&x,&y) & USBCDC_WAITING_FOR_RECEIVE))
{

GPIO_setOutputHighOnPin(LED_PORT4,LED_PIN7); // Turn on green LED if we go into waiting for receive

// Start a receive operation for three bytes, which will be the start of frame and the size byte.

if (USBCDC_receiveData(buffer,3,CDC0_INTFNUM) == USBCDC_BUS_NOT_AVAILABLE)
{
// Abort receive is BUS is not avialble

GPIO_setOutputLowOnPin(LED_PORT4, LED_PIN7);
__delay_cycles(1000000);
USBCDC_abortReceive(&x,CDC0_INTFNUM);
break;
} // GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);


}
__bis_SR_register(LPM0_bits + GIE); // go to sleep until event triggers
while (!bDataReceiveCompleted_event) // Wait until data is received
{
GPIO_setOutputHighOnPin(LED_PORT,LED_PIN); // blink the Red LED
__delay_cycles(1000000);
GPIO_setOutputLowOnPin(LED_PORT,LED_PIN);
__delay_cycles(1000000);
status = USBCDC_getInterfaceStatus(CDC0_INTFNUM,&x,&y);
bytesatPort = USBCDC_getBytesInUSBBuffer(CDC0_INTFNUM);
}

GPIO_setOutputLowOnPin(LED_PORT4,LED_PIN7); // Turn Off Green LED
while(1); // wait here

  • This code is unreadable; use the "Insert Code" button to insert code.

    Specify exactly what you have changed from the example.
  • Clemens, thanks for the tip on using "Insert Code". I also updated the text to show the differences from the example code. The initialization code and event handler code is identical. The example is a state machine that receives simple packets. My version simply sets up a receive operation (for 3 bytes instead of just one) and stops once the flag in the event handler is set.
  • There might be a race condition between the main loop and the interrupt. In any case, this code does not look like the example in figure 35 of the Programmer's Guide; please try that first.
  • Hi Luis,

    You application is set to put the device to sleep till you receive all 3 bytes of data.  The following line of code puts your device to sleep:

    __bis_SR_register(LPM0_bits + GIE); // go to sleep until event triggers

    The only way the device will wakeup is when the bDataReceiveCompleted_event is triggered.  This event is triggered when all 3 bytes are received. 

    When the device is sleeping only the events that have occured before the device is put to sleep is kept as is. 

    If you want the RED LED to blink then I suggest you comment out the above line of code. 

    On the other hand if you want both the GREEN and RED LED to work, then move the above line of code to after executing the following code block:

    while (!bDataReceiveCompleted_event) // Wait until data is received

    {

    .......

    }

     

    Regards,

    Arthi Bhat

     

  • Hi Arthi,

    Thanks for the input.  What you described is the behavior I expect. However,  when I run the code, the device comes out of sleep, but it gets 'stuck' in the while loop waiting for !bDataReceiveCompleted_event to be TRUE, even after I send it three bytes.  

    I re-read through section 11 of the USB of the Programmer's guide over the weekend and have a couple of ideas to try - just haven't had time so far.  I'll report back once I get things working.

    Thanks

  • Hi Luis,

    You need to re-write your code to make it work properly.  Please follow the C4 example or the other examples provided in the developers package.  Checking the events and re-setting them once they are checked are important to get CDC to work properly.  

     Regards,

    Arthi Bhat

  • Hi Luis,

    I have re-written your code.  I made a couple of changes.  One of them is to replace the blinking LED with a solid LED in the code block that is executed when there is no data being sent.  The other is that I added some code that resets the bDataReceivedCompleted_event to FALSE so that your program can be re-run continuously.

        while (1)
        {
            // Check the USB state and directly main loop accordingly
            switch (USB_getConnectionState())
            {
                // This case is executed while your device is enumerated on the
                // USB host
                case ST_ENUM_ACTIVE:
                    // If no command is being processed, then open to receive the
                    // start of the "packet"
                	GPIO_setOutputLowOnPin(LED_PORT4,LED_PIN7); // Turn OFF green LED
                	// Only open it if we haven't already done so
                	
                	if (!(USBCDC_getInterfaceStatus(CDC0_INTFNUM,&x,&y) & USBCDC_WAITING_FOR_RECEIVE))
                	{
                   	   GPIO_setOutputHighOnPin(LED_PORT4,LED_PIN7); // Turn on green LED if we go into waiting for receive
    
                	   // Start a receive operation for three bytes, which will be the start of frame and the size byte.
                	   if (USBCDC_receiveData(buffer,3,CDC0_INTFNUM) == USBCDC_BUS_NOT_AVAILABLE)
                	   {
                	       // Abort receive is BUS is not avialble
                	       GPIO_setOutputLowOnPin(LED_PORT4, LED_PIN7);
                	       __delay_cycles(1000000);
                	       USBCDC_abortReceive(&x,CDC0_INTFNUM);
                	       break;
                	   } // GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);
                	}
                 	while (!bDataReceiveCompleted_event) // Wait until data is received
                	{
                     	GPIO_setOutputHighOnPin(LED_PORT,LED_PIN); // blink the Red LED
         //       	   __delay_cycles(1000000);
         //       	   GPIO_setOutputLowOnPin(LED_PORT,LED_PIN);
        //        	   __delay_cycles(1000000);
                	   status = USBCDC_getInterfaceStatus(CDC0_INTFNUM,&x,&y);
                	   bytesatPort = USBCDC_getBytesInUSBBuffer(CDC0_INTFNUM);
                	}
                    //check for data received completion event
                	if (bDataReceiveCompleted_event)
                	{
                		//reset the event
                		bDataReceiveCompleted_event = FALSE;
                        GPIO_setOutputLowOnPin(LED_PORT,LED_PIN);
                		GPIO_setOutputLowOnPin(LED_PORT4,LED_PIN7); // Turn Off Green LED
                	    __delay_cycles(1000000);
    
                	}
                    break;
                // These cases are executed while your device is disconnected from
                // the host (meaning, not enumerated); enumerated but suspended
                // by the host, or connected to a powered hub without a USB host
                // present.
                case ST_PHYS_DISCONNECTED:
                case ST_ENUM_SUSPENDED:
                case ST_PHYS_CONNECTED_NOENUM_SUSP:
                    __bis_SR_register(LPM3_bits + GIE);
                    _NOP();
                    break;
    
                // The default is executed for the momentary state
                // ST_ENUM_IN_PROGRESS.  Usually, this state only last a few
                // seconds.  Be sure not to enter LPM3 in this state; USB
                // communication is taking place here, and therefore the mode must
                // be LPM0 or active-CPU.
                case ST_ENUM_IN_PROGRESS:
                default:;
            }
    
        }  // while(1)

    Regards,

    Arthi

  • Hi Arthi,

    Thanks! between this and re-reading Chapter 11 of the developer's guide, I now have something that works.

**Attention** This is a public forum