MSP430

An introduction to the TI MSP430 low-power microcontrollers

The MSP430 is a very clean 16-bit byte-addressed processor with a 64K unified address space, and memory-mapped peripherals. The current family includes a variety of on-chip peripherals, and ranges from a 20-pin package with 1K of ROM and 128 bytes of RAM to 100-pin packages with 60K of ROM and 2K of RAM. Devices with greater RAM and ROM, and additional peripheral blocks are in development.
The MSP430 excels where low power consumption is important. Many applications, such as water meters, are currently achieving more than 10 years operation from a single button cell battery. If low power is not critical, well, the MSP430 is a nice elegant device to use, anyway. It programs very well in C, making assembly language programming unnecessary. There is no memory bank switching to make the compiler's life difficult; it uses normal RAM for its stack; it has a clean 16 bit instruction set. In fact, it is somewhat like an ordinary desktop RISC processor, but requires very little power.

The memory map

All current MSP430s share a common memory map. The amount of each type of memory varies with the device, but the overall layout is common.
The main ROM is always at the highest addresses. In the 60K version it extends from address 0x1100 to 0xFFFF (see below for what happens between 0x1000 and 0x10FF). Some devices use mask programmed ROM or EPROM. All the more recent parts are available with flash (electrically erasable) memory, and have a mask programmed option for high volume users. If the device has flash memory, it is erasable in 512 byte pages. The device can self-program its own flash memory, although this imposes some constraints on the supply voltage.
At the low end of memory is a 512 byte space for the memory-mapped peripherals. The first 256 bytes of this are on an 8-bit bus, and can only be accessed 8 bits at a time. The second 256 bytes are on a 16-bit bus, and can only be accessed 16 bits at a time.
RAM begins at address 0x200. If there is 2K of RAM, it extends from address 0x0200 to 0x9FF.
Processors with flash memory have a 1K serial bootloader ROM at addresses 0x0C00 to 0x0FFF. This is unalterable, masked, ROM. It contains a factory set program to erase and reprogram the on board flash memory. (see later for other programming and debug options).
Processors with flash memory also have an additional 128 or 256 bytes of flash memory between addresses 0x1000 and 0x107F or 0x10FF. The only real difference between this and the main flash memory is that this is erasable in 128 byte pages. This makes it more suitable for efficiently handling configuration data.


The register set

The processor has 16 16-bit registers, although only 12 of them are truly general purpose. The first four have dedicated uses:

  • r0 (aka PC) is the program counter. You can jump by assigning to r0, and immediate constants are fetched from the instruction stream using the post-increment addressing mode on r0. The PC is always even.
  • r1 (aka SP) is the stack pointer. This is used by call and push instructions, and by interrupt handling. There is only one stack pointer; the MSP430 doesn't have anything resembling a supervisor mode. The stack pointer is always even; It is unclear if the LSB is even implemented.
  • r2 (aka SR) is the status register. Its bits are assigned as follows:


    1514131211109876543210
    ReservedVSCG1SCG0OSCOFFCPUOFFGIENZGC
    SCG (system clock generator), OSCOFF (oscillator off), and CPUOFF are used to control the various low-power modes.
    GIE is the global interrupt enable. Turning off this bit masks interrupts. (NOTE: it may be delayed by 1 cycle, so an interrupt may be taken after the instruction after GIE is cleared. Add a NOP or clear GIE one instruction earlier than your real "critical section".)
    N, Z, C and V are the usual processor status bits, set as a side effect to instruction execution. If r2 is specified as a destination, the explicitly written bits override the side effects. An instruction sets all 4 bits, or none of them. Logical instructions set C to the opposite of Z (C is set if the result is NOT zero), and clear V to 0.
    C is a "carry" bit as opposed to a "borrow" bit when subtracting. That is, subtract with carry of A-B computes A + ~B + Carry. (~ is the C "not" or "bitwise invert" operator.)
    Note that the basic move instruction does NOT set these bits (unless it's a move to r2).
  • r3 is hardwired to 0. If specified as a source, its value is 0. If specified as a destination, the value is discarded.
r2 and r3 have no use as pointers. When specified in the context of a pointer they provide an alternate function - common constant values. This is one of the important features of the MSP430 instruction set, allowing it to achieve a high level of code density, and a flexible instruction set. These constant registers can provide the numbers -1, 1, 2, 4 or 8. So, for example, the "clr x" is actually emulated by the instruction "mov #0,x". The constant "0" is taken from the constant register r3. The assembler understands both "clr x" and "mov #0,x", and produces the same code for either. Many RISC and RISC like architectures suffer poor code density. The constant registers allow the MSP430 to achieve a very competitive code density. They also make the code faster, as less program memory read cycles are needed. See below for the actual encoding used to select a particular constant.
Note that some assemblers for the MSP430 allow the use of the alternate names "PC" for "r0", "SP" for "r1", and "SR" for "r2". GNU msp430 binutils does not understand these alternate names. You must use "r0", "r1" or "r2".



The available addressing modes

MSP430 instructions have at most two operands, a source and a destination.
All instructions are 16 bits long, followed by at most two optional offsets words, one for each of the source and the destination.
The source operand (or the only operand of one-operand instructions) is specified with 2 addressing mode bits and 4 register select bits:


00 nnnnRnRegister direct
01 nnnnoffset(Rn)Register indexed
10 nnnn@RnRegister indirect
11 nnnn@Rn+Register indirect with post-increment
The only addressing mode that uses an extension word is the indexed mode. A 16-bit offset can reach anywhere in the address space.
The destination operand in a two-operand instruction has only one addressing mode bit, which selects either register direct or indexed. Register indirect can obviously be faked up with a zero index.
Operand addresses are computed in a simple, sequential way. The C statement
*p++ *= 2;
can be implemented as
add @Rn+,-2(Rn)
because the source operand is computed completely (including the register post-increment) before the destination is computed.
When r0 (the program counter) is used as a base address, indexed mode provides PC-relative addressing. This is, in fact, the usual way that TI's MSP430 assembler accesses operands when a label is referred to.
@r0 just specifies the following instruction word in ROM, but @r0+ specifies that word and skips over it. In other word, an immediate constant! You can just write #1234 and the assembler will specify the addressing mode properly.
r1, the stack pointer, can be used with any addressing mode, but @r1+ always increments by 2 bytes, even on a byte access.
When r2 (the status register) or r3 (the zero register) are specified, the addressing mode bits are decoded specially:



00 0010r2Normal access
01 0010&<location>Absolute addressing. The extension word is used as the address directly. The leading & is TI's way of indicating that the usual PC-relative addressing should not be used.
10 0010#4This encoding specifies the immediate constant 4.
11 0010#8This encoding specifies the immediate constant 8.
00 0011#0This encoding specifies the immediate constant 0.
01 0011#1This encoding specifies the immediate constant 1.
10 0011#2This encoding specifies the immediate constant 2.
11 0011#-1This specifies the all-bits-set constant, -1.







Byte and word issues

The MSP430 is byte-addressed, and little-endian. Word operands must be located at even addresses. Most instructions have a byte/word bit, which selects the operand size. Appending ".b" to an instruction makes it a byte operation. Appending ".w" to an instruction, to make it a word operation, is also legal. However, since it is also the default behaviour, if you add nothing, it is generally omitted. A byte instruction with a register destination clears the high 8 bits of the register to 0. Thus, the following would clear the top byte of the register, leaving the lower byte unchanged:
mov.b Rn,Rn

The on-chip peripherals are divided into an 8-bit bank and a 16-bit bank. The 8-bit peripherals must only be accessed using 8-bit instructions; using a 16-bit access produces garbage in the high byte. The 16-bit peripherals must only be accessed at even addresses. Byte accesses to even addresses are legal, but not usually useful.
The processor's behaviour when a word is accessed at an odd location is poorly documented. In all current processors the lower bit is just silently ignored. The effect is, therefore, the same as specifying an address which is one less.
It should be noted that the the byte and word addressing behaviour of the MSP430 prevents the processor supporting strict compliance with the standard C language. In standard C everything should be copiable, by copying at the byte level. This usually has little impact on the types of embedded program for which the MSP430 is typically used. However, it can sometimes catch you out!



The instruction set

All instructions are 16 bits long, and there are only three instruction formats:


1514131211109876543210
000100OpcodeB/WAdDest reg
001ConditionPC offset (10 bit)
OpcodeSource regAdB/WAsDest reg

As and Ad are the source and destination addressing modes. B/W is a bit that is set to 1 for byte instructions. 2-operand opcodes begin at 0100 = 4.
As you can see, there are at most 8+8+12 = 28 instructions to keep track of, which is nice and simple.
One-operand instructions:


000RRC(.B)9-bit rotate right through carry. C->msbit->...->lsbit->C. Clear the carry bit beforehand to do a logical right shift.
001SWPBSwap 8-bit register halves. No byte form.
010RRA(.B)Badly named, this is an 8-bit arithmetic right shift.
011SXTSign extend 8 bits to 16. No byte form.
100PUSH(.B)Push operand on stack. Push byte decrements SP by 2. CPU BUG: PUSH #4 and PUSH #8 do not work when the short encoding using @r2 and @r2+ is used. The workaround, to use a 16-bit immediate, is trivial, so TI do not plan to fix this bug.
101CALLFetch operand, push PC, then assign operand value to PC. Note the immediate form is the most commonly used. There is no easy way to perform a PC-relative call; the PC-relative addressing mode fetches a word and uses it as an absolute address. This has no byte form.
110RETIPop SP, then pop PC. Note that because flags like CPUOFF are in the stored status register, the CPU will normally return to the low-power mode it was previously in. This can be changed by adjusting the SR value stored on the stack before invoking RETI (see below). The operand field is unused.
111Not usedThe MSP430 actually only has 27 instructions.

The status flags are set by RRA, RRC, SXT, and RETI.
The status flags are NOT set by PUSH, SWPB, and CALL.
Relative jumps. These are all PC-relative jumps, adding twice the sign-extended offset to the PC, for a jump range of -1024 to +1022.


000JNE/JNZJump if Z==0 (if !=)
001JEQ/ZJump if Z==1 (if ==)
010JNC/JLOJump if C==0 (if unsigned <)
011JC/JHSJump if C==1 (if unsigned >=)
100JNJump if N==1 Note there is no "JP" if N==0!
101JGEJump if N==V (if signed >=)
110JLJump if N!=V (if signed <)
111JMPJump unconditionally

Two-operand instructions. These basically perform dest = src op dest operations. However, MOV doesn't fetch the destination, and CMP and BIT do not write to the destination. All are valid in their 8 and 16 bit forms.
Operands are written in the order src,dest.


0100MOV src,destdest = srcThe status flags are NOT set.
0101ADD src,destdest += src
0110ADDC src,destdest += src + C
0111SUBC src,destdest += ~src + C
1001SUB src,destdest -= srcImplemented as dest += ~src + 1.
1001CMP src,destdest - srcSets status only; the destination is not written.
1010DADD src,destdest += src + C, BCD.
1011BIT src,destdest & srcSets status only; the destination is not written.
1100BIC src,destdest &= ~srcThe status flags are NOT set.
1101BIS src,destdest |= srcThe status flags are NOT set.
1110XOR src,destdest ^= src
1111AND src,destdest &=- src

There are a number of zero- and one-operand pseudo-operations that can be built from these two-operand forms. These are usually referred to as "emulated" instructions:


NOPMOV r3,r3Any register from r3 to r15 would do the same thing.
POP dstMOV @SP+,dst
Note that other forms of a NOP instruction can be constructed as emulated instructions, which take different numbers of cycles to execute. These can sometimes be useful in constructing accurate timing patterns in software.
Branch and return can be done by moving to PC (r0):


BR dstMOV dst,PC
RETMOV @SP+,PC

The constants were chosen to make status register (r2) twiddling efficient:


CLRCBIC #1,SR
SETCBIS #1,SR
CLRZBIC #2,SR
SETZBIS #2,SR
CLRNBIC #4,SR
SETNBIS #4,SR
DINTBIC #8,SR
EINTBIC #8,SR

Shift and rotate left is done with add:


RLA(.B) dstADD(.B) dst,dst
RLC(.B) dstADDC(.B) dst,dst

Some common one-operand instructions:


INV(.B) dstXOR(.B) #-1,dst
CLR(.B) dstMOV(.B) #0,dst
TST(.B) dstCMP(.B) #0,dst

Increment and decrement (by one or two):


DEC(.B) dstSUB(.B) #1,dst
DECD(.B) dstSUB(.B) #2,dst
INC(.B) dstADD(.B) #1,dst
INCD(.B) dstADD(.B) #2,dst

Adding and subtracting only the carry bit:


ADC(.B) dstADDC(.B) #0,dst
DADC(.B) dstDADD(.B) #0,dst
SBC(.B) dstSUBC(.B) #0,dst



Instruction timing

Generally, instructions take 1 cycle per word of memory accessed.
Thus, start with 1 cycle for the instruction itself. Then add 1 cycle for a memory source, 2 cycles for a memory destination, and one additional cycle per offset word.
Note that in two-operand instructions, memory destinations require an offset word, so they cost a total of 3 cycles.
This holds even for instructions (MOV, CMP and BIT) that only access the destination once.
Short immediate constants (using r2 or r3) count as register operands for instruction timing purposes.
Exceptions to this rule are:

  • A 2-operand instruction which writes to PC (r0) takes an extra cycle if it's only one word long (i.e. source not indexed).
  • Jumps take 2 cycles, whether taken or not.
  • PUSH, CALL and RETI are special:


    PUSH Rn3 cycles
    PUSH @Rn, @Rn+, #x4 cycles
    PUSH offset(Rn)5 cycles
    CALL Rn4 cycles
    CALL @Rn4 cycles
    CALL @Rn+, #x5 cycles
    CALL offset(Rn)5 cycles
    RETI5 cycles

Other CPU operations take following times to execute:


Interrupt6 cycles
Reset4 cycles

Interrupts

The MSP430 supports 16 exception vectors, from 0xFFE0 to 0xFFFF. There are 14 maskable interrupts which are assigned to peripherals in a model-dependent way. The first 14 can be masked by clearing the GIE bit in the status register. The last two are non-maskable: 0xFFFC is the NMI vector, and 0xFFFE is the reset vector.
Actually, all of the "non-maskable" interrupt sources are maskable, just not with the GIE bit. They are:

  • The RST/NMI pin can be configured to send an NMI rather than reset the processor when pulled low.
  • Flash access violation.
  • An oscillator fault occurs. The more recent MSP430 devices use a on chip system clock called the FLL - frequency locked loop. This can be programmed to provide a range of core clock frequencies which are phase locked to an external crystal (usually a 32kHz watch type crystal). If the frequency adjustment reaches the extreme limits, and the loop cannot lock, an oscillator fault is declared.
    Other MSP430 devices use a different oscillator module. Here the oscillator fault flag is set when one of the oscillators does not oscillate. The CPU should be using an alternate oscillator if this happens.

Handling an interrupt (other than RESET) consists of:

  • Push PC on stack.
  • Push SR on stack.
  • Choose the highest priority interrupt to service.
  • If the interrupt has only one source, reset the interrupt request bit. If there are multiple possible sources, leave them for software to poll.
  • If this is an NMI, clear enable bits for the three NMI sources mentioned above.
  • Clear the SR (except for SCG0), disabling interrupts and power-saving.
  • Fetch the interrupt vector into the PC
  • Start executing the interrupt handler

A reset is similar, but doesn't save any state.
You can nest interrupt handlers by disabling the current source and setting the GIE bit back to 1.
Note that there are no exceptions internal to the processor such as divide by zero or address error.


The hardware multiplier

Some MSP430 processors have, as a memory-mapped peripheral, a hardware 16x16->32 multiply/accumulate unit. This is accessed via eight 16-bit registers from 0x0130 to 0x013F.
Writing the first operand specifies the operation type depending on the address used:

  • 0x0130 - MPY unsigned multiply.
  • 0x0132 - MPYS signed multiply.
  • 0x0134 - MAC unsigned multiply-accumulate.
  • 0x0136 - MACS signed multiply-accumulate.

Writing the second operand to 0x0138 starts the operation. The product is available in 0x013A(SumLo), 0x013C(SumHi) and 0x013E(SumExt) with only 2 cycles of latency. Thus, you can fetch the result with the next instruction if it's an indexed or absolute addressing mode.
If you use a register indirect or post-increment mode, you need to insert a nop (or something) between writing the second operand and reading the results.
The accumulator (SumLo and SumHi) is only 32 bits. SumExt is set to the carry (0 or 1) of the 32+32-bit sum in a MAC operation, but the old value of SumExt is not used.
In MPYS and MACS, SumExt is just the sign-extension of SumHi (0 or -1), which is not tremendously useful.
While all registers can be read back, the operation specified by the first operand's address is not recoverable by an interrupt handler. Thus, it is not possible to context-switch the multiplier unless you add some sort of wrapper software (locking or shadow registers) around it.
All registers are read/write except:

  • The first four are actually aliases for one register, so they always read the same value.
  • SumExt is not writable.

The multiplier is one 16-bit peripheral where a byte write might make sense. A byte write is zero-extended to 16 bits, which allows 8-bit unsigned operands to be used naturally.
Once the first operand has been written, multiple second operands can be written without changing it. For example, when evaluating a polynomial by Horner's rule
a + b*x + c*x^2 + d*x^3 = (((d * x + c) * x) + b) * x + a
Then x can be written to the first operand register just once.


Low power modes

Low power operation is a key feature of the MSP430. Its design gives very low leakage, and it operates from a single supply rail. This gives an extremely low current drain when the processor is in standby mode. Several low power modes are supported, which balance the needs of different applications. As the number of the LPM mode number rises, the number of things disabled on the chip also rises:

  • LPM0 - The CPU is disabled.
  • LPM1 - The loop control for the fast clock (MCLK) is also disabled.
  • LPM2 - The fast clock (MCLK) is also disabled.
  • LPM3 - The DCO oscillator and its DC generator are also disabled.
  • LPM4 - The crystal oscillator is also disabled.

As the LPM mode rises power consumption decreases, but the time needed to wake up increases. Note, however, that the MSP430's design keeps even the worst case wakeup time fairly low. For example, the parts which use the FLL system clock module need only a few microseconds to get the FLL locked after waking up.
The MSP430 is switched into a low power mode by altering bits in the status register. Typically processing within an interrupt routine will determine when the processor needs to change from a low power mode to normal operation, and alters those same status register bits to achieve that. It does this by directly modifying the memory location where the processor's status register was pushed onto the stack at the start of the interrupt. When the interrupt routine returns, using the RETI instruction, the altered status register value is loaded into the processor status register, and the processor continues operation in the newly selected mode. The C language tools support an easy method to handle this.

Programming the flash memory

An MSP430s using flash ROM can program themselves using software, but there is an initial chicken-and-egg problem getting the programming software into the chip in the first instance.
Fortunately, there are two ways you can do this on a "bare" MSP430:

  • Via the JTAG interface
  • Via the bootstrap loader

JTAG is a JEDEC-standard in-circuit testing interface. It uses 4 pins: mode, clock, data in and data out. It's basically a big shift register. You can chain devices together by connecting the in and out pins to make one giant whole-board shift register, and take over the I/O pins for various sorts of board testing.
There are also a few opcodes reserved to for manufacturer extensions, which TI uses for remote access and debugging purposes.
All MSP430 devices have a JTAG port, although on the 20- and 28-pin parts, the pins are multiplexed with normal I/O pins and only a dedicated "test" pin is needed, to enable the JTAG functionality.
The full capabilities of TI's extensions to the JTAG port are rather extensive, and include stopping and single-stepping the processor. See TI's app. note slaa149 for details.
But, in particular, you can perform arbitrary memory accesses, and thereby program the flash ROM.
This is quick, if you can do all the complex wiggling of the JTAG control lines fast enough, but that's rather complex piece of work.
An alternative is a bootstrap loader that is included on all flash MSP430 processors and uses standard 9600 baud asynchronous communications. For those parts with 2k of RAM you can download a replacement BSL and use 38400 baud. Downloading this at 9600 baud, and then flashing at 38400 baud is faster for programs larger than about 10k bytes.
This is also invoked by special wiggling of the TEST input while RESET is active. (For parts with a dedicated JTAG interface, and thus no TEST pin, TCK is used instead.)
All this requires is some level-shifters and a serial port. See TI application notes slaa089a and slaa096b for details.


Decoding part numbers

What does something like MSP430F1121 mean?
The letter indicates the type of ROM on board:

  • C - Mask ROM. This is programmed at manufacturing time.
  • E - UV-EPROM. This comes in a windowed package and is erasable with UV. This requires a special high voltage supply to program.
  • F - Flash ROM. This is electrically erasable, and can be programmed with normal operating voltages.
  • P - One-time programmable. This is an E part in a cheaper windowless package. Once programmed, it cannot be erased.

Note that only the original 3xx series parts use UV-EPROM. Everything after that uses Flash ROM. Programming the EPROM parts is done over the JTAG port.
The first digit after the letter is the overall family: 1, 3 or 4. They are roughly in increasing order of capability, but there's a lot of range. Parts are generally upward-compatible within a family.
Basically, 1xx parts don't have an LCD controller, while all the 3xx parts do. Both families have models with ADCs; the 11x2 parts have a 10-bit ADC, while others have a 12-bit ADC. Some parts have hardware UARTS, although any of them can bit-bang it.
Initially, the 1xx parts were small 20- and 28-pin parts, and the 3xx parts were 56 or 64 pins. However, the 1xx parts have grown up and the 13x and higher packages come in 64-pin packages, while the 3xx parts range from a 48-pin 31xS subset to 100 pins.
The second digit is the device within a family. Again, generally higher numbers are more capable, but it varies a lot. As a general overview:

  • 11x: 20-pin parts. 11x1 adds comparator, 11x2 adds ADC10.
  • 12x: 28-pin parts, like 11x1 but with more I/O and USART.
  • 13x: 64-pin parts, adding lots more I/O, another timer, USART, and ADC12.
  • 14x: 64-pin parts, like 13x but with a hardware multiplier and a second USART.
  • 15x: Like 13x, but adding 2xDAC12, 3xDMA, brownout reset and I2C.
  • 16x: Like 14x, but adding 2xDAC12, 3xDMA, brownout reset and I2C.
  • 31x: 56 pins, basic device with I/O, timers, comparator/timer, LCD driver.
  • 32x: 64 pins, like 31x but with ADC12+2 (can be kludged to do 14 bits).
  • 33x: 100 pins, like 31x with more I/O and LCD, multiplier, and USART.
  • 41x: 64 pins, basic device with I/O, timers, comparator, LCD driver.
  • 43x: 80 or 100 pins, more LCD, ADC12, second timer, USART, second crystal oscillator.
  • 44x: 100 pins, like 43x but with a hardware multiplier, second USART and expanded timer.
A fourth digit, if present, is a sub-version number. A '1121 is a '112 with a little bit extra (an analog comparator for software ADC). A '1122 is a '112 with a 10-bit ADC. (Exception: the 161x parts.)
The third digit encodes the amount of memory on the chip:

  • xx0: 1K ROM, 128 RAM
  • xx1: 2K ROM, 128 RAM
  • xx2: 4K ROM, 256 RAM
  • xx3: 8K ROM, 256 RAM
  • xx4: 12K ROM, 512 RAM
  • xx5: 16K ROM, 512 RAM
  • xx6: 24K ROM, 1024 RAM
  • xx7: 32K ROM, 1024 RAM
  • xx8: 48K ROM, 2048 RAM
  • xx9: 60K ROM, 2048 RAM
The 16x series adds:
  • xx10: 32K ROM, 5K RAM
  • xx11: 48K ROM, 10K RAM
Note the 161x numbers are an exception to the usual 4th digit rule.

MSP430 specific extensions to the GNU toolchain

This section describes the MSP430-specific extensions to the GNU toolset. You should refer to the GNU documentation for information about the standard features of the GNU tools.

Compiler options

The compiler recognises the following MSP430 specific command line parameters:

-mmcu=Specify the MCU name
-mno-volatile-workaroundDo not perform a volatile workaround for bitwise operations.
-mno-stack-initDo not initialise the stack as main() starts.
-minit-stack=Specify the initial stack address.
-mendup-at=Jump to the specified routine at the end of main().
-mforce-hwmulForce use of a hardware multiplier.
-mdisable-hwmulDo not use the hardware multiplier.
-minline-hwmulIssue inline code for 32-bit integer operations for devices with a hardware multiplier.
-mnoint-hwmulDo not disable and enable interrupts around hardware multiplier operations. This makes multiplication faster when you are certain no hardware multiplier operations will occur at deeper interrupt levels.
-mcall-shiftsUse subroutine calls for shift operations. This may save some space for shift intensive applications.
The following MCU names are currently recognised for the "-mmcu" parameter:

msp1msp2   
msp430x110msp430x112   
msp430x1101    
msp430x1111msp430x1121   
msp430x122msp430x123   
msp430x1222msp430x1232   
msp430x133msp430x135   
msp430x1331msp430x1351   
msp430x147msp430x148msp430x149  
msp430x1471msp430x1481msp430x1491  
msp430x155msp430x156msp430x157  
msp430x167msp430x168msp430x169msp430x1610msp430x1611
msp430x311msp430x312msp430x313msp430x314msp430x315
msp430x323msp430x325msp430x336msp430x337 
msp430x412msp430x413   
msp430xE423msp430xE425msp430xE427  
msp430xW423msp430xW425msp430xW427  
msp430x435msp430x436msp430x437  
msp430x447msp430x448msp430x449  
"msp1" means an MCU without a hardware multiplier. "msp2" means an MCU with a hardware multiplier. These can be useful to make the compiler generate the correct code for a new device, before it is fully supported.


Compiler defined symbols

The compiler defines some symbols, so the header files and source code can easily behave in an MCU dependant manner. These are:

  • MSP430
  • __MSP430__
  • __MSP430_xxx__, where xxx is replaced by the number of the MCU variant (e.g. __MSP430_149__ is defined for the msp430x149).


    The mspgcc header files

    The include path for the standard header files is automatically defined by the compiler. The header file "<io.h>" is usually included at the start of all mspgcc source files. This defines all TI's standard definitions for the MCU variant being used, along with some mspgcc specific extensions.
    If you have used other software tools for the MSP430, you will find mspgcc's header file handling a little different and a little simpler to use. There is a header file for each peripheral module type. Where variants of a module exist (e.g. the UART exists in versions with and without I2C facilities), switches are used to select the appropriate defines. There is a customised header file for each MCU group (e.g. msp430x44x.h for the msp430x447, msp430x448 and msp430x449). <io.h> inlcudes the appropriate header file, based on the command line "-mmcu" parameter. If you program for a number of different MSP430 parts, nothing needs to be changed in your source code to rebuild it for a different chip.

Comments

Popular Posts