This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

BLE_NUS change UART baudrate at runtime

Can you please help i use ble _ nus and after few message i need to change uart baudrate. I cloes uart then init uart with new baudrate parameter but everytime MCU goes to in error handler function. Where will be best to put  new uart initialization. I know that after i send via bluetooth to nrf52840 0x06 0x39 0x36 0x30 0x30 and nrf52840 forward this message on tx  in next 200 ms device connected to nrf52840s uart will respond on new baudrate which i have send that it changes.

Parents
  • So what debugging have you done to determine when / where it gets sent to the error handler ?

    As always, I would strongly recommend that you start simple - so make sure that you can get this runtime change working without BLE  first.

    Once you have that working, then move on to integrating it with BLE ...

    I cloes uart then init uart with new baudrate

    So one thing that will be important is to ensure that nothing tries to use any UART-related functions after you close it, but before you're successfully initialised it with the new settings ...

  • in nus_data_handler function i have add condition 

    if (p_evt->params.rx_data.p_data[0] == 0x06 && p_evt->params.rx_data.p_data[1] == 0x39 && p_evt->params.rx_data.p_data[2] == 0x36){
    
    //app_uart_close();
    
    bsp_board_led_invert(3);
    NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud9600 << UART_BAUDRATE_BAUDRATE_Pos);
    }

    if i comment "NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud9600 << UART_BAUDRATE_BAUDRATE_Pos);"

    nrf52840 did not go to  NRF_BREAKPOINT_COND; in app_error_weak.c.

    if i dont put all if  condition block nrf52840  go to  NRF_BREAKPOINT_COND; in app_error_weak.c.

  • its not on debugging. i dont get data on my smartphone and nrf52840 get disconnected from smartphone. If i dont send message to change uart everything works well and messages from device goes via UART on nrf and then over BLE to my smartphone and vice versa. 

  • i dont get data on my smartphone

    That could be for any number of reasons - so you need to find out what, exactly, is causing it!

    For that, you will need to debug.

    Again, the easiest approach is to get the baud rate change working and debugged on its own - without the added complications of BLE.

    Once you have the baud rate change working and debugged on its own, then - and only then - move on to adding the BLE stuff.

  •     while (true)
        {
            uint8_t cr;
            while (app_uart_get(&cr) != NRF_SUCCESS);
            while (app_uart_put(cr) != NRF_SUCCESS);
    
    
          
    
            if (cr == 'q' || cr == 'Q')
            {
                printf(" \r\nBAUDRATE 1200\r\n");
                bsp_board_led_invert(0);
                NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud1200 << UART_BAUDRATE_BAUDRATE_Pos);
                
    
              /*  while (true)
                {
                    // Do nothing.
                }*/
            }
        }

    Default baud rate on which app start is 9600 and later i change it to 1200. When i added  NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud1200 << UART_BAUDRATE_BAUDRATE_Pos);  as you say ithat try changing baudrate n uart example without BLE. I can change baudrate  and communicate with device normally on new baud rate which are stored now in NRF_UART0 register.  but when added this feature in BLE UART that doesnt work.

  • OK - so you need to start debugging to fins what it is with the BLE that causes the crash!

    Remember that BLE events come in asynchronously - so you need to be particularly careful that no BLE event tries to use the UART while it is in the middle of being reconfigured ...

  • how to debug hen you say and i have already see that "if you stop the CPU with a breakpoint, that will crash the softdevice"

Reply Children
  • Did I not also mention Monition Mode Debug ... ?

    And there is still, of course, printf-style debugging

    Or, if you're just catching the case where your UART code would crash anyhow, it's not such a problem ...

  • I find that when i send  message with change uart command ( array of letters) 'q' 'r' 't' as you can see in code section and when this condition happen nrf sends over uart 'q' 'r' 't' on new baudrate but i need to send this on  previously baudrate and after  this message is sent it need to receive message on new baudrate settings.

    static void nus_data_handler(ble_nus_evt_t * p_evt)
    {
    
        if (p_evt->type == BLE_NUS_EVT_RX_DATA)
        {
            uint32_t err_code;
    
            NRF_LOG_DEBUG("Received data from BLE NUS. Writing data on UART.");
            NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
    
            for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
            {
                do
                {
                    err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                    if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                    {
                        NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                        APP_ERROR_CHECK(err_code);
                    }
                } while (err_code == NRF_ERROR_BUSY);
            }
            if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
            {
                while (app_uart_put('\n') == NRF_ERROR_BUSY);
            }
    
            if (p_evt->params.rx_data.p_data[0] == 'q' && p_evt->params.rx_data.p_data[1] == 'r' && p_evt->params.rx_data.p_data[2] == 't')
            {
              
              bsp_board_led_invert(3);
    
              NRF_UART0->BAUDRATE = (UART_BAUDRATE_BAUDRATE_Baud9600 << UART_BAUDRATE_BAUDRATE_Pos);
            
        
            }
        }
    }

  • so have you now fixed the crashing?

    Is this now a new question?

  • chrashing is stil happening because now nrf change his baudrate  before it should.

    it should change baudrate after 'q' 'r' 't' send over his tx pin not before. 

    I send over smartphones BLE 'q' 'r' 't' (command to change baudrate) to nrf and nrf needs to send over his uart 'q' 'r' 't' and then change his baudrate to receive message from other device which is connected on his uart on new baudrate.

    Now is happening that when i send over smartphones BLE 'q' 'r' 't'  to nrf. Nrf change his baudrate and sends on new baudrate 'q' 'r' 't'. 

    i need that works on this order:

    1. smartphone via ble send 'q' 'r' 't'

    2. nrf receive from smartphone 'q' 'r' 't' and send over uart on his default baudrate 'q' 'r' t'

    3. after nrf is send 'q' 'r' 't' it change baudrate on new value

    4. nrf receive message from uart on new baudrate

    5. send this message to smartphone via BLE

  • That would be a lot clearer with a diagram - like the Message Sequence Charts Nordic use for describing this kind of stuff; eg,

    https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s130.api.v2.0.0/group___b_l_e___g_a_p___a_d_v___m_s_c.html

    I'm losing track of what has & has not been proved here.

    1. Without BLE, Have you demonstrated that you can change the baud rate on-the-fly, and the nRF will correctly transmit & receive at the new baud rate?
       
    2. After successfully completing (1), Having then got the same with BLE ?
Related