2 Replies Latest reply on Dec 18, 2015 11:34 AM by op_2169936

    4800 P_UART Baudrate


      I finally got around to spending a few days working with the BCM920737TAG3 board, and am starting to get the hang of it. I even managed to get 2.2.2 running.


      However, one of my main requirements remains a baudrate of 4800.


      I seem to have two options:

      1) get it to work natively, even if this is not officially supported. (4800 UART Baudrate)

      2) write a software uart, that would use one of the PWM outputs or the new bt_clock_based_timer for bitbanging TX and a timer combined with a pin interrupt for RX


      as you can imagine, I'd prefer 1)


      I spent many hours trying to get 1) to work, but have not yet managed.

          tw_puart_init(GPIO_PIN_UART_RX, GPIO_PIN_UART_TX,4800);

          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!


      Thanks already!

        • 1. Re: 4800 P_UART Baudrate

          It's not possible to slow down the internal Cortex M processor.  That has been discussed elsewhere on the forum.


          A baud rate below 9600 has not been tested, so that is unsupported.

          • 2. Re: 4800 P_UART Baudrate

            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?