Custom Uart baud rate 117600

Hello,

We are using UART channel to communicate with the other MCU, 

It has a specific clock to save power but its only option is 117600 baud rate which corresponds to 2% deviation of 115200.

Is there any way to configure 117600 and make it work?

Thanks

Parents
  • Hi Joon,

    UART baud rate is configured in the BAUDRATE register. You can try to reach 117600 baud rate by tweaking the value slightly up from 0x01D60000, the rated value for 115200 baud rate.

    Please note that this will be unofficial and not tested, so we also cannot guarantee you that it would work. If you pursue this option, please perform thorough testing.

    Hieu

  • Hi Hieu,

    Thanks for the information, I am going to have to try that way,

    For the register value corresponding to 115200 baud rate, your link says it is 0x01D60000 but my sdk s140 shows 0x01D7E000UL in nrf52840_bitfields.h.

    I found a post related to this question, it is for nrf52832, here https://devzone.nordicsemi.com/f/nordic-q-a/43280/technical-question-regarding-uart-baud-rate-generator-baudrate-register-offset-0x524 

    Do you think this also work for nrf52840 ?

    Thanks,

    Joon

  • Hi Hieu,

    That's great suggestion, Thanks for that.

    Actually I believe in source code, not a product specification, no worries.

    I tested 111111 baud rate,

    The register value is come out 0x01C72000 based on the post, so added NRF_UART0->BAUDRATE = 0x01C72000 after uart_init();

    It worked fine with the 111111 baud device while 115200 baud failed to communicate. I didn't measure the precise timings with a scope but that's enough.

    Thanks for the support and have great vacation.

    Joon

  • Just in case you didn't use rounding from my old post response you referenced, this works with rounding included on the nRF52840 (you may already be using this)

    // Baudrate generator for the UART is the top 20 bits of a 32-bit field; add in rounding 0.5 ls bit
     uint32_t CalculatedRegisterValue;
     uint64_t SystemClock = 16000000ULL;    // Typically 16MHz
     uint64_t MagicScaler = 32; // Preserves bits on divisions, shift 32 bits
     CalculatedRegisterValue = (uint32_t)((((((uint64_t)RequiredBaudRate << MagicScaler)) + (SystemClock>>1)) / SystemClock) + 0x800) & 0xFFFFF000;

    As an aside, should you need a really fast serial port transmit, the uart Tx works up to 8MHz although only 1MHz on uart receive. This is useful if using a high-speed external flash memory dump via the uart

  • Hi hmolesworth,

    Thank you for the extra tips. Do you mind sharing some brief background behind how you came up with the formula? It might be obvious to you, but perhaps readers with less IC/hardware knowledge like me can't understand it fully.

  • The background is actually similar to your case; a serial sensor was using 921600 baud but was unreliable when connected to a nRF52832 so I checked the bit rate with an accurate meter and found that it was indeed incorrect - by quite a lot. Changing the baud register indicated that altering some lower-order bits had no effect, although not easy to see on a 'scope or even an accurate meter at 921600 baud. The trick is to select a very low baud rate (less than 1200, actual value unimportant) and capture a single character transmission so that the lower order register bits make a discernable difference on a 'scope when the bits are changed. This allows finding all the bits in the baud register which have no effect, hence the baud register only has 20 useful bits. Mapping the setting at a low baud rate and knowing the peripheral uses the 16MHz clock allowed the determination of the formula. Some uarts use as few as 3 bits to determine start bit validity, others use 8 or 16 bits. That determines the Rx clock prescaler as each Rx bit has 3, 8 or 16 clock ticks respectively (not applicable to the Tx).

Reply Children
No Data
Related