To 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.
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 this post: 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.
Serial Port Complete: COM Ports, USB Virtual COM Ports, and Ports for Embedded Systems
PC COM ports, USB virtual COM ports, and ports in embedded systems are all addressed in this updated guide to programming, interfacing, and using serial ports.
Topics include using .NET’s SerialPort class for COM-port communications on PCs; upgrading existing RS-232 designs to USB or wireless networks; and creating serial networks of embedded systems and PCs.
Example circuits and code provide a quick start to projects. Installation and maintenance staff will also find tips for ensuring reliable operation and problem tracking.
This book details the use of the ARM Cortex-M family of processors and the Arduino Uno in practical CAN bus based projects. Inside, it gives a detailed introduction to the architecture of the Cortex-M family whilst providing examples of popular hardware and software development kits. Using these kits helps to simplify the embedded design cycle [...]
As I had mentioned in my post, Arduino DUE CORE Board With Dual CAN Bus Interface And Extended Power Supply Range, our business strategy is providing prototyping solutions for the CAN Bus (including SAE J1939, ISOBUS, NMEA 2000), and, in the months to follow, we will increase our focus on the Arduino platform, specifically the Arduino Due. Now [...]
This post is a follow-up on my article LPC1768/1769 - ARM Cortex M3 Development - MCUXpresso IDE Installation And Adding A Template Project, in which we installed the MCUXpresso integrated development environment (IDE) and created a working but non-functional project for the LPC1768/LPC7169 processor. You can start the compilation (click on "Build 'LPC1769Template' [Debug]"), and there will [...]
LPC1768/1769 - ARM Cortex M3 Development - MCUXpresso IDE Installation And Adding A Template Project
After getting your LPC1768 or LPC1769 Cortex-M3 Development Board, it is time to getting started with MCUXpresso IDE. In this Step by Step tutorial we will go through the process of creating projects in MCUXpresso IDE for Cortex-M series Microcontrollers by NXP(Founded by Philips) based on CMSIS (Cortex Microcontroller Software Interface Standard). MCUXpresso is a derivative [...]
There are two worlds when it comes to the programming of embedded applications, one for hobbyists and engineers involved in rapid prototyping and one for "professional" programmers. The first one is represented by hardware platforms such as the Arduino, Raspberry Pi, BeagleBone, and others. The second is dominated by non-standard and thus expensive hardware systems [...]
This page is part of a series of posts by Wilfried Voss titled NXP LPC17xx ARM Cortex-M3 Microcontroller - Programming Tips & Tricks, explaining the programming of embedded systems using the ARM Cortex-M3 processor. The MCUXpresso IDE brings developers an easy-to-use Eclipse-based development environment for NXP MCUs based on ARM® Cortex®-M cores, including, among many others, the LPC [...]
Artila Electronics, a designer and manufacturer of embedded device networking and computing, releases the FreeRTOS based, IBM Bluemix ready remote I/O module, RIO-2010BM, which is powered by a 32-bit NXP LPC1768 100MHz ARM Cortex M3 processor and equipped with 64KB SRAM 512KB Flash. The ARM cortex M3 plus the FreeRTOS make RIO-2010BM a computing platform for [...]
The Arduino Due is a microcontroller board based on the Atmel SAM3X8E ARM Cortex-M3 CPU. It is the first Arduino board based on a 32-bit ARM core microcontroller. It has 54 digital input/output pins (of which 12 can be used as PWM outputs), 12 analog inputs, 4 UARTs (hardware serial ports), a 84 MHz clock, [...]
In a previous post ( Arduino Due: Dual CAN Port Test Sketch), I demonstrated how to read and write the two CAN ports on the Arduino Due. The post explains that the two CAN ports on the Arduino Due are practically useless without their respective CAN transceivers. CAN transceivers convert a regular TTL signal from the CAN controller [...]