Strictly necessary cookies are on by default and cannot be turned off. Functional, Performance and Tracking/targeting/sharing cookies can be turned on below based on your preferences (this banner will remain available for you to accept cookies). You may change your cookie settings by deleting cookies from your browser. Then this banner will appear again. You can learn more details about cookies HERE.
Strictly necessary (always on)
Functional, Performance and Tracking/targeting/sharing (default off)
P_UART_HIGH_BAUDRATE_DIV(0x44); //set the registers directly
I tried using the functions I could find in puart.h (tw_puart_init() and puart_calculateBaudrate()), as well as using the two macros above to set the divisor registers directly. While this worked for almost any baudrate, I could not get 4800 to work. (P_UART would output at 26607 baud when set to 4800). Unfortunately, There is no obvious logic as to how "dhbr" and "dlbr" need to be calculated, or how they might be used by the internal hardware to actually genrate the output. It is obviously not just a 16 bit "divisor" for the clock that's split into two 8 bit registers, as I'm used to from other systems. I tested at least 40 different baudrates at known intervals, to see if I could find some patterns in the binary representation of the two registers, to no avail.
If someone from broadcom could give me some pointers in which direction to continue, or even better: provide an actual solution, that would be the best. getting some "real" documentation of the hardware would be great.
I have three more ideas before I start working on a software uart, but I can't figure out how to try them, as the documentation is lacking concerning these things:
a) Slow the entire CPU down from 24 to 12Mhz, and hope that 4800 baud will then work with the divisor settings of 9600 at 24Mhz.
as I will almost definitely need some lower power modes while the radio can be completely off, this might be interesting anyway - It would be great if I could get more info on this (eg what the lowest speed is at which Bluetooth will still work)
b) use a different clock for P_UART - I already figured out how to use the auxiliary clock for PWM, and how to configure that to use either the 24MHz or 1MHz as the reference to generate pretty much any frequency (pwm_tones app is great!). I could not find any (documented) methods of using one of the ACLK's for P_UART.
c) somehow manage to increase the sampling (constant P_UART_SAMPLE_CLOCK) from 16 to 32, which should get me down to 4800 baud with the settings for 9600 baud.
If anyone has some ideas for me, I'd be very happy to hear them!
OK, Some info for others looking for similar answers:
I have now figured out that this is a limitation of the way the UART timer is used:
the divisor has an integer and a fractional part:
P_UART_HIGH_BAUDRATE_DIV() actually sets the integer part
P_UART_LOW_BAUDRATE_DIV() the fractional part (and not the low and high byte of a 16bit divisor, as the names imply)
P_UART_HIGH_BAUDRATE_DIV() actually sets the pre-load value of the timer - in other words: 256 - integer_divisor. Even though it's a 32 bit register, only 8 bits are used, so when it is 0, this means that the maximum divisor is 256, which corresponds to a baudrate of 5859 baud. (24000000/(16*256)=5859.375)
4800 baud would mean a divisor of 312.5
Too bad I can't slow down the entire CPU (is this not even possible when Bluetooth is off?)
Nonetheless, I'm still keen on an answer about the other two options I wrote about:
b) using a different clock for P_UART_CLK (12MHz would work perfectly, heck - I'd even take 20MHz, resulting in 4880 baud)
c) changing P_UART_SAMPLE_CLOCK from 16 to 32 somehow?
By the way: will the newly announced BCM20739 and BCM20719 have the same limitations?