In my post last week, I explained how ST changed my favorite ARM Cortex-M4 development board very slightly and changed the name to protect the innocent. I had to rework this post to reflect the name change, but the concepts are intact.
This board was known as the STM32F4Discovery board until very recently, and is still known that way in the documentation. I suppose it could be considered the Rev. D STM32F4Discovery board, but the new USB UART support really simplified how I will be handling serial ports. I’ll write a post later on using a Rev. C board and what you have to do to follow the examples. Let’s get started.
Over the last six months, we’ve discussed what an embedded system is, went over the various tools involved, took a crash course in C, and looked at various aspects of embedded systems programming, Now it’s time to put our tools to use, grab a development board and get some hands on experience.
In the next series of posts, I will be introducing my current favorite development board, stepping through examples, and getting you comfortable with the documentation for a processor. This will not be an exhaustive overview of every aspect of our processor, more like teaching you to help yourself so you can move to other processors and tools and work on your own projects.
Introducing the board
In the workshop I lead at ENTS, the processor board that I have chosen is the STM32F407G-DISC1 Discovery board from STMicroelectronics. The ST Discovery boards are low cost development boards you can pick up through Digikey or Mouser.
My choice of the DISC1 board was not arbitrary, I was using one at work for prototyping real products, so I had some familiarity with the board. One of our customers had used an Atmel SAM4S and it seemed like a very nice processor, but the development board needed an extra debugger module (I see that they are included now). And TI has some boards in the same vein that are very good too.
All of the boards I considered use ARM Cortex-M processors. These processors are big enough that they don’t have the restrictions like having to worry about pages of memory, weird register rules, and running out of pins. They are a nice, clean design, that was intended to be used with a compiler. Nothing kills a hobby project faster than running out of memory and processor speed; it’s best to go big. All of this capacity might seem like expensive overkill, but for $30CDN ($21US) why put up with restrictions?
But why not an Arduino? When talking to the students at the workshop, many had worked with Arduino and had run into the limits of memory, speed, and pins. They wanted to go beyond what was possible on an Arduino, plus be able to understand what the Arduino libraries were hiding. The Arduino UNO uses an Atmel 328 processor which is an 8-bit device and has 32K of Flash memory and 2K of RAM. This is a great processor for small projects and learning, but they tend to run out of space when you start adding features to your project.
ARM doesn’t make chips, they design processors and sell the rights to use their designs to chip manufacturers. This has turned out to be a very lucrative business for them, and some chip manufacturers have stopped development of their existing processors because the ARM designs compete directly with their low volume 32-bit processors, and even with their 8-bit devices. Selling a processor that is not an ARM is a liability now.
But what is does the ARM architecture provide? It is the compute core of the processor, not all of the peripherals like SPI, Ethernet, and Flash memory, just the calculating part. Between manufacturers, the instruction set will be the same, but the peripherals will not be. The compilers aren’t affected by peripheral differences, since peripherals are simply used by putting values into memory locations. And when your compiler that can cover processors from ST, TI, Atmel, NXP, Maxim, and all of the other ARM licensees, that is a huge user base and you get better compilers and better libraries in the long run.
ARM has three processor design families; Cortex-A, R, and M. The Cortex-A processors are used in larger devices like the BeagleBone, RaspberryPi, iPhone, iPad, and Android devices. The Cortex-R processors are designed for high reliability real-time embedded systems like hot tub controllers and flight displays. The Cortex-M series is intended for cost conscious commodity embedded systems. We will be using an M.
The DISC1 board has plenty of goodies built-in to allow experimentation without having to add any new chips or boards. It has an audio DAC, microphone, and amplifier, a three axis accelerometer, a push button, four LEDs, a full-speed USB on-the-go port, and all of the processor pins are brought out to 0.1” spacing headers. Plus it has the all important USB debugging module built on to the board.
The processor is the STM32F407VG Cortex-M4F running at up to 168MHz, with 32-bit hardware floating point, 1MB of Flash, and 192KB of RAM. The processor uses memory mapped peripherals in a linear (not segmented) 32-bit address space.
Some of the peripherals include:
- 3 - 12-bit ADCs with up to 24 channels of input
- 2 - 12-bit DACs
- 14 timers plus a dedicated system tick timer
- Real time clock with leap year support
- True random number generator
- Unique processor ID
- 3 SPI
- 3 I2C
- 4 UART
- 2 CAN
Basically, everything that you need to suck up all of your spare time.
One of the things I like about using the ST board is a piece of software that ST provides called CubeMX (Cube). Cube is a utility that you use to generate all of the startup code for your processor.
One of the painful steps in setting up a processor is working out all of the conflicts between the various peripherals you want to use and the pins they attach to. Most pins will be attached to multiple peripherals and you have to choose which peripherals to let use a pin. Most peripherals can be mapped onto alternate pins, so if you want to use the ethernet and a UART that use the same pin, you can move the UART to another set of pins. Cube makes this process simpler, and then it generates the code to turn on the port, map the peripheral onto the port, set up the speeds, and start the peripheral.
Finally, ST provides a library called the Hardware Abstraction Layer (HAL), that gives you high level calls to control the peripherals. We will be using the HAL rather than poking values into registers (like some other people are doing).
This post is part of a series. Please see the other posts here.