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.

MSP430F5529: Not able to write the commands on launchpad

Part Number: MSP430F5529


Team,

Can you please help with my customer's question below:

I am configuring MSP430F5529 Launchpad as a CDC device  and trying to communicate it  from Ubuntu terminal.

I have loaded the  TI stack on the microcontroller and successfully communicated using PuTTY from Ubuntu terminal.

Next , I want to use libUSB for communication with the micro  instead of PuTTY.

 

I am able to open the serial port using libusb but not able to write the commands.

Thanks

Viktorija

  • Hello Viktorija,

    What commands are you referring to? Are you referring to commands within a certain CDC Example? If so, which one?
  • I am the originator of this question ,command was probably not a appropriate word .I want to send a random string  "LED ON" from host PC to MSP430 over USB. Here is some background :MSP430 is running TIs  cdc stack and an example code to turn on the LED (GPIO 1.0) by inputting a text string 'LED ON'. I am using PuTTY to open the port, initiate communication and wite the string (command) to toggle GPIO .

    Now, I want to use libusb   instead of PuTTY .Using libusb I want to send a text string to turn on/toggle GPIO 1.0.Below is a code I am trying.

    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <libusb-1.0/libusb.h>
    
    #define VENDOR_ID      0x2047   // For Texas Instruments
    #define PRODUCT_ID     0x0013   // Texas Instruments
    
    #define ACM_CTRL_DTR   0x01
    #define ACM_CTRL_RTS   0x02
    
    /* used a global variable to keep the device handle
     */
    static struct libusb_device_handle *devh = NULL;
    
    /* The Endpoint address are hard coded for TI device
     */
    static int ep_in_addr  = 0x81; //EP 1 IN
    static int ep_out_addr = 0x02; //EP 2 OUT
    
    void write_char(unsigned char c)
    {
        /* To send a char to the device simply initiate a bulk_transfer to the
         * Endpoint with address ep_out_addr.
         */
        int actual_length;
        if (libusb_bulk_transfer(devh, ep_out_addr, &c, 1,
                                 &actual_length, 0) < 0) {
            fprintf(stderr, "Error while sending char\n");
        }
    }
    
    int read_chars(unsigned char * data, int size)
    {
        /* To receive characters from the device initiate a bulk_transfer to the
         * Endpoint with address ep_in_addr.
         */
        int actual_length;
        int rc = libusb_bulk_transfer(devh, ep_in_addr, data, size, &actual_length,
                                      1000);
        if (rc == LIBUSB_ERROR_TIMEOUT) {
            printf("timeout (%d)\n", actual_length);
            return -1;
        } else if (rc < 0) {
            fprintf(stderr, "Error while waiting for char\n");
            return -1;
        }
    
        return actual_length;
    }
    
    
    int main(int argc, char **argv)
    {
        int rc;
    
        /* Initialize libusb
         */
        rc = libusb_init(NULL);
        if (rc < 0) {
            fprintf(stderr, "Error initializing libusb: %s\n", libusb_error_name(rc));
            exit(1);
        }
    
        /* Set debugging output to max level.
         */
        libusb_set_debug(NULL, 3);
    
        /* Look for a specific device and open it.
         */
        devh = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID);
        if (!devh) {
            fprintf(stderr, "Error finding USB device\n");
            goto out;
        }
    
        /* As we are dealing with a
    -ACM device, it's highly probable that
         * Linux already attached the cdc-acm driver to this device.
         * We need to detach the drivers from all the USB interfaces. The CDC-ACM
         * Class defines two interfaces: the Control interface and the
         * Data interface.
         */
        for (int if_num = 0; if_num < 2; if_num++) {
            if (libusb_kernel_driver_active(devh, if_num)) {
                libusb_detach_kernel_driver(devh, if_num);
            }
            rc = libusb_claim_interface(devh, if_num);
    
            if (rc < 0) {
                fprintf(stderr, "Error claiming interface: %s\n",
                        libusb_error_name(rc));
                goto out;
            }
        }
    
        /* Start configuring the device:
         * - set line state
         */
        rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS,
                                    0, NULL, 0, 0);
        if (rc < 0) {
            fprintf(stderr, "Error during control transfer: %s\n",
                    libusb_error_name(rc));
        }
    
        /* - set line encoding: here 9600 8N1
         * 9600 = 0x2580 ~> 0x80, 0x25 in little endian
         */
        unsigned char encoding[] = { 0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08 };
        rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding,
                                    sizeof(encoding), 0);
        if (rc < 0) {
            fprintf(stderr, "Error during control transfer: %s\n",
                    libusb_error_name(rc));
        }
    
        /* We can now start sending or receiving data to the device
         */
        unsigned char buf[65];
        int len;
        
      
            write_char('LED ON');
            len = read_chars(buf, 64);
            buf[len] = 0;
            fprintf(stdout, "Received: \"%s\"\n", buf);
            sleep(1);
    
        libusb_release_interface(devh, 0);
    
    out:
        if (devh)
                libusb_close(devh);
        libusb_exit(NULL);
        return rc;
    }

  • Hello Jagbir,

    In the future when posting code to the forum, please use the "Use rich formatting" button to make your post. When pasting the code in, click the </> button so the code will be formatted properly for easy reading. I have already edited your post to do this.

    Judging from your text above, I assume you are using the second CDC example (LED On/Off/Flash) on the MSP430 Device. Is this example not working for you?

    As far as libUSB is concerned, this is a Linux library that I cannot help you with as I am not knowledgeable of it. If you are having any issues with the USB Library for MSP430F5529, I can help you with that, but it seems you were able to get this working properly via Putty interface.
  • The program is working when I use PuTTY but its not working with libUSB.
  • Hello Jagbir,

    Again I cannot help you with the libUSB portion of this. Once the MSP430 USB device is connected properly, it doesn't care what is attached, and as long as the data being sent over the USB line matches the type the application is looking for it should respond appropriately as you saw when connected via PuTTY.
  • Hi,
    The following code is adapted from TI cdc LED ON OFF example.This code works wel in windows in putty.When I run this code using PuTTY in Linux ,the moment I hit the first keyboard key. I keep getting garbage data
    on the putty screen.Sometimes the moment I plug in the MS430 and launch putty ,the screen gets filled with garbage values.
    I am clearing the buffer in code using 'USBCDC_rejectData (CDC0_INTFNUM) 'but it did not help.




    #include "driverlib.h" #include <stdio.h> //added by J.singh #include "USB_config/descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" // USB-specific functions #include "USB_API/USB_CDC_API/UsbCdc.h" #include "USB_app/usbConstructs.h" #include "hal.h" // NOTE: Modify hal.h to select a specific evaluation board and customize for your own board. uint8_t retInString (char* string); // Function declarations void initTimer(void); void setTimer_A_Parameters(void); // Global flags set by events volatile uint8_t bCDCDataReceived_event = FALSE; // Indicates data has been rx'ed // without an open rx operation #define MAX_STR_LENGTH 64 char wholeString[MAX_STR_LENGTH] = "" ; // Entire input str from last 'return' char pieceOfString[MAX_STR_LENGTH] = "" ; // Holds the new addition to the string char outString[MAX_STR_LENGTH] = "" ; // Holds the outgoing string int bytesSent ,bytesReceived; Timer_A_initUpModeParam Timer_A_params = {0}; /* ======== main ======== */ void main (void) { int i, myDelay, myDuration; char command[MAX_STR_LENGTH]; 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 initTimer(); // Prepare timer for LED toggling USB_setup(TRUE, TRUE); // Init USB & events; if a host is present, connect __enable_interrupt(); // Enable interrupts globally USBCDC_rejectData (CDC0_INTFNUM); GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);//LED 1.0 ON while (1) { uint8_t i; // 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: // Enter LPM0 (can't do LPM3 when active) __bis_SR_register(LPM0_bits + GIE); _NOP(); // Exit LPM on USB receive and perform a receive operation // If this is true, some data is in the buffer; begin receiving a cmd if (bCDCDataReceived_event){ // Add bytes in USB buffer to the string USBCDC_receiveDataInBuffer((uint8_t*)pieceOfString,MAX_STR_LENGTH,CDC0_INTFNUM); // Get the next piece of the string // Append new piece to the whole strcat(wholeString,pieceOfString); // Echo back the characters received USBCDC_sendDataInBackground((uint8_t*)pieceOfString, strlen(pieceOfString),CDC0_INTFNUM,0); // Has the user pressed Enter/return yet? if (retInString(wholeString)){ sscanf(wholeString, "%s %d %d", command, &myDelay, &myDuration); // Compare to string and respond if (!(strcmp(command, "kill"))){ // Turn off timerA Timer_A_stop(TIMER_A0_BASE); // Prepare the outgoing string strcpy(outString,"\r\LED OFF process started .\r\n\r\n"); // Send the response over USB USBCDC_sendDataInBackground((uint8_t*)outString, strlen(outString),CDC0_INTFNUM,0); for(i=0;i<=myDelay;i++){ _delay_cycles(8000000); } // Prepare the outgoing string strcpy(outString,"\r\nBye!!!\r\n\r\n"); // Send the response over USB USBCDC_sendDataInBackground((uint8_t*)outString, strlen(outString),CDC0_INTFNUM,0); // Turn off LED P1.0 GPIO_setOutputLowOnPin(LED_PORT, LED_PIN); _delay_cycles(6000000); // 0.6 seconds delay GPIO_setOutputHighOnPin(LED_PORTDELAY, LED_PINDELAY);//JS For Demo only //JS: Time to wake up. for(i=0;i<=myDuration;i++){ _delay_cycles(8000000); } // Prepare the outgoing string strcpy(outString,"\r\nNot yet.\r\nLED ON Again\r\n\r\n"); // Send the response over USB USBCDC_sendDataInBackground((uint8_t*)outString, strlen(outString),CDC0_INTFNUM,0); // Turn on LED P1.0 GPIO_setOutputHighOnPin(LED_PORT, LED_PIN); _delay_cycles(16000000); GPIO_setOutputLowOnPin(LED_PORTDELAY, LED_PINDELAY);//JS For Demo only } else { // Prepare the outgoing string //strcpy(outString,"\r\n Bad command!\r\n\r\n"); sprintf(outString,"\r\n Bad command! '%s'\r\n\r\n", command); // Send the response over USB USBCDC_sendDataInBackground((uint8_t*)outString, strlen(outString),CDC0_INTFNUM,0); } // Clear the string in preparation for the next one for (i = 0; i < MAX_STR_LENGTH; i++){ wholeString[i] = 0x00; } } bCDCDataReceived_event = FALSE; } 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: //Turn off LED P1.0 // GPIO_setOutputLowOnPin(LED_PORT, LED_PIN); __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) } // main() /* * ======== UNMI_ISR ======== */ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector = UNMI_VECTOR __interrupt void UNMI_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(UNMI_VECTOR))) UNMI_ISR (void) #else #error Compiler not found! #endif { switch (__even_in_range(SYSUNIV, SYSUNIV_BUSIFG)) { case SYSUNIV_NONE: __no_operation(); break; case SYSUNIV_NMIIFG: __no_operation(); break; case SYSUNIV_OFIFG: UCS_clearFaultFlag(UCS_XT2OFFG); UCS_clearFaultFlag(UCS_DCOFFG); SFR_clearInterrupt(SFR_OSCILLATOR_FAULT_INTERRUPT); break; case SYSUNIV_ACCVIFG: __no_operation(); break; case SYSUNIV_BUSIFG: // If the CPU accesses USB memory while the USB module is // suspended, a "bus error" can occur. This generates an NMI. If // USB is automatically disconnecting in your software, set a // breakpoint here and see if execution hits it. See the // Programmer's Guide for more information. SYSBERRIV = 0; //clear bus error flag USB_disable(); //Disable } } /* * ======== retInString ======== */ // This function returns true if there's an 0x0D character in the string; and if // so, it trims the 0x0D and anything that had followed it. uint8_t retInString (char* string) { uint8_t retPos = 0,i,len; char tempStr[MAX_STR_LENGTH] = ""; strncpy(tempStr,string,strlen(string)); // Make a copy of the string len = strlen(tempStr); // Find 0x0D; if not found, retPos ends up at len while ((tempStr[retPos] != 0x0A) && (tempStr[retPos] != 0x0D) && (retPos++ < len)) ; // If 0x0D was actually found... if ((retPos < len) && (tempStr[retPos] == 0x0D)){ for (i = 0; i < MAX_STR_LENGTH; i++){ // Empty the buffer string[i] = 0x00; } //...trim the input string to just before 0x0D strncpy(string,tempStr,retPos); //...and tell the calling function that we did so return ( TRUE) ; // If 0x0D was actually found... } else if ((retPos < len) && (tempStr[retPos] == 0x0A)){ // Empty the buffer for (i = 0; i < MAX_STR_LENGTH; i++){ string[i] = 0x00; } //...trim the input string to just before 0x0D strncpy(string,tempStr,retPos); //...and tell the calling function that we did so return ( TRUE) ; } else if (tempStr[retPos] == 0x0D){ for (i = 0; i < MAX_STR_LENGTH; i++){ // Empty the buffer string[i] = 0x00; } // ...trim the input string to just before 0x0D strncpy(string,tempStr,retPos); // ...and tell the calling function that we did so return ( TRUE) ; } else if (retPos < len){ for (i = 0; i < MAX_STR_LENGTH; i++){ // Empty the buffer string[i] = 0x00; } //...trim the input string to just before 0x0D strncpy(string,tempStr,retPos); //...and tell the calling function that we did so return ( TRUE) ; } return ( FALSE) ; // Otherwise, it wasn't found } /* * ======== setTimer_A_Parameters ======== */ // This function sets the timer A parameters void setTimer_A_Parameters() { Timer_A_params.clockSource = TIMER_A_CLOCKSOURCE_ACLK; Timer_A_params.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1; Timer_A_params.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE; Timer_A_params.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE; Timer_A_params.timerClear = TIMER_A_DO_CLEAR; Timer_A_params.startTimer = false; } /* * ======== initTimer ======== */ void initTimer (void) { // Configure timer parameters setTimer_A_Parameters(); // Start timer Timer_A_clearTimerInterrupt(TIMER_A0_BASE); // Set timer period to zero Timer_A_params.timerPeriod = 0; Timer_A_initUpMode(TIMER_A0_BASE, &Timer_A_params); } /* * ======== TIMER1_A0_ISR ======== */ #if defined(__TI_COMPILER_VERSION__) || (__IAR_SYSTEMS_ICC__) #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR (void) #elif defined(__GNUC__) && (__MSP430__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void) #else #error Compiler not found! #endif { GPIO_toggleOutputOnPin(LED_PORT, LED_PIN); } //Released_Version_5_20_06_02

  • Hello Jagbir,

    This issue sounds like the "Babbling Bug" aka USB10 erratum. Please see the errata document for the workaround for this.
  • Hello Jagbir,

    Were you able to resolve your issue? Due to no response, this thread will be closing soon.

**Attention** This is a public forum