Reading analog values on the msp430

I finally got all the components to use the bag of electret microphones I got last year. Using a LM36 audio amp I set up a simple circuit to read values from the microphone and set LED's corresponding to the value read.

I had trouble finding a solid example of doing analog reads in a loop for the msp430. This program, sets up LED's(On P1.1 and P1.6), sets up the ADC, then sits in a loop. If the value on the ADC is grater than 512 the LED will go red.

I tested this by shouting at the micro controller, something I have done many times before, but never with such satisfying results.

#include <msp430g2553.h>

unsigned int adcvalue = 0;

void configureADC(void);

int
main(void)
{
    WDTCTL = WDTPW + WDTHOLD;       //Stop the Watch dog

    P1DIR |= 0x41;                  //Enabled P1.0 and P1.6
    P1OUT = 0x41;

    BCSCTL1 = CALBC1_1MHZ;          //Set range
    BCSCTL2 &= CALBC1_1MHZ;         //SMCLK = DCO = 1MHz

    P1SEL |= BIT3;

    configureADC();
    __enable_interrupt();

    while(1) {
        __delay_cycles(20000);
        ADC10CTL0 |= ENC + ADC10SC;         //Sampling and conversion start
        adcvalue = ADC10MEM;                //Read from the ADC

        if(adcvalue > 512)
            P1OUT = 0x40;
        else
            P1OUT = 0x01;

    }

    return 0;
}

void
configureADC(void)
{
    ADC10CTL1 = INCH_3 + ADC10DIV_3;
    ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;
    ADC10AE0 |= BIT3;
}

Attaching a debugger to mspdebug

The cool thing we get with the msp430 and the Launchpad is on chip debugging. This goes a long way to pave over the warts of writing straight C for the 430. We will load up the blink program from last time , run it with the debugger and pause execution.

Start up mspdebug as before, this time we pass a command for mspdebug to run directly. The "gdb" command will cause mspdebug to listen on port 2000, gdb can then connect and control the debugger.

$ mspdebug rf2500 "gdb"

Next we are going to start up msp430-gdb, load the program from before and start it running.

$ msp430-gdb
(gdb) target remote localhost:2000
(gdb) file led.elf
(gdb) load led.elf
(gdb) continue
^C
(gdb) break main.c:14
(gdb) c                 #We can shorthand commands
Now between each continue we will see the LED's toggle, red then green.
(gdb) continue

From gdb we can send mspdebug directly with the monitor command.

Tech seen debugging bus sign

In Aberdeen we have digital displays mounted in most of the bus stops, in fact most major cities in the world probably have similar signs. The signs get their data via radio broadcasts, these broadcasts have in fact been captured before and reverse engineered.

For a long time I have been thinking about doing a similar thing and figuring out the bus information that is in the air. I am sure I will get to it one day.

Well this morning as I headed off to work I caught a technician in the act of debugging one of these signs. I grabbed a quick picture of the guy working, but I didn't want to bother him.

It looked like the tech was using a serial cable from his laptop up to the display. The antenna on the bus shelter looked much larger than the normal ones.

msp430 hello world

A couple of years ago the TI Launchpad made quite a splash when TI released the boards for just $5 each. The Launchpad uses the msp430 low power microcontroller from TI, these microcontrollers don't have the same pretty face as the avr microcontrollers in the AVR world.

This means the code is a little harder to read and write. It is a lot closer to assembly language than the high level Arduino C/C++. While it looks worse I find it more fun to write and it will leave you with a much better understanding of how the controller is working.

So lets load up a simple blinking light program(no more of that sketch nonesense), fire up the debugger and stop the code as it is executing. Grab the following code and make file and compile up the main.elf target. If you are using a different microcontroller then you should change the g2553 to the microcontroller you are using.

Blink Program

#include <msp430g2553.h>

int i = 0;
int j = 0;
int
main(void)
{
    WDTCTL = WDTPW + WDTHOLD;   //Stop the watch dog timer
    P1DIR |= 0x41;              //Set the direction bit of P1(0x01) as an output

    P1OUT = 0x40;               //Set P1.6 high, P1.0 low

    for(;;) {
        P1OUT ^= 0x41;          //Toggle both P1.1 and P1.6

        for(i = 0; i < 20000;i++){  //Loop for a while to block
            nop();
        }   
    }   
    return 0;
}

Makefile

CC=msp430-gcc
CFLAGS=-Os -Wall -g -mmcu=msp430g2231

OBJS=main.o

all: $(OBJS)
    $(CC) $(CFLAGS) -o main.elf $(OBJS)

%.o: %.c 
    $(CC) $(CFLAGS) -c $<

clean:
    rm -fr main.elf $(OBJS)

We use the mspdebug program to flash the program to the msp430 like so.

$ mspdebug -q rf2500
Trying to open interface 1 on 006
rf2500: warning: can't detach kernel driver: No data available
fet: FET returned error code 4 (Could not find device or device not supported)
fet: command C_IDENT1 failed
Device: MSP430G2xx3
fet: FET returned NAK
warning: device does not support power profiling
(mspdebug) prog main.elf
Erasing...
Programming...
Done, 152 bytes total
(mspdebug) run
Running. Press Ctrl+C to interrupt...
^C
    ( PC: 0c068)  ( R4: 0dff7)  ( R8: 0ffbb)  (R12: 0fdf7)  
    ( SP: 00400)  ( R5: 05a08)  ( R9: 0dcff)  (R13: 0fd67)  
    ( SR: 00004)  ( R6: 0b775)  (R10: 0dddf)  (R14: 0dfff)  
    ( R3: 00000)  ( R7: 0ff1f)  (R11: 0dfff)  (R15: 00000)  
main+0x2a:
    0c068: f9 3b                     JL      0xc05c
    0c06a: f2 3f                     JMP     0xc050
    0c06c: 32 d0 f0 00               BIS     #0x00f0, SR
    0c070: fd 3f                     JMP     0xc06c
    0c072: 30 40 76 c0               BR      #0xc076
    0c076: 00 13                     RETI    
(mspdebug) exit

There you have it, your first hello world on the msp430.

libnfc i2c usage

I have been working on applications using the SPI user space api. One of the devices I have been playing with is a PN523 NFC reader. The reader is supported by libnfc and can communicate using serial, SPI, i2c or usb depending on device support.

I wanted to get the nfc reader working over i2c, to form a baseline to compare it against SPI. I couldn't get the nfc-list to show any NFC devices connected to the Pi. I then tried to use the i2c -s command to scan the i2c bus, but instead of device detection the command threw an error.

It turns out that the iic driver for the Pi only supports one ioctl, I2CRDWR. That neuters most of the FreeBSD i2c tools as they use other ioctl's and error out on failure.

Learning that I looked at the Makefile for libnfc, this time realising that the i2c and the SPI device options are both commented out. I missed this the first time I looked at the FreeBSD port, there is still the option to use a serial device once I dig out a usb serial adapter.

It is looking a lot harder than I thought to get devices working with user space SPI on FreeBSD. It doesn't help that Linux has been the only operating system with user space SPI support for quite a long time.