Page 1 of 1

Baudrate configuration in USB CDC firmware

Posted: Wed Sep 19, 2018 3:52 pm
by aicastell
I have a problem setting up the baudrate of my USB CDC serial port. This is my initial SerialDriver configuration:

Code: Select all

    // 9600, 8N1
    SerialConfig SD1_cfg = {
        9600,
        0,
        USART_CR2_STOP1_BITS,
        0
    };


The SerialDriver is initialized in this way:

Code: Select all

    sdObjectInit(&SD1, NULL, NULL);
    sdStart(&SD1, &SD1_cfg);


Opening the cdc usb-serial port and sending bytes

Code: Select all

    
    $ picocom  -b 9600  /dev/ttyACM0


works fine.

The problem is when I try to close that picocom connection, and re-open it with a different baudrate. To do that I have implemented these two cases in the custom requests_hook_cb callback of my USBDriver:

Code: Select all

    case CDC_GET_LINE_CODING
        usbSetupTransfer(usbp, (uint8_t *)&cdc_linecoding, sizeof(cdc_linecoding), NULL);
        return true; 

    case CDC_SET_LINE_CODING:
        usbSetupTransfer(usbp, (uint8_t *)&cdc_linecoding, sizeof(cdc_linecoding), NULL);
        setLineCoding(&cdc_linecoding);
        return true;


When I open the usb-serial port with a different baudrate:

Code: Select all

    $ picocom   -b 115200  /dev/ttyACM0


The setLineCoding function is called. I was expecting the new baudrate (115200) available in cdc_linecoding->dwDTERate, but is not. I am debugging this using a LED in this way:

Code: Select all

void setLineCoding(cdc_linecoding_t* lcp)
{
    SD1_cfg.speed = (uint32_t)lcp->dwDTERate;
   
    // DEBUG
    if (SD1_cfg.speed == 115200) {
        led_on(LED_A);
    }
 }
 


setLineCoding function is called but the SD1_cfg.speed value is not the expected value (115200), because LED_A is not switched on.

I am doing something wrong?

Re: Baudrate configuration in USB CDC firmware

Posted: Wed Sep 19, 2018 4:06 pm
by Giovanni
Hi,

You don't need to call sdObjectInit(), it is done internally in the HAL.

I cannot see the whole code but you need to call sdStart() again in order to apply the new configuration (no need to stop, just start again).

Giovanni

Re: Baudrate configuration in USB CDC firmware

Posted: Wed Sep 19, 2018 4:15 pm
by aicastell
Thanks for your fast answer :)

This is the whole code of my setLineCoding function:

Code: Select all

void setLineCoding(cdc_linecoding_t* lcp)
{
    SD1_cfg.speed = (uint32_t)lcp->dwDTERate;
   
    // DEBUG
    if (SD1_cfg.speed == 115200) {
        led_on(LED_A);
    }

    if (SD1.state != SD_UNINIT)                                 
        return;                                                                 

    while(SD1.state != SD_READY)
        chThdSleepMilliseconds(1);                                               
    sdStop(&SD1);

    while(usbserial_base.sdp->state != SD_STOP)
        chThdSleepMilliseconds(1);
    sdStart(&SD1, &SD1_cfg);
}


I was debugging the speed field because this code is not working as expected.

Re: Baudrate configuration in USB CDC firmware

Posted: Wed Sep 19, 2018 5:29 pm
by Giovanni
Note that those messages are processed in ISR context and you are calling functions that are blocking.

Is the state checker enabled in chconf.h? it will stop any illegal call and help find errors.

Giovanni

Re: Baudrate configuration in USB CDC firmware

Posted: Thu Sep 20, 2018 10:35 am
by aicastell
First of all, thank you for your fast and valuable feedback.

What should be the most convenient way to manage that inside ISR context? Defining a callback for the fourth usbSetupTransfer parameter (currently set as NULL)? Or publishing an event inside ISR and managing it in the main loop?

CH_DBG_SYSTEM_STATE_CHECK was set to FALSE. After setting to TRUE, binary stops running in some unknown place, even when the setLineCoding functions is not called. That sound strange to me, because when that variable is set with FALSE the source code works as expected (reading from HID sensors and using CDC ACM serial port as expected). How can I take profit from setting that variable with TRUE value? Do I need a JTAG to debug the source code?

Re: Baudrate configuration in USB CDC firmware

Posted: Thu Sep 20, 2018 11:53 am
by Giovanni
Hi,

From a callback you could wakeup a thread that does the reprogramming then goes back to sleep.

About state checker, if it stops then there is a problem. After a stop, do a stack trace, it will show you exactly where the problem is.

Giovanni