I saw somewhere in the web pages that a description of the processor
was solicited.  Here's a first draft of a summary.  Comments?




A brief intriduction to the TI MSP430 low-power microcontroller...

The MSP430 is a very clean 16-bit byte-addressed processor with a 64K
unified address space and a memory-mapped peripherals.  The 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.

TI are promoting it for its ultra-low-power capabilities, but it's
a pretty nice device anyway.

In particular, there is no bank-switching of any sort, and
there are no write-only registers.


* Memory map

ROM is always at high addresses.  In the 60K version is extends from
addresses 0x1000 to 0xFFFF.

At the low end is 512 bytes of memory-mapeed peripherals.  The first
256 bytes 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.

This is followed by RAM.  If there is 2K of RAM, this extends from
0x0200 to 0x9FF.

Processors with Flash (electrically eraseable) ROM feature a 1K serial
bootloader ROM at 0x0C00 to 0x0FFF.  This is a true, hardwired ROM.
They also have an additional 128 or 257 bytes of programmable "data ROM"
at 0x1000 to 0x107F or 0x10FF.  The Program ROM is in addition to this,
except for the 60K version.

* 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 is PC, the program counter.  You can jump by assigning to R0, and
  immediate constants are fetched from the instruction stream using
  the postincrement addressing mode on R0.  The PC is always even.

- R1 is SP, 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; I'm not even sure if the low bit is implemented.

- R2 is SR, the status register.  The bits are assigned as follows:
  1   1   1   1   1   1   1
  6   5   4   3   2   1   0   9   8   7   6   5   4   3   2   1   0
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  |          reserved         | V |SCG|SCG|OSC|CPU|GIE| N | Z | C | SR
  |                           |   | 1 | 0 |OFF|OFF|   |   |   |   |
  +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

  The System Clock Generator (SCG) bits, OSC off and CPU off are used
  for various low-power modes and won't be explained here.

  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 intruction 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 hardwaired to 0.  If specified as a source, a value of 0 is used.
  If specified as a destination, the result is discarded.

Since R2 and R3 make no sense as pointers, the instruction encodings that
would normally specify addressing modes based on them are used to encode
other useful small constants: -1, 1, 2, 4 and 8.


Note that the GMU msp430 binutils don't understand the "PC", "SP" and
"SR" registers; you have to specify R0, R1 or R2.


* 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 nnnn - Rn, register direct
01 nnnn - offset(Rn), register indexed (same as 68000)
10 nnnn - @Rn, register indirect (would be (Rn) on 68000)
11 nnnn - @Rn+, postincrement (would be (Rn)+ on 68000)

The only mode that takes an extension word is indexed.  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 direct 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 postincrement) 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 instructon word in ROM, but @R0+
specifies that word and skips over it.  In other word, an immediate
constant!  You can jyst 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 0010 - R2, normal access
01 0010 - &offset, 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 - #4.  This encoding specifies the immediate constant 4.
11 0010 - #8.  This encoding specifies the immediate constant 8.
00 0011 - #0.  This encoding specifies the immediate constant 0.
01 0011 - #1.  This encoding specifies the immediate constant 1.
        Note that there is no extension word in this case!
10 0011 - #2.  This encoding specifies the immediate constant 2.
11 0011 - #-1.  This specifies the all-bits-set constant -1.


* Byte/Word

The MSP430 is byte-addressed, and little-endian.  Word operands must be at
even addresses.  All instructions have a byte/word bit which selects the
operand size.  A byte instruction with a register destination clears the
high 8 bits of the register to 0.

(Thus, a register can be zero-extended with mov.b Rn,Rn.)

To specify a byte instruction, add a ".B" suffix to the opcode.
".W" is legal, but is the default, and is usually omitted.

The on-chip periperals 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.

Note that this is a violation of the C language rule that everything
can be copied by copying bytes.


It's not documented what happens if you try a word access at
an odd address.  There's no processor exception for such a case,
so I suspect the low bit is just ignored.


* Instruction set

As mentioned above, all instructions are 16 bits long.  There are only
three instruction formats:

1   1   1   1   1   1   1
6   5   4   3   2   1   0   9   8   7   6   5   4   3   2   1   0
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0   0   0   1   0   0 |  opcode   |B/W|   Ad  |   dest reg    | 1-operand
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
| 0   0   1 | condition |     10-bit PC offset                  | relative jump
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|     opcode    |   source reg  | Ad|B/W|   As  |   dest reg    | 2-operand
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

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
000 - RRC(.B).  9-bit rotate right through carry.  C->msbit->...->lsbit->C.
        Clear the carry bit beforehand to do a logical right shift.
001 - SWPB.  Swap 8-bit register halves.  No byte form.
010 - RRA(.B).  Badly named, this is an 8-bit arithmetic right shift.
011 - SXT.  Sign extend 8 bits to 16.  No byte form.
100 - PUSH(.B).  Push operand on stack.  Push byte decrements SP by 2.
        CPU BUG: PUSH #4 and PUSH #8 don't work when the short encoding
        using @R2 and @R2+ is used.  The workaround, to use a 16-bit
        immediate, is trivial, so TI don't plan on fixing this bug.
101 - CALL.  Fetch operand, push PC, then assign operand value to PC.
        Note that 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.
110 - RETI.  Pop SP, then pop PC.  Note that because flags like
        CPUOFF are in the stored status register, the CPU will return
        to the low-power mode it was in, unless you adjust the SR
        before invoking RETI.  Operand field unused.
111 - Not used.  The 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.
000 - JNE/JNZ   Jump if Z=0
001 - JEQ/Z     Jump if Z=1
010 - JNC/JLO   Jump if C=0
011 - JC/JHS    Jump if C=1
100 - JN        Jump if N=1  Note that there is no "JP" if N=0!
101 - JGE       Jump if N==V
110 - JL        Jump if N!=V
111 - JMP       Jump unconditionally

Two-operand instructions.  These are basically dest = src op dest,
although MOV doesn't fetch the destination, and CMP and BIT don't
write the destination.  All are also available in byte (.B) form.

Operands are written in src,dest order.

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

There are a number of zero- and one-operand pseudo-operations that
can be built out of these two-operand forms:

NOP             MOV #0,#0
POP dst         MOV @SP+,dst

Branch and return can be done by moving to PC (R0):
BR dst          MOV dst,PC
RET             MOV @SP+,PC

The constants were chosen to make status register (R2) twiddling easy:
CLRC            BIC #1,SR
SETC            BIS #1,SR
CLRZ            BIC #2,SR
SETZ            BIS #2,SR
CLRN            BIC #4,SR
SETN            BIS #4,SR 
DINT            BIC #8,SR
EINT            BIC #8,SR

Shift and rotate left is done with add:
RLA(.B) dst     ADD(.B) dst,dst
RLC(.B) dst     ADDC(.B) dst,dst

Some common one-operand instructions:
INV(.B) dst     XOR(.B) #-1,dst
CLR(.B) dst     MOV(.B) #0,dst
TST(.B) dst     CMP(.B) #0,dst

Increment and decrement (by one or two):
DEC(.B) dst     SUB(.B) #1,dst
DECD(.B) dst    SUB(.B) #2,dst
INC(.B) dst     ADD(.B) #1,dst
INCD(.B) dst    ADD(.B) #2,dst

And adding just the carry bit to things:
ADC(.B) dst     ADDC(.B) #0,dst
DADC(.B) dst    DADD(.B) #0,dst
SBC(.B) dst     SUBC(.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 intruction 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 Rn - 3 cycles
  PUSH @Rn, @Rn+, #x - 4 cycles
  PUSH offset(Rn) - 5 cycles

  CALL Rn - 4 cycles
  CALL @Rn - 4 cycles
  CALL @Rn+, #x - 5 cycles
  CALL offset(Rn) - 5 cycles

  RETI - 5 cycles

Other CPU operations take time as follows:
- Interrupt - 6 cycles 
- Reset - 4 cycles


* Interrupts

The MSP430 supports 16 exception vectors, from 0xFFE0 to 0xFFFF.
There are 14 maskable interrupts which are assigned to peripherals
in a midel-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.
- An oscillator fault occurs.  The MSP430 uses an on-chip programmable
  oscillator which can be automatically frequency-locked to an external
  32 kHz crystal.  If the frequency adjustment reaches the extreme
  limits (the on-board oscillator can't be synchronized with the
  reference crystal), an oscillator fault is declared.

Taking 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.  You can cause exceptions
or reset by writing to peripherals.


* The hardware multiplier

Some MSP430 processors have, as a memory-mapped peripheral, a haradware
16x16->32 multiply/accumulate unit.  This is accessed via 8 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 postincrement 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-estension 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.

(Arrgh.  Why couldn't TI have specified the operation with the
address of the SECOND operand?)

All registers are read/write except:
- The first 4 are actually aliases for one register, so they always
  read the same value.
- SumExt is not writeable.

The multipler 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 once.


* Programming

An MSP460 can program itself with software, but there is an initial
chicken-and-egg problem getting the programming software into the
chip to program itself.

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 giat 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.

This is also invoked by special wiggling of the TEST input while
RESET is active.  (For poarts 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 app notes slaa089a and slaa096b for details.


* Decoding part numbers.

What does something like MSP430F1121 mean?

Well, the letter indicates the type of memory on board:
C - Mask ROM.  This is programmed at manufacturing time.
E - UV-EPROM.  This comes in a windowed package and is eraseable with UV.
        This requires a sepcial high voltage supply to program.
F - Flash ROM.  This is electrically eraseable, 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, and .  But 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 second USART, hardware multiplier.
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: 100 pins, more LCD, ADC12, second timer, USART, second crystal
44x: 100 pins, like 43x but wth second USART and better 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 that the 161x numbers are an exception to the usual 4th digit rule.

Reply via email to