a program i made a while back to log gps/accelerometer data

Dependencies:   FatFileSystem mbed

Files at this revision

API Documentation at this revision

Comitter:
Xach
Date:
Sat Sep 08 20:40:58 2012 +0000
Commit message:
a program i made a while back to log gps/accelerometer data

Changed in this revision

ACCEL_ADXL345.cpp Show annotated file Show diff for this revision Revisions of this file
ACCEL_ADXL345.h Show annotated file Show diff for this revision Revisions of this file
FATFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
GPS_LS20031.cpp Show annotated file Show diff for this revision Revisions of this file
GPS_LS20031.h Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.cpp Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.h Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.cpp Show annotated file Show diff for this revision Revisions of this file
SerialBuffered.h Show annotated file Show diff for this revision Revisions of this file
globals.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 82a02991476c ACCEL_ADXL345.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ACCEL_ADXL345.cpp	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,104 @@
+#include "ACCEL_ADXL345.h"
+#include "mbed.h"
+
+void accel_ISR() {
+    accelRdy = true;
+    accelTime = timer.read_us();
+    updateAccel();
+}
+
+void updateAccel() {
+  
+    __disable_irq();// if we are interrupted here i could mean we get accel data from 2 different samples
+    _cs = 0;
+    _spi.write(0xF2);   // Read X out reg and have it continue for 6 bytes
+    xraw0 =  _spi.write(0x0);
+    xraw1 =  _spi.write(0x0);
+    yraw0 =  _spi.write(0x0);
+    yraw1 =  _spi.write(0x0);
+    zraw0 =  _spi.write(0x0);
+    zraw1 =  _spi.write(0x0);
+    _cs = 1;
+    __enable_irq();
+    
+    //pc.printf(" X1=%i, X0=%i, Y1=%i, Y0=%i, Z1=%i, Z0=%i, \n",xraw1,xraw0,yraw1,yraw0,zraw1,zraw0);
+
+    //   pc.printf("%d %d %d",xaxis,yaxis,zaxis);
+}
+
+void convertAccel(){
+  xaxis = (float)(xraw0 | (xraw1 << 8))/250.0;//(((xraw1 & 0x01) | ((xraw1&0x01)<<3) )<< 8));
+  yaxis = (float)(yraw0 | (yraw1 << 8))/250.0;//(((yraw1 & 0x01) | ((yraw1&0x01)<<3) ) << 8));
+  zaxis = (float)(zraw0 | (zraw1 << 8))/250.0;//(((zraw1 & 0x01) | ((zraw1&0x01)<<3) ) << 8));
+
+}
+
+
+void initAccel() {
+
+    // Taken from datasheet
+    // 8 bit data
+    // High steady state clock
+    // Second edge capture
+    _spi.format(8,3);
+
+    // 5MHz clock rate
+    _spi.frequency(1000000);
+
+    // Select the device, active low chip select
+    _cs = 0;
+
+    _spi.write(0x31); // set data_format to 0b00000001 to turn on 4 wire mode with act high interrupts,10 bit mode and +- 4g operation
+    _spi.write(0x0B);
+    // end this transfer
+    _cs = 1;
+
+
+    wait (0.01); //this is stupid, get rid of it
+
+
+// new transfer
+    _cs = 0;
+
+    _spi.write(0x5D); // start writing at 0x1D but turn on sequential writes so we can set everything in one fowl swoop
+
+    _spi.write(0xFF);  // set THRESH_TAP - only used when corresponding interrupt is enabled
+    _spi.write(0x00); // set OFSX
+    _spi.write(0x00); // set OFSY
+    _spi.write(0x00); // set OFSZ
+    _spi.write(0xFF); // set DUR (min duration to be considered a TAP event)
+    _spi.write(0x00); // set Latent (max duration between TAP events)
+    _spi.write(0x00); // set Window (max time after a Latency to be in the same TAP window)
+    _spi.write(0x00); // set THRESH_ACT - only used when corresponding interrupt is enabled
+    _spi.write(0x00); // set THRESH_INACT - only used when corresponding interrupt is enabled
+    _spi.write(0xFF); // set TIME_INACT - only used when corresponding interrupt is enabled
+    _spi.write(0x00); // set ACT_INACT_CTL - AC/DC coupling for activity registers + enabling/disabling in x,y.z - only used when corresponding interrupt is enabled
+    _spi.write(0xFF); // set THRESH_FF (free fall) - only used when corresponding interrupt is enabled
+    _spi.write(0xFF); // set TIME_FF (free fall)
+    _spi.write(0x00); // set TAP_AXES (with 0x00 we are disabling all tap detection)
+    // end this transfer
+    _cs = 1;
+
+// start another multiple byte transfer
+    _cs = 0;
+    _spi.write(0x6C); // another sequential write starting at 0x2C
+    _spi.write(0x0E); // set BW_RATE to disable low power and turn on max bandwidth
+    _spi.write(0x0B); // set // set PWR_CTRL to start measurments, and not be asleep , and to do 8hz measurements if asleep
+    _spi.write(0x00); // set INT_ENABLE
+    _spi.write(0x00); // set INT_MAP - send all interrupts to INT1 but doesnt really matter because we wont use this (yet)
+    _cs = 1;
+
+    // start new transfer
+    _cs = 0;
+    _spi.write(0x38); // FIFO_CTL
+    _spi.write(0x00); // disable the FIFO
+    _cs = 1;
+
+    _cs = 0;
+    _spi.write(0x80);
+    wait(.1);
+    devid = _spi.write(0x0);
+    _cs  = 1;
+    accel.attach_us(&accel_ISR, 625);
+    accelRdy = false;
+}
diff -r 000000000000 -r 82a02991476c ACCEL_ADXL345.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ACCEL_ADXL345.h	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,19 @@
+
+#include"mbed.h"
+
+SPI _spi (p5,p6,p7);
+DigitalOut _cs (p8);
+
+void updateAccel();
+void convertAccel();
+void initAccel();
+void accel_ISR();
+volatile bool accelRdy;
+volatile int accelTime;
+unsigned char xraw0, yraw0, zraw0;
+signed char xraw1, yraw1, zraw1;
+float xaxis, yaxis,zaxis;
+unsigned char devid;
+Ticker accel;
+
+Timer timer;
diff -r 000000000000 -r 82a02991476c FATFileSystem.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FATFileSystem.lib	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_unsupported/code/FatFileSystem/#333d6e93e58f
diff -r 000000000000 -r 82a02991476c GPS_LS20031.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_LS20031.cpp	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,49 @@
+
+#include "GPS_LS20031.h"
+#include "mbed.h"
+
+
+
+char checkSum(char* theseChars) {
+    char check = 0;
+    // iterate over the string, XOR each byte with the total sum:
+
+    for (int c = 1;theseChars[c]!= '*'; c++) {
+        check = char(check ^ theseChars[c]);
+    }
+    // return the result
+    return check;
+}
+
+bool NMEA_parse(char *msg) {
+    char ns, ew,av;
+    float magVar;
+
+
+    // Check if it is a GPGGA msg (matches both locked and non-locked msg)
+    if (sscanf(msg, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%f", &timeG, &av, &latitude, &ns, &longitude, &ew, &speed_knotts, &magVar, &date) >= 1) {
+        if (av == 'A') {
+            if (ns == 'S') {
+                latitude  *= -1.0;
+            }
+            if (ew == 'W') {
+                longitude *= -1.0;
+            }
+            return true;
+            /*  float degrees = trunc(latitude / 100.0f);
+              float minutes = latitude - (degrees * 100.0f);
+              latitude = degrees + minutes / 60.0f;
+              degrees = trunc(longitude / 100.0f);  //a term had to be removed from this line
+              minutes = longitude - (degrees * 100.0f);
+              longitude = degrees + minutes / 60.0f;*/
+        }
+         else {
+            longitude = 0.0;
+            latitude = 0.0;
+            return false;
+        }
+
+    }
+    return false;
+
+}
\ No newline at end of file
diff -r 000000000000 -r 82a02991476c GPS_LS20031.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPS_LS20031.h	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,13 @@
+#pragma once
+#ifndef GPS_LS20031_H
+#define GPS_LS20031_H
+
+bool NMEA_parse(char* msg);
+char checkSum(char* theseChars);
+float date;
+float latitude;
+float longitude;
+float speed_knotts;
+float timeG;
+
+#endif
\ No newline at end of file
diff -r 000000000000 -r 82a02991476c SDFileSystem.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.cpp	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,295 @@
+/* mbed Microcontroller Library - SDFileSystem
+ * Copyright (c) 2008-2009, sford
+ *
+ * Introduction
+ * ------------
+ * SD and MMC cards support a number of interfaces, but common to them all
+ * is one based on SPI. This is the one I'm implmenting because it means
+ * it is much more portable even though not so performant, and we already 
+ * have the mbed SPI Interface!
+ *
+ * The main reference I'm using is Chapter 7, "SPI Mode" of: 
+ *  http://www.sdcard.org/developers/tech/sdcard/pls/Simplified_Physical_Layer_Spec.pdf
+ *
+ * SPI Startup
+ * -----------
+ * The SD card powers up in SD mode. The SPI interface mode is selected by
+ * asserting CS low and sending the reset command (CMD0). The card will 
+ * respond with a (R1) response.
+ *
+ * CMD8 is optionally sent to determine the voltage range supported, and 
+ * indirectly determine whether it is a version 1.x SD/non-SD card or 
+ * version 2.x. I'll just ignore this for now.
+ *
+ * ACMD41 is repeatedly issued to initialise the card, until "in idle"
+ * (bit 0) of the R1 response goes to '0', indicating it is initialised.
+ *
+ * You should also indicate whether the host supports High Capicity cards,
+ * and check whether the card is high capacity - i'll also ignore this
+ *
+ * SPI Protocol
+ * ------------
+ * The SD SPI protocol is based on transactions made up of 8-bit words, with
+ * the host starting every bus transaction by asserting the CS signal low. The
+ * card always responds to commands, data blocks and errors.
+ * 
+ * The protocol supports a CRC, but by default it is off (except for the 
+ * first reset CMD0, where the CRC can just be pre-calculated, and CMD8)
+ * I'll leave the CRC off I think! 
+ * 
+ * Standard capacity cards have variable data block sizes, whereas High 
+ * Capacity cards fix the size of data block to 512 bytes. I'll therefore
+ * just always use the Standard Capacity cards with a block size of 512 bytes.
+ * This is set with CMD16.
+ *
+ * You can read and write single blocks (CMD17, CMD25) or multiple blocks 
+ * (CMD18, CMD25). For simplicity, I'll just use single block accesses. When
+ * the card gets a read command, it responds with a response token, and then 
+ * a data token or an error.
+ * 
+ * SPI Command Format
+ * ------------------
+ * Commands are 6-bytes long, containing the command, 32-bit argument, and CRC.
+ *
+ * +---------------+------------+------------+-----------+----------+--------------+
+ * | 01 | cmd[5:0] | arg[31:24] | arg[23:16] | arg[15:8] | arg[7:0] | crc[6:0] | 1 |
+ * +---------------+------------+------------+-----------+----------+--------------+
+ *
+ * As I'm not using CRC, I can fix that byte to what is needed for CMD0 (0x95)
+ *
+ * All Application Specific commands shall be preceded with APP_CMD (CMD55).
+ *
+ * SPI Response Format
+ * -------------------
+ * The main response format (R1) is a status byte (normally zero). Key flags:
+ *  idle - 1 if the card is in an idle state/initialising 
+ *  cmd  - 1 if an illegal command code was detected
+ *
+ *    +-------------------------------------------------+
+ * R1 | 0 | arg | addr | seq | crc | cmd | erase | idle |
+ *    +-------------------------------------------------+
+ *
+ * R1b is the same, except it is followed by a busy signal (zeros) until
+ * the first non-zero byte when it is ready again.
+ *
+ * Data Response Token
+ * -------------------
+ * Every data block written to the card is acknowledged by a byte 
+ * response token
+ *
+ * +----------------------+
+ * | xxx | 0 | status | 1 |
+ * +----------------------+
+ *              010 - OK!
+ *              101 - CRC Error
+ *              110 - Write Error
+ *
+ * Single Block Read and Write
+ * ---------------------------
+ *
+ * Block transfers have a byte header, followed by the data, followed
+ * by a 16-bit CRC. In our case, the data will always be 512 bytes.
+ *  
+ * +------+---------+---------+- -  - -+---------+-----------+----------+
+ * | 0xFE | data[0] | data[1] |        | data[n] | crc[15:8] | crc[7:0] | 
+ * +------+---------+---------+- -  - -+---------+-----------+----------+
+ */
+ 
+#include "SDFileSystem.h"
+
+#define SD_COMMAND_TIMEOUT 5000
+
+SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name) :
+  FATFileSystem(name), _spi(mosi, miso, sclk), _cs(cs) {
+      _cs = 1; 
+}
+
+int SDFileSystem::disk_initialize() {
+
+    _spi.frequency(100000); // Set to 100kHz for initialisation
+    
+    // Initialise the card by clocking it a bit (cs = 1)
+    for(int i=0; i<16; i++) {   
+        _spi.write(0xFF);
+    }
+
+    // send CMD0, should return with all zeros except IDLE STATE set (bit 0)
+    if(_cmd(0, 0) != 0x01) { 
+        fprintf(stderr, "Not in idle state\n");
+        fprintf(stderr, "_cnd value = %i\n", _cmd(0,0));
+        return 1;
+    }
+    
+    // ACMD41 to give host capacity support (repeat until not busy)
+    // ACMD41 is application specific command, so we send APP_CMD (CMD55) beforehand
+    for(int i=0;; i++) {
+        _cmd(55, 0); 
+        int response = _cmd(41, 0);
+        if(response == 0) { 
+            break;
+        } else if(i > SD_COMMAND_TIMEOUT) {
+            fprintf(stderr, "Timeout waiting for card\n");
+            return 1;
+        }    
+    }
+
+    _sectors = _sd_sectors();
+
+    // Set block length to 512 (CMD16)
+    if(_cmd(16, 512) != 0) {
+        fprintf(stderr, "Set block timeout\n");
+        return 1;
+    }
+        
+    _spi.frequency(5000000); // Set to 1MHz for data transfer
+    return 0;
+}
+
+int SDFileSystem::disk_write(const char *buffer, int block_number) {
+    // set write address for single block (CMD24)
+    if(_cmd(24, block_number * 512) != 0) {
+        return 1;
+    }
+
+    // send the data block
+    _write(buffer, 512);    
+    return 0;    
+}
+
+int SDFileSystem::disk_read(char *buffer, int block_number) {        
+    // set read address for single block (CMD17)
+    if(_cmd(17, block_number * 512) != 0) {
+        return 1;
+    }
+    
+    // receive the data
+    _read(buffer, 512);
+    return 0;
+}
+
+int SDFileSystem::disk_status() { return 0; }
+int SDFileSystem::disk_sync() { return 0; }
+int SDFileSystem::disk_sectors() { return _sectors; }
+
+// PRIVATE FUNCTIONS
+
+int SDFileSystem::_cmd(int cmd, int arg) {
+    _cs = 0; 
+
+    // send a command
+    _spi.write(0x40 | cmd);
+    _spi.write(arg >> 24);
+    _spi.write(arg >> 16);
+    _spi.write(arg >> 8);
+    _spi.write(arg >> 0);
+    _spi.write(0x95);
+
+    // wait for the repsonse (response[7] == 0)
+    for(int i=0; i<SD_COMMAND_TIMEOUT; i++) {
+        int response = _spi.write(0xFF);
+        if(!(response & 0x80)) {
+            _cs = 1;
+            return response;
+        }
+    }
+    _cs = 1;
+    return -1; // timeout
+}
+
+int SDFileSystem::_read(char *buffer, int length) {
+    _cs = 0;
+
+    // read until start byte (0xFF)
+    while(_spi.write(0xFF) != 0xFE);
+
+    // read data
+    for(int i=0; i<length; i++) {
+        buffer[i] = _spi.write(0xFF);
+    }
+    _spi.write(0xFF); // checksum
+    _spi.write(0xFF);
+
+    _cs = 1;    
+    return 0;
+}
+
+int SDFileSystem::_write(const char *buffer, int length) {
+    _cs = 0;
+    
+    // indicate start of block
+    _spi.write(0xFE);
+    
+    // write the data
+    for(int i=0; i<length; i++) {
+        _spi.write(buffer[i]);
+    }
+    
+    // write the checksum
+    _spi.write(0xFF); 
+    _spi.write(0xFF);
+
+    // check the repsonse token
+    if((_spi.write(0xFF) & 0x1F) != 0x05) {
+        _cs = 1; 
+        return 1;
+    }
+
+    // wait for write to finish
+    while(_spi.write(0xFF) == 0);
+
+    _cs = 1; 
+    return 0;
+}
+
+static int ext_bits(char *data, int msb, int lsb) {
+    int bits = 0;
+    int size = 1 + msb - lsb; 
+    for(int i=0; i<size; i++) {
+        int position = lsb + i;
+        int byte = 15 - (position >> 3);
+        int bit = position & 0x7;
+        int value = (data[byte] >> bit) & 1;
+        bits |= value << i;
+    }
+    return bits;
+}
+
+int SDFileSystem::_sd_sectors() {
+
+    // CMD9, Response R2 (R1 byte + 16-byte block read)
+    if(_cmd(9, 0) != 0) {
+        fprintf(stderr, "Didn't get a response from the disk\n");
+        return 0;
+    }
+    
+    char csd[16];    
+    if(_read(csd, 16) != 0) {
+        fprintf(stderr, "Couldn't read csd response from disk\n");
+        return 0;
+    }
+
+    // csd_structure : csd[127:126]
+    // c_size        : csd[73:62]
+    // c_size_mult   : csd[49:47]
+    // read_bl_len   : csd[83:80] 
+
+    int csd_structure = ext_bits(csd, 127, 126);
+    int c_size = ext_bits(csd, 73, 62);
+    int c_size_mult = ext_bits(csd, 49, 47);
+    int read_bl_len = ext_bits(csd, 83, 80);
+    
+    if(csd_structure != 0) {
+        fprintf(stderr, "This disk tastes funny! I only know about type 0 CSD structures");
+        return 0;
+    }
+                            
+    int blocks = (c_size + 1) * (1 << (c_size_mult + 2));
+    int block_size = 1 << read_bl_len;
+
+    if(block_size != 512) {
+        fprintf(stderr, "This disk tastes funny! I only like 512-byte blocks");
+        return 0;
+    }
+    
+    return blocks;
+}
diff -r 000000000000 -r 82a02991476c SDFileSystem.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.h	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,56 @@
+/* mbed Microcontroller Library - SDFileSystem
+ * Copyright (c) 2008-2009, sford
+ */
+
+#ifndef SDFILESYSTEM_H
+#define SDFILESYSTEM_H
+
+#include "mbed.h"
+#include "FATFileSystem.h"
+
+/* Class: SDFileSystem
+ *  Access the filesystem on an SD Card using SPI
+ *
+ * Example:
+ * > SDFileSystem sd(p5, p6, p7, p12, "sd");
+ * > 
+ * > int main() {
+ * >     FILE *fp = fopen("/sd/myfile.txt", "w");
+ * >     fprintf(fp, "Hello World!\n");
+ * >     fclose(fp);
+ * > }
+ */
+class SDFileSystem : public FATFileSystem {
+public:
+
+	/* Constructor: SDFileSystem
+	 *  Create the File System for accessing an SD Card using SPI
+	 *
+	 * Variables:
+	 *  mosi - SPI mosi pin connected to SD Card
+	 *  miso - SPI miso pin conencted to SD Card
+	 *  sclk - SPI sclk pin connected to SD Card
+	 *  cs   - DigitalOut pin used as SD Card chip select
+   *  name - The name used to access the filesystem
+	 */
+	SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name);
+	virtual int disk_initialize();
+	virtual int disk_write(const char *buffer, int block_number);
+	virtual int disk_read(char *buffer, int block_number);	
+	virtual int disk_status();
+	virtual int disk_sync();
+	virtual int disk_sectors();
+
+protected:
+
+	int _cmd(int cmd, int arg);
+	int _read(char *buffer, int length);
+	int _write(const char *buffer, int length);
+	int _sd_sectors();
+	int _sectors;
+	
+	SPI _spi;
+	DigitalOut _cs;	 
+};
+
+#endif
diff -r 000000000000 -r 82a02991476c SerialBuffered.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.cpp	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,155 @@
+
+#include "mbed.h"
+#include "SerialBuffered.h"
+#include <string.h>
+
+//extern Serial loggerSerial;
+
+SerialBuffered::SerialBuffered( size_t bufferSize, PinName tx, PinName rx ) : Serial(  tx,  rx ) {
+    m_buffSize = 0;
+    m_contentStart = 0;
+    m_contentEnd = 0;
+    m_timeout = 1.0;
+    ReadStrings = false;
+    unreadStrings = 0;
+
+    attach( this, &SerialBuffered::handleInterrupt );
+
+    m_buff = (uint8_t *) malloc( bufferSize );
+    if ( m_buff == NULL ) {
+        //loggerSerial.printf("SerialBuffered - failed to alloc buffer size %d\r\n", (int) bufferSize );
+    } else {
+        m_buffSize = bufferSize;
+    }
+}
+
+
+SerialBuffered::~SerialBuffered() {
+    if ( m_buff )
+        free( m_buff );
+    if (str_buff);
+    free(str_buff);
+}
+
+
+void SerialBuffered::setTimeout( float seconds ) {
+    m_timeout = seconds;
+}
+////////////////////
+void SerialBuffered::startReadStrings( char endChar) {
+    term = endChar;
+    str_buff_pos = 0;
+    str_wr_buff_pos = 0;
+    int i;
+    for (i = 0; i < STRING_BUFFERS; i++)
+        str_buff[i] = (char *) malloc(m_buffSize);
+
+    ReadStrings = true;
+}
+
+void SerialBuffered::stopReadStrings() {
+    ReadStrings = false;
+
+}
+
+int SerialBuffered::stringsAvailable() {
+    if (unreadStrings < STRING_BUFFERS)
+        return unreadStrings;
+    else
+        return -1;
+}
+
+char* SerialBuffered::getString() {
+    unreadStrings--;
+    if (str_buff_pos >= STRING_BUFFERS)
+        str_buff_pos = 0;
+
+    return str_buff[str_buff_pos++];
+}
+//////////////////////////////////////////
+
+size_t SerialBuffered::readBytes( uint8_t *bytes, size_t requested ) {
+    int i = 0;
+
+    for ( ; i < requested; ) {
+        int c = getc();
+        if ( c < 0 )
+            break;
+        bytes[i] = c;
+        i++;
+    }
+
+    return i;
+
+}
+
+
+
+
+
+int SerialBuffered::getc() {
+    m_timer.reset();
+    m_timer.start();
+    while ( m_contentStart == m_contentEnd ) {
+
+
+        wait_ms( 1 );
+        if ( m_timeout > 0 &&  m_timer.read() > m_timeout )
+            return EOF;
+    }
+
+    m_timer.stop();
+
+    uint8_t result = m_buff[m_contentStart++];
+    m_contentStart =  m_contentStart % m_buffSize;
+
+
+    return result;
+}
+
+
+int SerialBuffered::readable() {
+    return m_contentStart != m_contentEnd ;
+}
+
+
+
+
+//isr
+void SerialBuffered::handleInterrupt() {
+    if (ReadStrings) {
+
+        str_buff[str_wr_buff_pos][ m_contentEnd ] = Serial::getc();
+        if (str_buff[str_wr_buff_pos][ m_contentEnd ] == term) {
+            str_buff[str_wr_buff_pos][ m_contentEnd + 1 ] = '\0';
+            unreadStrings++;
+            str_wr_buff_pos++;
+            m_contentEnd = 0;
+            
+            if (str_wr_buff_pos >= STRING_BUFFERS)
+                str_wr_buff_pos = 0;
+            if (unreadStrings >= STRING_BUFFERS)
+                unreadStrings = 0;
+        } else {
+            m_contentEnd = ++m_contentEnd % m_buffSize;
+        }
+
+
+    } else {
+        while ( Serial::readable()) {
+            if ( m_contentStart == (m_contentEnd +1) % m_buffSize) {
+                //         loggerSerial.printf("SerialBuffered - buffer overrun, data lost!\r\n" );
+                Serial::getc();
+
+            } else {
+
+                m_buff[ m_contentEnd ++ ] = Serial::getc();
+                m_contentEnd = m_contentEnd % m_buffSize;
+
+
+
+            }
+        }
+    }
+}
+
diff -r 000000000000 -r 82a02991476c SerialBuffered.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SerialBuffered.h	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,52 @@
+#pragma once
+
+// This is a buffered serial reading class, using the serial interrupt introduced in mbed library version 18 on 17/11/09
+
+// In the simplest case, construct it with a buffer size at least equal to the largest message you
+// expect your program to receive in one go.
+#define STRING_BUFFERS 24
+
+class SerialBuffered : public Serial {
+public:
+    SerialBuffered( size_t bufferSize, PinName tx, PinName rx );
+    virtual ~SerialBuffered();
+
+    int getc();     // will block till the next character turns up, or return -1 if there is a timeout
+
+    int readable(); // returns 1 if there is a character available to read, 0 otherwise
+
+    int strReady(); // returns the number of strings ready
+
+
+
+
+    void setTimeout( float seconds );    // maximum time in seconds that getc() should block
+    // while waiting for a character
+    // Pass -1 to disable the timeout.
+
+    size_t readBytes( uint8_t *bytes, size_t requested );    // read requested bytes into a buffer,
+    // return number actually read,
+    // which may be less than requested if there has been a timeout
+    
+    void startReadStrings( char term);
+    void stopReadStrings();
+    char* getString();
+    int stringsAvailable();
+private:
+
+    void handleInterrupt();
+
+
+    uint8_t *m_buff;            // points at a circular buffer, containing data from m_contentStart, for m_contentSize bytes, wrapping when you get to the end
+    uint16_t  m_contentStart;   // index of first bytes of content
+    uint16_t  m_contentEnd;     // index of bytes after last byte of content
+    uint16_t m_buffSize;
+    float m_timeout;
+    Timer m_timer;
+    int unreadStrings;
+    char term;
+    bool ReadStrings;
+    char *str_buff[STRING_BUFFERS];
+    int str_buff_pos;
+    int str_wr_buff_pos;
+};
\ No newline at end of file
diff -r 000000000000 -r 82a02991476c globals.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/globals.h	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,25 @@
+#ifndef GLOBALS_H // header guards
+#define GLOBALS_H
+
+extern void updateAccel();
+extern void initAccel();
+extern void convertAccel();
+extern Timer timer;
+
+extern unsigned char xraw0, yraw0, zraw0;
+extern signed char xraw1, yraw1, zraw1;
+extern float xaxis, yaxis,zaxis;
+extern unsigned char devid;
+extern volatile bool accelRdy;
+extern volatile int accelTime;
+
+extern bool NMEA_parse(char* msg);
+extern char checkSum(char* theseChars);
+extern float date;
+extern float latitude;
+extern float longitude;
+extern float speed_knotts;
+extern float timeG;
+
+
+#endif
diff -r 000000000000 -r 82a02991476c main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,188 @@
+#include "mbed.h"
+#include "SerialBuffered.h"
+#include "globals.h"
+#include "SDFileSystem.h"
+#include "string.h"
+
+#define SDWrite(STR) ((fp == NULL) ? fprintf(fp, STR) : errorled=1)
+
+PwmOut Red(p25);
+PwmOut Green(p23);
+PwmOut Blue(p21);
+
+
+SDFileSystem sd(p11, p12, p13, p10, "sd");
+DigitalOut myled(LED1);
+DigitalOut genled(LED2);
+DigitalOut errorled(LED3);
+DigitalOut successled(LED4);
+Serial pc (USBTX,USBRX);
+//FILE *fp = fopen("/sd/foo.txt", "w");
+
+
+
+
+int main() {
+    Red.period_us(100);
+    Green.period_us(100);
+    Blue.period_us(100);
+    Red = 0;
+    Green = 0;
+    Blue = 0;
+
+    int flushCount = 0;
+    int fileStartTime = 0;
+
+    errorled = 0;
+    initAccel();
+
+    while (devid == 0) {
+        initAccel();
+        pc.printf("devid=%u\n",devid);
+    }
+    pc.printf("devid=%u\n",devid);
+    fp = fopen("/sd/clbr.txt", "a");
+    int j = 0;
+    while (j<6400) {
+        if (accelRdy) {
+            accelRdy = false;
+
+            convertAccel;
+            j++;
+        }
+    }
+    pc.printf("NMEA data from LS20031:\n");
+    char * pva_sent = (char *)calloc(255, sizeof(char));
+    char * titlePath = (char *)calloc(255, sizeof(char));
+
+    SerialBuffered *b = new SerialBuffered( 256, p28, p27);
+    b->baud( 56000 );
+    //only need to do this once to set up rmc
+    //   char setup[] = "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*%x\r\n";
+    // pc.printf("checksum : %x", checkSum(setup));
+    // b->printf(setup, checkSum(setup));
+
+    b->startReadStrings('\n');
+    b->setTimeout( 0.1 );//stupid , shouldnt need this
+    char* line[32];
+
+    myled = 1;
+    genled = 1;
+
+    while (b->stringsAvailable()<=0); // we need to wait for gps string
+    char * firstMsg = b->getString();
+    while (!NMEA_parse(firstMsg)) {
+
+        if (b->stringsAvailable()>0)
+            firstMsg = b->getString();
+    }
+    while (b->stringsAvailable()>0) {
+        firstMsg = b->getString();
+        NMEA_parse(firstMsg);
+    }
+
+    myled = 0;
+    genled = 0;
+
+    fileStartTime = (int)timeG/10000;
+    sprintf (titlePath, "/sd/%i_%i.txt",(int)date/10000 , (int)timeG/10000);
+    pc.printf(titlePath);
+    FILE *fp = fopen(titlePath, "a");
+
+    while (fp == NULL) {
+        wait (1);
+        errorled = 1;
+        successled = 1;
+        genled = 1;
+        myled = 1;
+        wait(1);
+        errorled = 0;
+        successled = 0;
+        genled = 0;
+        myled = 0;
+        if (b->stringsAvailable()>0) {
+            firstMsg = b->getString();
+            NMEA_parse(firstMsg);
+        }
+        fileStartTime = (int)timeG/10000;
+        sprintf (titlePath, "/sd/%i_%i.txt",(int)date/10000 , (int)timeG/10000);
+        fp = fopen(titlePath, "a");
+    }
+
+    pc.printf(titlePath);
+    fprintf(fp,"break,\n");
+
+    timer.start();
+    while (1) {
+        if (accelRdy) {
+            accelRdy = false;
+            convertAccel();
+            sprintf (pva_sent,"A,%i,%f,%f,%f\n",accelTime,xaxis,yaxis,zaxis);
+            // sprintf (pva_sent,"%f,%f,%f\n", xaxis,yaxis,zaxis);
+            // pc.printf(pva_sent);
+            fprintf(fp,pva_sent);
+            Red = abs(yaxis);
+            Blue = abs(zaxis);
+            Green = abs(xaxis);
+            successled = 1;
+        }
+
+        int i= 0;
+        while (b->stringsAvailable()>0) {
+            updateAccel();
+            timer.reset();
+            if (i<STRING_BUFFERS)
+                line[i++] = b->getString();
+            else
+                break;
+        }
+
+        //    pc.printf("\n\navailable:%i\n", i); //if i>1 it would be a good idea to throw an error
+
+        while (i>=1) {
+            flushCount++;
+            if (flushCount > 150) {
+
+                flushCount = 0;
+                fclose(fp);
+
+                if (fileStartTime - (int)timeG/10000 != 0) {
+                    fileStartTime = (int)timeG/10000;
+                    if (date != 0)
+                        sprintf (titlePath, "/sd/%i_%i.txt",(int)date/10000 , (int)timeG/10000);
+                }
+                fp = fopen(titlePath, "a");
+                while (fp == NULL) {
+                    wait (1);
+                    errorled = 1;
+                    successled = 1;
+                    genled = 1;
+                    myled = 1;
+                    wait(1);
+                    errorled = 0;
+                    successled = 0;
+                    genled = 0;
+                    myled = 0;
+
+                    fp = fopen(titlePath, "a");
+                }
+
+            }
+            NMEA_parse(line[--i]);
+
+            //sprintf (pva_sent,"\ngot line:%i\nDate:%f Time:%f Lat:%f Lon:%f Speed:%f Ax:%f Ay:%f Az:%f", i ,date,timeG,latitude,longitude,speed_knotts,xaxis,yaxis,zaxis);
+            sprintf (pva_sent,"G,%i,%f,%f,%f,%f,%f,%f,%f\n",(int)date,timeG,latitude,longitude,speed_knotts,xaxis,yaxis,zaxis);
+            //  pc.printf(pva_sent);
+            successled = 1;
+            fprintf(fp,pva_sent);
+            successled = 0;
+            //pc.printf("A X=%f, Y=%f, Z=%f\n",xaxis,yaxis,zaxis);
+
+        }
+
+
+    }
+}
+
+
+
diff -r 000000000000 -r 82a02991476c mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Sat Sep 08 20:40:58 2012 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0
\ No newline at end of file