Arduino Due ARM Cortex-M3

ARM Cortex Processors – UART Programming Problem At Baud Rates Higher Than 115200

Arduino Due - ARM Cortex M3 processor with UART connectionTo say it upfront, I cannot confirm with 100% certainty that all ARM Cortex microcontrollers are affected by the UART programming problem as described in the following, but there are indications that make my assumption very probable. The outcome depends primarily on thorough testing of serial communication applications, but there is evidence to the contrary in popular systems like the Arduino Due and the Raspberry Pi.

I have encountered baud rate problems using embedded systems with the NXP LPC1754 and LPC1768 as well as the Arduino Due with its Atmel SAM3X8E ARM Cortex-M3 CPU. And yes, they are all Cortex M3 processors. I am not a hardware specialist, but I believe the UART programming is somewhat universal between all ARM processor types. In addition, I have seen forum inquiries pointing to similar problems with the Raspberry Pi 2  which uses a 900 Mhz Quad Core ARM Cortex-A7 CPU.

To describe the actual problem:

The standard code used to program UARTs on ARM microcontrollers contains a bug that prevents the processor from properly supporting any baud rates above 115,200 bits/sec.

And the cause of the problem is very obvious (once you know what it is). So let’s have a look at the standard code. The following is a simplified example, but the principle is the same with all examples I found.

LPC1768 Cortex M3 - UART Initialization Code
Standard LPC1754/68 Cortex M3 – UART Initialization Code

I have highlighted the problem section in red. FPCLK represents the system core clock, and it is being divided by 16 and is then divided by the desired baud rate. In all consequence, due to using an integer variable (uint16_t), we are dealing here with rounding errors that have greater impact at higher baud rates.

There is a specific and well documented algorithm to determine the data for the DLL and DLM registers in reference to the desired baud rate, and any hardware specialist will be able to figure out the right data and hard-code it into the program. However, that will limit your program to only a single baud rate.

So what to do? Again, I am not a hardware specialist, so I did some online research and after some hard work finally found the solution at:
https://www.lpcware.com/content/forum/lpc1768-uart-using-fdr-at-higher-baud-rates

I took the code as described there and modified it out of mere readability reasons. In a next step, I implemented the code into my embedded systems (LPC1754 and LPC1768) and tested the result by connecting the output (RS232) to a PC running the RealTerm software. Similar tests starting at 115,200 had failed before using the original code version, but the new code proved to be working without problems.

Unfortunately, the good people who developed the software for the Arduino Due or the Raspberry Pi did either not test thoroughly enough or knowingly deemed this a minor shortcoming. In case of the Raspberry Pi, I suspect that the supported baud rate is limited to under 115,200 baud, but I haven’t invested enough efforts to prove my point to the last detail. I just know there are problems.

In case of the Arduino Due, you can see the effect by simply writing code that initializes the Serial port’s baud rate to 230,400 using the Serial.begin command. Then, in the loop program, print a string to be monitored with the Serial Monitor that is set to 230,400 as well. All that you will see is garbage. The Serial Monitor is a PC software (with PC being the hardware running either Windows, Linux, or OS-X), where the operating system handles baud rates precisely to standard, while the Arduino Due fails to provide the exact baud rate.

If you have any comments, insights, or questions, please feel free to contact me through this website.