This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430 UART Baud Calc Alternative

Other Parts Discussed in Thread: MSP430WARE

The MSP430Ware UART Driver uses UARTBAUDRATE_calculateBaudDividers() to calculate the divisor values. That function uses a lot of floating point operations. It there a lighter implementation that uses fixed point? I suppose I could fix the baud rate and use the calculated divisor values as hard-coded values; No runtime change of baud rate.

  • Hello Norman,

    Considering UART has been running on 8-bit micros for decades, it does seem strange that the function includes floats.  I suppose for inner MCU communication you can achieve very high data rates using floats.  You could create another baud rate calculator taken from any 8051 based MCU, matching the timer intervals to the baud rates.  That would give you your runtime adjustability.

    Thanks,

  • I am a beginner at MSP430 and 8051 is very far in my past. I don't know if the MSP430 and 8051 UART controllers are similiar enough to share code or utilities. For a given UART controller clock frequency and desired baud rate, the UARTBAUDRATE_calculateBaudDividers() function calculates the values for 3 register in the UART controller. It does this using a brute force iterative method to find a register setting with the least amount error of between actual and desired. All in double precision math. The computional time hit is probably okay as setting the baud rate is usually done once at boot and seldom afterwards. The double precision library cost in code space and stack space is more worrisome.

  • The UART protocol is the same no matter what device it is running on, but you already know that.  The MSP430 is far in my future, so the only thing I can suggest would be to look at the code and maybe consider putting the values in a table aligned to 16 bits.  There are also software versions of the UART posted in this forum that some people have found useful.  Once again, you would have to look at the code and compare memory usage between the two methods.

    A MSP430 with a larger flash may also ease your worries.

    Thanks,

  • Norman Wong said:

    The MSP430Ware UART Driver uses UARTBAUDRATE_calculateBaudDividers() to calculate the divisor values. That function uses a lot of floating point operations. It there a lighter implementation that uses fixed point? I suppose I could fix the baud rate and use the calculated divisor values as hard-coded values; No runtime change of baud rate.

    If you are working with few standard baudrate values, it can be inserted in code directly, without need for any calculation. Here is my baudrate calculator http://forum.43oh.com/topic/2640-uart-configurator/ so you can find needed setup values.

    If you are working on something else, where all baudrate values (123456, 654321...) must be supported on the fly (for example, like my USB-UART bridge http://forum.43oh.com/topic/3350-msp430f550x-based-usb-uart-bridge/) , than this is not possible to do without divide function, and I use my own integer function.

  • Norman Wong said:

    The MSP430Ware UART Driver uses UARTBAUDRATE_calculateBaudDividers() to calculate the divisor values. That function uses a lot of floating point operations. It there a lighter implementation that uses fixed point? I suppose I could fix the baud rate and use the calculated divisor values as hard-coded values; No runtime change of baud rate.

    If you are working with few standard baudrate values, it can be inserted in code directly, without need for any calculation. Here is my baudrate calculator http://forum.43oh.com/topic/2640-uart-configurator/ so you can find needed setup values.

    If you are working on something else, where all baudrate values (123456, 654321...) must be supported on the fly (for example, like my USB-UART bridge http://forum.43oh.com/topic/3350-msp430f550x-based-usb-uart-bridge/) , than this is not possible to do without divide function, and I use my own integer function.

  • Norman Wong said:
    The MSP430Ware UART Driver uses UARTBAUDRATE_calculateBaudDividers() to calculate the divisor values. That function uses a lot of floating point operations. It there a lighter implementation that uses fixed point? I suppose I could fix the baud rate and use the calculated divisor values as hard-coded values; No runtime change of baud rate.

    Why you need to calculate baud runtime? Wouldn't array of pre-calculated values be sufficient? 

    Regards,
    Maciej 

  • zrno soli said:

    If you are working with few standard baudrate values, it can be inserted in code directly, without need for any calculation. Here is my baudrate calculator http://forum.43oh.com/topic/2640-uart-configurator/ so you can find needed setup values.


    If you are working on something else, where all baudrate values (123456, 654321...) must be supported on the fly (for example, like my USB-UART bridge http://forum.43oh.com/topic/3350-msp430f550x-based-usb-uart-bridge/) , than this is not possible to do without divide function, and I use my own integer function.

    Your baudrate calculator looks great. I was thinking about porting the MSP430 baud rate code to a PC console app. Not quite as nice as a GUI like yours.

    Other posts on the 43oh forum would suggest that each series of the MSP430 is slightly different in calculating baud rate divisors. Perhaps the MSP430Ware calculator is complex because it is supposed to support every series. I am using a F5 series.

    I do want to leave myself the ability to change the baud rate at runtime. I will probably have to code my own integer math version or just settle to a fixed baud rate with hard-coded values.

    Thanks for the info. Gives me some insight into solving the problem.

  • MaciejKucia said:

    Why you need to calculate baud runtime? Wouldn't array of pre-calculated values be sufficient? 

    Regards,
    Maciej 

    Well...when it gets down to it, all I need are BR0, BR1 and MCTL values for a given clock and baud. If clock and baud are fixed, a lookup table will suffice. The trouble is that the clock may not be fixed. Different boards and config of upstream dividers might cause clock changes. Calculation at runtime is an easy way to handle the clock or baud changes. At this late stage in development, I am considering a lookup table or just settling for fixed baud rate.

    The pre-calculation part is the problematic part. The complexity of the MSP430Ware baud rate code is daunting. Matching the code with hand calculation is not workable. I guess I can use the MSP430 itself to generate a table. Or use a PC utility like the one posted by zrno soli.

  • You can also take a look how Grace manages this stuff. There is a function too I believe. 

    Regards,
    Maciej 

  • Norman Wong said:

    The MSP430Ware UART Driver uses UARTBAUDRATE_calculateBaudDividers() to calculate the divisor values. That function uses a lot of floating point operations. It there a lighter implementation that uses fixed point? I suppose I could fix the baud rate and use the calculated divisor values as hard-coded values; No runtime change of baud rate.

    Hi Norman,

    You should try using the UART_initAdvance() function instead of UART_init() - the initAdvance version runs MUCH faster. UART_init() calculates the baud rate at run-time, whereas UART_initAdvance() has you enter pre-calculated UART settings (instead of having them calculate at runtime) - we even have the UART settings for different clock frequencies and baud rates listed in a handy table in most of the User's Guides.

    I think the UART_init() function that uses calculateBaudDividers() to calculate it at runtime was mostly included for consistency with the Tiva M4 driverlib functions - it is easy to code, but it is a much less useful function on an MSP430 which has no floating point unit and runs at a lower clock freq, making it impractical. I've submitted feedback to our MSP430 driverlib team that we should probably have our UART example codes use UART_initAdvance instead of UART_init for this reason. I think these examples are scheduled to be updated in a future release.

    Regards,

    Katie

  • Katie Enderle said:
    UART_init() calculates the baud rate at run-time

    If you read back through, this was one of his requirements.

    Here's my thought on this... since this is a F5x series device (which have a lot more memory compared to the 2x value devices), is it really a problem to have some code that uses float?

    Consider that it is probably only called once during setup (where hopefully the extra time to perform calculations aren't a bother).

    It is complex primarily due to the need to calculate the modulation parameters.

    I'm not saying that it couldn't be done more efficiently, but for one-time setup on a device with relatively plenty of memory, and it already exists, I'd be tempted to just use it.

  • Hi Brian,

    I see. If you might need to change the baudrate at runtime, you can implement the table from the user's guide of baudrate settings for different clock frequencies as a lookup table. If you've set up your clocks using driverlib as well, you could always try using for example UCS_getSMCLK to determine your current clock source frequency, then use that to know where in the lookup table to find your settings.

    Brian Boorman said:

    Here's my thought on this... since this is a F5x series device (which have a lot more memory compared to the 2x value devices), is it really a problem to have some code that uses float?

    Consider that it is probably only called once during setup (where hopefully the extra time to perform calculations aren't a bother).

    It is complex primarily due to the need to calculate the modulation parameters.

    I'm not saying that it couldn't be done more efficiently, but for one-time setup on a device with relatively plenty of memory, and it already exists, I'd be tempted to just use it.

    You have a point, but this will really depend on Norman's application, its responsiveness and power requirements, what clock frequency he runs at, and how often he might be re-initializing the UART settings. Here are the pros and cons:

    If you are only running at 1MHz, this particular function takes a VERY long time to run (like a minute in my experience) - that is eating a lot of power by having to be in active mode that whole time, and it's keeping the device occupied for a long time before he can actually start his UART communications. If he frequently needs to reconfigure the UART, I think the lookup table and UART_initAdvance will probably be a better idea. If it is something that runs once at the beginning of your code, or if you are running at a high speed like 20-25MHz, it's probably not as much of a concern like you said.

    Regards,

    Katie

     

  • MaciejKucia said:

    You can also take a look how Grace manages this stuff. There is a function too I believe. 

    Regards,
    Maciej 

    Thanks for the link. Too new to the MSP430. Didn't know about Grace. Always good to have another option for precalc.

  • Brian Boorman said:

    If you read back through, this was one of his requirements.

    Here's my thought on this... since this is a F5x series device (which have a lot more memory compared to the 2x value devices), is it really a problem to have some code that uses float?

    Consider that it is probably only called once during setup (where hopefully the extra time to perform calculations aren't a bother).

    It is complex primarily due to the need to calculate the modulation parameters.

    I'm not saying that it couldn't be done more efficiently, but for one-time setup on a device with relatively plenty of memory, and it already exists, I'd be tempted to just use it.

    I believe the same MSP430Ware library is used on the 2x series. And you are right, at this time on my F5x device, there is plenty of memory left but that can always change. Add some extra functionality or trade memory for speed optimizations and memory starts getting scarce. My project is getting too close to release and I likely will just have to "just use it".

  • Katie Enderle said:

    Hi Norman,

    You should try using the UART_initAdvance() function instead of UART_init() - the initAdvance version runs MUCH faster. UART_init() calculates the baud rate at run-time, whereas UART_initAdvance() has you enter pre-calculated UART settings (instead of having them calculate at runtime) - we even have the UART settings for different clock frequencies and baud rates listed in a handy table in most of the User's Guides.

    I think the UART_init() function that uses calculateBaudDividers() to calculate it at runtime was mostly included for consistency with the Tiva M4 driverlib functions - it is easy to code, but it is a much less useful function on an MSP430 which has no floating point unit and runs at a lower clock freq, making it impractical. I've submitted feedback to our MSP430 driverlib team that we should probably have our UART example codes use UART_initAdvance instead of UART_init for this reason. I think these examples are scheduled to be updated in a future release.

    Regards,

    Katie

    Thanks for the info. That explains a lot.  I took a quick look at UART_initAdvance(). It looks to be API for taking precalc values and putting them in the right registers. Not a lot of examples of it's usage in the current release of MSP430Ware. Just a couple examples that use some magic numbers. Hopefully examples will demonstrate a table lookup with data from User Guides.

    At this time, my memory and time requirements are not that critical. I'll probably just live with the floating point right now. However, 1 minute at 1Mhz implies 3 seconds at 20Mhz. Speeding up boot by 3 seconds is definitely a nice to have.

  • Norman Wong said:
    Well...when it gets down to it, all I need are BR0, BR1 and MCTL values for a given clock and baud. If clock and baud are fixed, a lookup table will suffice. The trouble is that the clock may not be fixed.

    After all, it's not too complicated, on USCI even less than on USART (1x family).

    First step: divide the clock by the baudrate. This gives you the 16 bit value for UCBR0/1. Integer division!
    Now multiply this with the baudrate and subtract it from the clock. It gives you the decimals (* baudrate).
    Next step is to calculate (still integer, with clever shiftinmg) how many 1/16 of the baudrate the remainder is. This is the value for MCTL

    On the USART, it wa similar, but here a recursive loop was used to generate a bit pattern by continuously calculating the surplus or missing time when BR or BR+1 was used. Still not too complex. I once implemented it for the 1611 and reused it on many projects with different baudrates and clock speeds without problems.
    For the USCI I wrote the following code (excerpt of the full one which auto-selects oversamplign mode if the clock is much higher than the baudrate, and allows using of ACLK and SMCLK automatically for best fit):

      long temp=(((long)CLOCK<<4)/baudrate);
      mod = ((temp&0xF)+1)&0xE;                                                // UCBRSx (bit 1-3)
      divider = temp >> 4;

    However, I haven't used it on more than one project so far. And on this project with the given clock and baudrate, even a totally wrong mdoulation would still have been within the RS232 specs. So use it at your own risk.

    Norman Wong said:
    The complexity of the MSP430Ware baud rate code is daunting.


    Well, I had to look at my own code for a few seconds to extract these three lines. The whole UART init code initializes up to 4 UARTs (5438), allocates ringbuffers for RX and TX, sets up timeouts for GETCHsettign up the messaging system for multitasking events BYTE_READY and BUFFER_EMPTY and of course calculates the optimum (to be tested) UART configuration for a given baudrate for variable SMCLK or ACLK speeds.
    After removing all this, only the above three lines are left for baudrate calculation in non-oversampling mode.

  • @Jens-Michael

    I am slowing sifting through the MSP430Ware baud rate code and I am beginning to see what you mean. The huge amount of best fit code could be replaced with a few lines if the f and s mod values are ignored. The caveat is that timing error will not be minimised.

    Not quite sure yet but I think there is oversight in the MSP430Ware funciton. The code only uses the BITCLK 8x8 pattern. There is no use of BITCLK16 16x16 patterns defined in the F5x TRM. I am somewhat amazed that MSP430Ware would contain floating point code. StellarsWare and StarterWare seem be simliar in quality. I getting a bit of Ware fatigue.

**Attention** This is a public forum