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 Joon,

    Good finding. I noticed that one value is for the UART peripheral, and one is for the UARTE peripheral. You will find both value in the same MDK header file, and in the Product Specification.

    I am not certain if some difference between the two peripherals is to account for that difference and have started an internal query about it. I will update you when I receive an answer.

    However, please note that it is currently the summer vacation period, and many of our engineers are away. Therefore, response can take a long time. My apology for the inconvenience.

    Regards,

    Hieu

  • Hi Joon,

    It seems like the numbers in our Product Specification are calculated a long time ago and it might take a while to track down their history. However, I will be out of office from today and for a few weeks. As such, I have to set that aside and refocus back to our initial goal.

    I reviewed the calculation in the ticket you link, however, I don't see the basis of some calculation steps, such as the + 0x800 or the & 0xFFFFF000 parts(*), so I cannot comment on its validity. However, the values calculated from their equations seem really close to the value in our Product Specification. Thus, I think you could use their formula as a basis to get a first value. From then, you can tweak the value and monitor the communication on an oscilloscope until the baud rate is exactly as you desired.

    What do you think about that suggestion?

    As mentioned, I will be out of office, but please feel free to follow-up, and one of our engineers will continue to support you in my stead.

    Regards,

    Hieu

    Note*: So I can guess the + 0x800 is for rounding, but then why & 0xFFFFF000 in the first place?

  • 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

Reply
  • 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

Children
  • 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).

Related