Small project to display some OBD values from the Toyota GT86/ Subaru BRZ/ Scion FRS on an OLED display.

Dependencies:   Adafruit_GFX MODSERIAL mbed-rtos mbed

Revision:
2:d3d61d9d323e
Parent:
1:ca506b88b1d6
Child:
3:eb807d330292
--- a/main.cpp	Tue Apr 22 15:32:49 2014 +0000
+++ b/main.cpp	Sun Apr 27 14:50:13 2014 +0000
@@ -1,11 +1,23 @@
 #include "mbed.h"
 #include "rtos.h"
 #include "IsoTpHandler.h"
+#include "MODSERIAL.h"
 
-Serial pc(USBTX, USBRX); // tx, rx 
+#define CAN1_TEST
+#define CAN1_OBD_CAR_SIMULATOR
+
+// Make TX buffer 1024bytes and RX buffer use 512bytes.
+MODSERIAL pc(USBTX, USBRX, 2 * 1024, 512); // tx, rx
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+CAN can1(p9, p10);
+DigitalOut can1_disable(p8);
 CAN can2(p30, p29);
+DigitalOut can2_disable(p28);
+
 IsoTpHandler tpHandler(&can2);
  
 void led2_thread(void const *args) {
@@ -19,41 +31,177 @@
 
 void can_process_packets(void const *args) {
     while (true) {
+        pc.printf("Th wait for can packet\r\n");
         osEvent evt = can_rx_queue.get(osWaitForever);
+        pc.printf("Got evt %d\r\n", evt.status);
         if (evt.status == osEventMail) {
+            pc.printf("Got can packet\r\n");
             CANMessage *msg = (CANMessage*) evt.value.p;
+            pc.printf("Process can packet\r\n");
             tpHandler.processCanMessage(msg);
+            pc.printf("Processed can packet\r\n");
             can_rx_queue.free(msg);
+            pc.printf("Freed can packet\r\n");
         }
     }
 }
 
  
 void can_rx_int_handler() {
+    //pc.printf("can_rx_int_handler\r\n");
     CANMessage* msg = can_rx_queue.alloc();
     if (!can2.read(*msg))
     {
+        //pc.printf("can_rx_int_handler no read\r\n");
         //this should not happen, because this function is called from the rx interrupt
         can_rx_queue.free(msg);
+        //pc.printf("can_rx_int_handler ret 1\r\n");
+        return;
+    }
+    if (msg->id != 0x7E8)
+    {
+        //no OBD message
+        can_rx_queue.free(msg);
         return;
     }
+    //pc.printf("can_rx_int_handler got packet\r\n");
+    osStatus error_code = can_rx_queue.put(msg);
+    //pc.printf("can_rx_int_handler in queue\r\n"); 
+    if (error_code != osOK) {
+        //pc.printf("can_rx_int_handler failed\r\n");
+        //error("Putting can message into mailbox failed with code %d!", error);
+    }
     
-    osStatus error_code = can_rx_queue.put(msg); 
-    if (error_code != osOK) {
-        error("Putting can message into mailbox failed with code %d!", error);
+    //pc.printf("can_rx_int_handler ok\r\n");
+}
+
+#ifdef CAN1_TEST
+Mail<CANMessage, 16> can1_rx_queue;
+CANMessage msg1;
+void can1_rx_int_handler() {
+    led3 = !led3;
+    CANMessage* msg = can1_rx_queue.alloc();
+    if (!can1.read(*msg))
+    {
+        can1_rx_queue.free(msg);
+        return;
+    }
+    can1_rx_queue.put(msg);
+    led4 = !led4;
+}
+
+
+#ifdef CAN1_OBD_CAR_SIMULATOR
+
+struct behaviour_t {
+    unsigned char rxData[8];
+    char txData[8];
+};
+
+behaviour_t behaviour[] = 
+{
+    {{0x02, 0x21, 0x01, 0, 0, 0, 0, 0}, {0x10, 0x1F, 0x61, 0x01, 0x51, 0, 0x37, 0x01}}, //first oil temp packet
+    {{0x30, 0, 0, 0, 0, 0, 0, 0}, {0x21, 0x1F, 0x61, 0x01, 0x51, 0, 0x37, 0x01}}, //second oil temp packet, TODO more pakets must be sent
+    {{0x02, 0x01, 0x21, 0, 0, 0, 0, 0}, {0x04, 0x41, 0x21, 0, 0, 0, 0, 0}},
+    {{0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}, {0x04, 0x41, 0x0C, 0x0F, 0xA2, 0, 0, 0}},
+    {{0x02, 0x01, 0x11, 0, 0, 0, 0, 0}, {0x03, 0x41, 0x11, 0x26, 0, 0, 0, 0}},
+    {{0x02, 0x01, 0x05, 0, 0, 0, 0, 0}, {0x03, 0x41, 0x05, 0x4D, 0, 0, 0, 0}},  //engine coolant temp
+};
+
+Mail<CANMessage, 16> can1_tx_queue;
+
+void can1_obd_car_simulator_process_packet(CANMessage &msg)
+{
+    if (msg.id != 0x7E0)
+    {
+        return;
+    }
+    
+    for (unsigned int i = 0; i < sizeof(behaviour) / sizeof (behaviour[0]); i++)
+    {
+        if (memcmp(msg.data, behaviour[i].rxData, 8) == 0)
+        {
+            CANMessage sendMsg(0x7E8, (char*) behaviour[i].txData, 8);
+            CANMessage* msg = can1_tx_queue.alloc();
+            *msg = sendMsg;
+            can1_tx_queue.put(msg);
+            
+            if (i == 1)
+            {
+                //send additinal packets later
+                sendMsg.data[0] = 0x22;
+                msg = can1_tx_queue.alloc();
+                *msg = sendMsg;
+                can1_tx_queue.put(msg);
+                sendMsg.data[0] = 0x23;
+                msg = can1_tx_queue.alloc();
+                *msg = sendMsg;
+                can1_tx_queue.put(msg);
+                sendMsg.data[0] = 0x24;
+                msg = can1_tx_queue.alloc();
+                *msg = sendMsg;
+                can1_tx_queue.put(msg);
+            }
+        }
     }
 }
 
+#endif //CAN1_OBD_CAR_SIMULATOR
+
+void can1_process_packets(void const *args) {
+    while (true) {
+        osEvent evt = can1_rx_queue.get(osWaitForever);
+        if (evt.status == osEventMail) {
+            CANMessage *msg = (CANMessage*) evt.value.p;
+            
+            pc.printf("\r\nRX1: '%d' '%d' '%d' '%x' '", msg->format, msg->type, msg->len, msg->id);
+            for (unsigned int i = 0; i < msg->len; i++)
+            {
+                pc.printf("%x ", msg->data[i]);
+            }
+            pc.printf("'\r\n");
+#ifdef CAN1_OBD_CAR_SIMULATOR
+            can1_obd_car_simulator_process_packet(*msg);
+#endif //CAN1_OBD_CAR_SIMULATOR            
+            can1_rx_queue.free(msg);
+        }
+    }
+}    
+
+void can1_send_packets(void const *args) {
+    pc.printf("TX1 start\r\n");
+    while (true) {
+        osEvent evt = can1_tx_queue.get(osWaitForever);
+        if (evt.status == osEventMail) {
+            CANMessage *msg = (CANMessage*) evt.value.p;
+            pc.printf("TX1 check\r\n");
+            if (can1.write(*msg))
+            {
+                pc.printf("TX1 send\r\n");
+                can1_tx_queue.free(msg);
+            }
+            else
+            {
+                pc.printf("TX1 wait \r\n");
+                Thread::wait(50);
+            }
+        }
+    }
+}    
+    
+#endif //CAN1_TEST
+
+char can_msg[8] = {0};
+CANMessage msg(0x7E0, can_msg, 8);
 void serial_int_handler() {
     if (!pc.readable()) {
         return;
     }
     uint8_t character = pc.getc();
-    printf("Received '%c'\n", character);
+    //pc.printf("Received '%c'\r\n", character);
     
-    char can_msg[8] = {0};
-    can_msg[0] = 0x02;  
-    can_msg[1] = 0x01;
+    msg.data[0] = 0x02;  
+    msg.data[1] = 0x01;
     char pid = 0;
     switch (character)
     {
@@ -64,31 +212,48 @@
             pid = 0x11; //throttle
             break;
         case '3': //oil 1
-            can_msg[1] = 0x21; //endian
+            msg.data[1] = 0x21; //endian
             pid = 1;
             break;
         case '4': //oil 2
-            can_msg[1] = 1; //endian
+            msg.data[1] = 1; //endian
             pid = 0x21;
             break;
         default:
             pid = 0x05; //engine coolant temp
     }
-    can_msg[2] = pid;
+    msg.data[2] = pid;
+    msg.len = 8;
     
-    printf("Can write %d\n", can2.write(CANMessage(0x7DF, can_msg, 8)));
+    //pc.printf("Sending message\r\n");
+    int result = can2.write(msg);  //or 0x7DF ?
+    //pc.printf("Can write %d\r\n", result);
+    //pc.printf("ret 1\r\n");
  }
  
 int main() {
-    pc.baud(115200);
-    pc.attach(serial_int_handler);
+    pc.baud(921600);
+    //pc.attach(&serial_int_handler);
+    can2_disable = 0;
     can2.frequency(500000);
+    //mbed can filter is not working? check it later
+    //can2.filter
     can2.attach(can_rx_int_handler);
     Thread thread(led2_thread);
     Thread can_thread(can_process_packets);
-    
+#ifdef CAN1_TEST
+    can1_disable = 0;
+    can1.frequency(500000);
+    can1.attach(&can1_rx_int_handler);
+    Thread can1_thread(can1_process_packets);
+    Thread can1_tx_thread(can1_send_packets);
+#endif //CAN1_TEST
+    pc.printf("Start\r\n");
     while (true) {
         led1 = !led1;
         Thread::wait(500);
+        if (pc.readable()) {
+            serial_int_handler();
+        }
     }
 }