Texas Instruments
MSP430

Part Reviewed: MSP430FR2111

 

Core

The MSP430 has a fully orthogonal instruction set that supports essentially every sort of addressing mode for every instruction. I didn’t do much assembly programming with this MCU, and almost all examples I’ve seen are done in C, but orthogonal instruction sets tend to make things easier for assembly programming.

 

Development Environment

Code Composer Studio is Texas Instruments’ heavily-modified Eclipse distribution. I used CCS v7.2, which is based on Eclipse Neon (4.6.0)

I enjoyed the Resource Explorer feature in Code Composer Studio; it’s an optional pane in CCS that contains documentation, code examples, and API references.  I usually detach it from CCS altogether and let my operating system manage it as a separate window. The problem with it is that since it’s Eclipse, this pane — docked or floating in its own window — is considered a view which is part of a perspective; if you get the Resource Explorer open to the correct page, the moment you start debugging, it will vanish. You can create a Resource Explorer view when you’re debugging, but it’s not the same Resource Explorer! Consequently, it will have its own internal state.

It’s also great to see performance-oriented hints — what TI calls the ULP Advisor — that appear automatically when compiling code. I was able to shave off several hundred microamps by following instructions to set all unused pins to outputs; a common gotcha on many platforms, but nonetheless, one that ULP advisor reminds you to do.

When you invoke the ctrl-spacebar shortcut to show a tooltip hint with the parameters for the function, Code Composer Studio inserts these parameter names into the function, which isn’t particularly helpful — necessitating a highlight-delete-and-replace operation with the actual parameters you intended to pass to the function.

But there’s also some modifications I find annoying — for example, the Ctrl-Spacebar auto-complete shortcut works mostly correctly, but when invoking it while calling a function, it creates dummy variables for each parameter of the function, instead of just popping up a tooltip with the parameter names. I don’t know how else to invoke the tooltip, so I have to manually delete each parameter and replace it with the proper call (which is typically an eum or other constant, when working with the driver lib).

Code Generation

Historically, MSP430 projects supported the GRACE code configurator tool, but Texas Instruments has apparently deprecated it.

Compilers & Toolchain

CCS provides support for both

Peripheral Libraries

Texas Instruments distributes a peripheral library called the MSP430 DriverLib (also referred to as, or part of, MSPWare, or MSP430Ware — it’s TI, so there’s three or four different names for everything). The recommended way of installing it is from within the Resource Explorer view in Code Composer Studio; from there, make sure to ignore the outdated documentation, and instead, browse around on the forums to discover people wondering how to create a project which uses DriverLib.

Like the peripheral libraries from a few other MCU vendors, TI puts heavy emphasis on example projects, and very little emphasis on documentation. To really understand DriverLib, you’re going to be importing a lot of example projects, carefully reading them line-by-line, and digging into the source file to see what each DriverLib call does; this will require strong understanding of the MSP430 peripherals.

A well-written peripheral library would have something like:

UART_Init(EUSCI_A_BASE, 115200, P1_6, P1_7, 8, 1); // initialize EUSCIA @ 115200, 8N1, and use P1_6 as TX and P1_7 as RX

Instead, this peripheral library is not designed to abstract the hardware, but rather to simply abstract the registers, which gets quite silly.

You essentially do everything manually; and you’ll notice how comical these functions start to look. For example, to mux the TX and RX pins, you call:

 GPIO_setAsPeripheralModuleFunctionInputPin(
 GPIO_PORT_P1,
 GPIO_PIN6 | GPIO_PIN7,
 GPIO_PRIMARY_MODULE_FUNCTION
 );

How do you know that P1_6 and P1_7 have a “primary module function” that’s the UART TX and RX pins? Read the datasheet!

This is equivalent to this:


P1SEL0 |= (BIT6 | BIT7);

If I have to look in the datasheet anyway, I might as well notice that primary module functions are activated using the SEL0 register. How is this peripheral library saving me time?

With the pins muxed, just initialize the UART:

EUSCI_A_UART_initParam param = {0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 8;
param.firstModReg = 0;
param.secondModReg = 0xD6;
param.parity = EUSCI_A_UART_NO_PARITY;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;

EUSCI_A_UART_init(EUSCI_A0_BASE, &param);
EUSCI_A_UART_enable(EUSCI_A0_BASE);

This is where things get downright awful. How do you set the baud rate? You calculate it from formulas in the datasheet, and then plug the raw numbers into clockPrescalar, firstModReg and secondModeReg variables.

None of these calls are self-documenting or self-discoverable, like they are in other peripheral libraries (like the library for the STM8). For example, the method signature for CS_initClockSignal is:

void CS_initClockSignal(uint8_t selectedClockSignal,
 uint16_t clockSource,
 uint16_t clockSourceDivider)

C doesn’t really have strongly-typed enums, so all these functions just take integers, which are determined based on named constants you pass in. If TI cared about making the peripheral library self-documenting and self-discoverable, these named constants would have names that match their module and parameter name, like:

CS_initClockSignal(CS_SELECTEDCLOCKSIGNAL_ACLK,CS_CLOCKSOURCE_XT1CLK,CS_CLOCKSOURCEDIVIDER_1);

That way, I can start typing out the parameter name, and auto-complete will give me all my options for each parameter. Instead, they have arbitrary names:

CS_initClockSignal(CS_ACLK, CS_XT1CLK_SELECT, CS_CLOCK_DIVIDER_1);

If we were in the 1980s and didn’t have good text-completion, I’d enjoy the shorter names — but it’s 2017; variable names should be descriptive and logically organized.

All of my criticism about the DriverLib boils down to it being verbose, hard to recall, and redundant.

But it’s not worthless: there are lots of great examples — if you just want to get something up and running quickly, you’ll end up with a project full of copypasta from example projects that seems to work, and that’ll be good enough for many people.

Debugging Experience

It takes about 5 or 6 seconds to start a debug session on the MSP430. Code-stepping responsiveness is equally average. The debugging functionality is typical Eclipse fair, with a few useful additions. The EnergyTrace analyzer communicates with power-measurement hardware on the LaunchPad (and other dev kits) to measure current and voltage. The Registers view can read and modify individual register values (grouped by function), while also breaking down the register into its individual configuration values. There’s built-in documentation for everything, with drop-down selections for each option. I wish more IDEs had this style of register view — it helps keep you away from PDF datasheets, so you can focus on your project.

There’s also built-in support to plot arrays of signals (though not live — you have to halt the core to allow the debugger to read the data array), and some profiling

Performance

Bit-Wiggling

Because of its orthogonal instruction set, bit-wiggling the MSP430 results in two instructions — and XOR.B and a JMP. I observed a 7-cycle period between toggles; the XOR.B instruction appears to take five cycles, with the JMP taking two.

Biquad Filtering

The MSP430FR2111 lacks a hardware multiplier (which higher-end MSP430s have), which really stunted the performance of this chip; the processor turned in a dismal 35.65 ksps performance figure into a 2.41 mA operating current, yielding more than 223 nJ/sample.

Bottom Line

The MSP430 has a well-deserved reputation for its low-power prowess, and it didn’t disappoint in my testing. Its Eclipse-based IDE, Code Composer Studio, is now completely free and unrestricted — plus open-source fans will appreciate MSP430’s GCC support. Energia, a fork of the Arduino/Wiring IDE, is a great starter for hobbyists (especially when compared to the nearly-useless MSP430Ware peripheral library) — and TI fully embraces that ecosystem with integrated Code Composer Studio support. The biggest problem with the MSP430 is price: the part reviewed — the MSP430FR2111 — is an absolute baseline part with few bells and whistles (there weren’t even enough PWM channels to fully implement the RGB LED DMX receiver project). Expect to pay 2-3 times the competition.

Leave a comment