Baudrate configuration in USB CDC firmware

Discussions and support about ChibiOS/HAL, the MCU Hardware Abstraction Layer.
aicastell
Posts: 12
Joined: Tue Sep 04, 2018 11:03 am
Has thanked: 6 times

Baudrate configuration in USB CDC firmware

Postby aicastell » Wed Sep 19, 2018 3:52 pm

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?

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Baudrate configuration in USB CDC firmware

Postby Giovanni » Wed Sep 19, 2018 4:06 pm

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

aicastell
Posts: 12
Joined: Tue Sep 04, 2018 11:03 am
Has thanked: 6 times

Re: Baudrate configuration in USB CDC firmware

Postby aicastell » Wed Sep 19, 2018 4:15 pm

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.

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Baudrate configuration in USB CDC firmware

Postby Giovanni » Wed Sep 19, 2018 5:29 pm

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

aicastell
Posts: 12
Joined: Tue Sep 04, 2018 11:03 am
Has thanked: 6 times

Re: Baudrate configuration in USB CDC firmware

Postby aicastell » Thu Sep 20, 2018 10:35 am

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?

User avatar
Giovanni
Site Admin
Posts: 14457
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Baudrate configuration in USB CDC firmware

Postby Giovanni » Thu Sep 20, 2018 11:53 am

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


Return to “ChibiOS/HAL”

Who is online

Users browsing this forum: No registered users and 27 guests