nRF52832 Product Specification V1.4, page 344 lists predefined baud rates only.
Is it possible to use other values for custom baud rate, and if so, what is the relationship between the Value and the actual generated baud rate?
nRF52832 Product Specification V1.4, page 344 lists predefined baud rates only.
Is it possible to use other values for custom baud rate, and if so, what is the relationship between the Value and the actual generated baud rate?
Such a good question, and highlights the fun the hardware design engineer must have been having that day .. this is what I use, inclusive of the rounding
// Baud rate calculation on nRF51 and nRF52832 // =========================================== // // Calculate BAUDRATE value settings for the black-magic 20-bit baud rate generator uint32_t CalculatedRegisterValue; uint64_t SystemClock = 16000000ULL; // Typically 16MHz uint64_t MagicScaler = 32; // Preserves bits on divisions, shift 32 bits // Baudrate generator for the UART is the top 20 bits of a 32-bit field; add in rounding 0.5 ls bit CalculatedRegisterValue = (uint32_t)((((uint64_t)RequiredBaudRate << MagicScaler) / SystemClock) + 0x800) & 0xFFFFF000;
So does it work? Well it doesn't exactly match the datasheet quoted values:
typedef struct { uint32_t QuotedRegisterValue; uint32_t RequiredBaudRate; uint32_t QuotedActualBaudRate; } BaudCheck_t; // Quoted values from nRF52832 v1.4 datasheet static BaudCheck_t BaudCheck[] = { {0x0004F000, 1200, 1205}, {0x0009D000, 2400, 2396}, {0x0013B000, 4800, 4808}, {0x00275000, 9600, 9598}, {0x003AF000, 14400, 14401}, {0x004EA000, 19200, 19208}, {0x0075C000, 28800, 28777}, {0x009D0000, 38400, 38369}, {0x00EB0000, 57600, 57554}, {0x013A9000, 76800, 76923}, {0x01D60000, 115200, 115108}, {0x03B00000, 230400, 231884}, {0x04000000, 250000, 250000}, {0x07400000, 460800, 457143}, {0x0F000000, 921600, 941176}, {0x10000000, 1000000, 1000000}}; #define NUM_BAUD_TESTS (sizeof(BaudCheck)/sizeof(BaudCheck[0])) static void BaudRateDivisorTest(void) { // Baud rate calculation on nRF51 and nRF52832 // =========================================== // // Calculate BAUDRATE value settings for the black-magic 20-bit baud rate generator uint32_t OkCountRegister = 0, FailCountRegister = 0, CalculatedRegisterValue; uint32_t OkCountActualBaud = 0, FailCountActualBaud = 0; uint32_t BaudIndex, ActualBaudRate; uint64_t SystemClock = 16000000ULL; // Typically 16MHz uint64_t MagicScaler = 32; // Preserves bits on divisions, shift 32 bits for (BaudIndex = 0; BaudIndex < NUM_BAUD_TESTS; BaudIndex++) { // Baudrate generator for the UART is the top 20 bits of a 32-bit field; add in rounding 0.5 ls bit CalculatedRegisterValue = (uint32_t)((((uint64_t)BaudCheck[BaudIndex].RequiredBaudRate << MagicScaler) / SystemClock) + 0x800) & 0xFFFFF000; if ( BaudCheck[BaudIndex].QuotedRegisterValue == CalculatedRegisterValue) { OkCountRegister++; } else { FailCountRegister++; } ActualBaudRate = (uint32_t)(((uint64_t)CalculatedRegisterValue * SystemClock) >> MagicScaler); if ( BaudCheck[BaudIndex].QuotedActualBaudRate == ActualBaudRate) { OkCountActualBaud++; } else { FailCountActualBaud++; } } while(1) ; }
The values either exactly match the data sheet or are close; that may be a code issue or a datasheet issue, who knows but I think the h/w guy was teasing us..
Thanks for the info. Very helpful!
Thanks for the info. Very helpful!