nRF52840DK uart - 921600 not working

I’m using the nRF52840DK to communicate with a module over uart. My problem is that the module has a baud rate of 921600 and as far as my understanding the nRF52840 is using a baud rate of 941176 when set to 921600.  This leads to my commands (13 bytes) only works around 10-20% of the times, and the data received is not as expected (startbytes etc.).

I have tried using nrf_serial_flush as well but then nothing works. Also tried setting the baud rate manually without succeeding.

Any tips?

Parents Reply Children
  • Which prescaler and CC? The only register you can write to to modify the baudrate of the UART or UARTE peripheral is the BAUDRATE register, and you should only use values that are described in the register description in the product specification.

    To achieve 941176, write 0x0F000000 (251658240) to the BAUDRATE register as stated in the product specification (typically by setting the sdk_config.h macro for the driver accordingly. Note that if using the UART peripheral instead of UARTE, the value is different (0x0EBED000 = 247386112), which you can also see in the product specification.

  • I tried to reply to the message where you gave me this code: 

    #include <stdint.h>
    #include "boards.h"
    
    int main(void)
    {
        nrf_gpio_range_cfg_output(LED_1, LED_2); 
        nrf_gpio_pin_clear(LED_1);
        
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        {
        }
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        
        NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos |
                                GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos |
                                LED_2 << GPIOTE_CONFIG_PSEL_Pos | 
                                GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos;
                                
        NRF_TIMER1->PRESCALER = 0;
        NRF_TIMER1->CC[0] = 1;
        NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
        NRF_TIMER1->TASKS_START = 1;
        
        NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[0];
        NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[0];
        
        NRF_PPI->CHENSET = PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos;
        
        while (true)
        {
            
        }
    }

  • Aha, I did not notice that. You will not be able to get the exact same frequency. The point was that you can use this to measure the accuracy. The accuracy over time will be the same regardless of the frequency of the toggeling pin (so regardless of the prescaler and CC), as the clock source / oscillator is the same. So this was an answer to how you can measure the accuracy of the HFXO. In short, output a known frequency and use a frequency counter to check the deviation from the intended frequency and the measured frequency. Assuming a perfect frequency counter, this will tell you the accuracy of your HFXO.

  • I see, but there is not a way to actually measure the exact 941176? 

  • Output it via GPIOTE using a timer like I showed? You can't (the math don't add up). That is was not the point with that code.

Related