If only I had one more [insert function here]!
There is one essential difference between embedded programmers and general computing programmers, and it has to do with the amazing variety of hardware we embedded programmers get to play with. I like to think of us as test pilots. While the larger community of pilots fly the same airplane and often the same routes every day, we enjoy a variety of machines and configurations that change often, searching for optimal cost, speed and utility in response to the market needs and/or our customers’ desires. As a result, our job is never boring - although, at times, we wish it was. Hence our somewhat bipolar approach to innovation: On one side, we try to find any excuse to play with the latest and greatest product/model prizing innovation and revolutionary advancements. On the other hand, we hate the learning curve that comes with it, and we wish everybody would use the same compiler, library and tools we just got familiar with and we learned to love… Only incremental changes, please…
Take Your Pick
We are in the year 2018, and when it comes to microcontrollers’ variety, there is no doubt in anyone’s mind that we have more than enough to choose from. We can pick any number of pins, any number of bits, any architecture and almost any combination of Flash and RAM memory. In fact, much of the competition among vendors in recent years has been focused on adding more of the above and expanding the resulting matrix of choices.
Some will argue that given sufficient clock speed and program memory space, any application can be written using only a bunch of general purpose I/Os (and I’ll throw in an ADC and a PWM for good measure). This sounds almost like a trivial corollary of Alan Turing’s original work on the General Purpose Computing Machine, extended to serve our embedded use case.
But, hopefully, we all agree that that this is not a sensible or practical strategy. After all, Alan Turing himself never built or used one of the machines that carry his name today.
Hopefully we all agree the embedded applications we develop today need a rich set of peripherals (functions) and this complicates matters, expanding the matrix, quite a bit.
So, even in 2018, in the world of ample embedded control choices, it is not uncommon for us designers to start working on a project using a given microcontroller model, only to realize we have to switch to a different one mid-project. Mind you, this is not for a lack of trying – it happens to lazy engineers who skipped proper analysis at the start and also to those who have done ample preparation and analysis. It is more often a matter of complexity -- much like in a chess game where we can only play so many moves ahead in our mind. It can be hard to see how the peripheral functions interact with each other as we put them to use in our applications, or it may be hard to predict the evolution of the hardware solution as the project requirements drift (as they always do) and deadlines loom ahead.
At best, a microcontroller change can be a minor disruption, and we are lucky enough to find a close match in the same family of devices from the same vendor. Things get more difficult when that option is not available, forcing us to change the device family, which often produces a domino effect as pinout changes and possibly other peripheral functions follow.
Core Independent Peripherals to the Rescue
The best way to deal with these types of issues is to plan ahead for them. Most recent microcontroller families do provide smart ways to rearrange the pins for each of the peripherals offered. I am not referring to a single alternate pin function (that is so 90’s) – I am talking about full pinout remapping for analog and digital functions. For example, in the Microchip portfolio of 8-, 16- and 32-bit microcontrollers this is known as the Peripheral Pin Select (PPS), every pin on the device will be able to operate as an input for any number of peripherals (up to 64 different ones in some models), and any peripheral output can be published on up to 16 different pins (even 32 in some models). Analog inputs to the ADC will be similarly multiplexed among the vast majority of the device pins (up to 35 out of 40 pins, for example).
While this is already great insurance against future migration incompatibilities, the real game changers are more flexible approaches such as the Core Independent Peripherals (CIPs) in Microchip devices. Keep in mind, this is not the primary reason CIPs were created. The goal of Core Independent Peripherals was to reduce the workload of the microcontroller CPU by automating as many of the low level and coordination activities normally required by traditional peripheral functions as possible. But the extra connection available and the flexible nature of the CIPs make them a perfect tool to solve the mid-project crisis.
A practical example: creating a new PWM function out of thin air
For a practical example, I want to bring your attention to a case that occurred recently. We were designing an enhanced version of an automotive sensor, which involved the use of several timers, a pair of 10-bit Pulse Width Modulation (PWM) modules and an analog comparator, all easily found in a humble 28-pin PIC16F18855 microcontroller. We quickly realized that we reached a hard limit in the resolution of our current design, and if we proceeded any further, we would need a 12-bit or higher resolution PWM register. Unfortunately, that option was not on the menu. Any similar 8-bit PIC microcontroller that shared a compatible form factor (and pinout) was either offering too small a program memory or adding a much larger/richer set of peripherals and higher cost. All we needed was one more PWM register with 12-bit or better resolution.
Luckily, PWM peripheral functions are quite simple to synthetize on a chip if you have a few flexible blocks and a bit of glue logic. Any PWM can be assembled by combining two elements in particular: a periodic pulse and a limit counter. In Figure 1 you can see how the two can be combined to provide the period and the duty cycle of the resulting square wave.
Figure 1 – A PWM as the sum of a base timer and a limit counter (Source: Microchip Technology)