vehicle CAN message log to SD file system using ring buffer memory

Dependencies:   SDFileSystem mbed

Files at this revision

API Documentation at this revision

Comitter:
ym1784
Date:
Fri Jan 25 21:04:19 2013 +0000
Child:
1:4a538cae9042
Commit message:
initial version

Changed in this revision

SDFileSystem.lib 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Fri Jan 25 21:04:19 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/SDFileSystem/#c8f66dc765d4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Jan 25 21:04:19 2013 +0000
@@ -0,0 +1,161 @@
+// CAN message log to SD card using can2.attach with ring buffer
+// 2013/Jan/25 using official SDFileSyatem library
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+
+CAN can2(p30, p29);
+CANMessage can_MsgRx;
+Timer timer;
+
+// LED to know the status
+DigitalOut User_Led1(LED1);
+DigitalOut User_Led2(LED2);
+DigitalOut User_Led3(LED3);
+DigitalOut User_Led4(LED4);
+#define LED_ON 1
+#define LED_OFF 0
+
+// status monitor
+Serial pc(USBTX, USBRX); 
+
+SDFileSystem sd(p5, p6, p7, p8, "sd"); // mosi, miso, sclk, cs, name
+FILE *fp;
+int file_open = 0;
+
+// button switch for closing file
+DigitalIn button1(p16);
+DigitalIn button2(p17);
+DigitalIn button3(p18);
+DigitalIn button4(p19);
+int SW0 = 0x0f, SW1 = 0x0f, SW2 = 0x0f, BUTTON = 0;
+Ticker sw_check;
+
+// function prototypes
+void can_check(void);
+void check_sw();
+
+// CAN message buffer
+#define BUFFER_SIZE 512  // buffer size must be power of 2
+#define BUFFER_MASK ( BUFFER_SIZE - 1 )
+unsigned int second[BUFFER_SIZE];
+unsigned short can_id[BUFFER_SIZE];
+unsigned char msg_length[BUFFER_SIZE];
+unsigned char data[8][BUFFER_SIZE];
+volatile unsigned int head = 0;
+volatile unsigned int tail = 0;
+
+int main()
+{
+    button1.mode(PullUp);
+    button2.mode(PullUp);
+    button3.mode(PullUp);
+    button4.mode(PullUp);
+    sw_check.attach_us(&check_sw, 5000);    // status check every 5 msec
+
+    can2.frequency(500000);
+    pc.baud(9600);
+    pc.printf("CAN log to SD card using ring buffer, 9600 bps\r\n");
+
+    User_Led1 = LED_OFF;
+    User_Led2 = LED_OFF;
+    User_Led3 = LED_OFF;
+    User_Led4 = LED_OFF;
+
+    char file_name[20];
+
+    time_t t;
+    t = time( NULL ) + 32400;  // UTC + 9 hours for JST
+    strftime( file_name, 20, "/sd/%y%m%d%H%M.log", localtime( &t ) );
+    pc.printf( "log file is %s\r\n", file_name );
+
+    fp = fopen(file_name, "w");
+    if ( fp == NULL ) {
+        pc.printf("Unable to create the file '%s'\r\n", file_name);
+        pc.printf("Please try again\r\n");
+
+        User_Led1 = LED_OFF;
+        file_open = 0;
+    } else {
+        User_Led1 = LED_ON;
+        file_open = 1;
+    }
+
+    timer.stop();
+    timer.reset();
+    timer.start();
+    can2.attach(&can_check);
+
+    int tmptail;
+    while(1) {
+        if ( head != tail ) {
+            tmptail = (tail + 1) & BUFFER_MASK;
+            fprintf(fp, "%03X,%03X,", head&0xfff, tmptail&0xfff);
+            fprintf(fp, "%08X,", second[tmptail]);
+            fprintf(fp, "t%03X%d", can_id[tmptail], msg_length[tmptail]);
+
+            for (int i=0; i<msg_length[tmptail]; i++) {
+                fprintf(fp, "%02X", data[i][tmptail]);
+            } // for
+            fprintf(fp, "\r\n");
+
+            tail = tmptail; // update tail after data sent
+            if ( tail == 0 ) {
+                // toggle led3
+                User_Led3 = !User_Led3;
+                t = time( NULL ) + 32400;  // UTC + 9 hours for JST
+                strftime( file_name, 20, "%T", localtime( &t ) );
+                pc.printf("new cycle of ring buffer at %s\r\n", file_name);
+            }
+        } // if head != tail
+
+        if ( BUTTON&0x01 ) {    // button1 pressed
+            BUTTON &= 0xfe;     // clear button status
+            can2.attach(0);     // detach CAN interrupt
+            file_open = 0;
+            //Close the file
+            fclose(fp);
+            pc.printf("file closed\r\n");
+            User_Led1 = LED_OFF;
+        } // if button
+    } // while
+} // main
+
+// read CAN2 message using intterupt and ring buffer
+void can_check(void) {
+    int temp_head;
+    if ( file_open == 1 ) {
+        while ( can2.read(can_MsgRx) ) {
+            temp_head = (head + 1) & BUFFER_MASK;
+            if ( temp_head == tail ) {          // buffer overflow error
+                fclose(fp);
+                fprintf(stderr, "buffer overflow\r\n");
+                fprintf(stderr, "head = %d\r\n", head);
+                fprintf(stderr, "tail = %d\r\n", tail);
+                User_Led4 = 1;
+                exit(1);
+            } // if
+
+            second[temp_head] = timer.read_us();
+            can_id[temp_head] = can_MsgRx.id & 0xFFF;
+            msg_length[temp_head] = can_MsgRx.len;
+            for (int i=0; i<can_MsgRx.len; i++) {
+                data[i][temp_head] = can_MsgRx.data[i];
+            } // for
+            head = temp_head;   // update head after data stored
+            // toggle led2
+            User_Led2 = !User_Led2;
+        } // while
+    } // if open
+} // can_check
+
+// read switch status, called every 5 msec
+void check_sw() {
+    SW2 = SW1;      // shift previous status
+    SW1 = SW0;      // shift previous status
+// get new status
+    SW0 = button1.read()+(button2.read()<<1)+(button3.read()<<2)+(button4.read()<<3);
+// following sequence detects switch press edge
+// HIGH(SW2) -> LOW(SW1) -> LOW(SW0)
+    BUTTON |= ((~(SW0|SW1))&SW2);   // update button status
+} // check_sw
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Jan 25 21:04:19 2013 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/0954ebd79f59
\ No newline at end of file