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

Files at this revision

API Documentation at this revision

Comitter:
chrta
Date:
Sun Apr 27 14:50:13 2014 +0000
Parent:
1:ca506b88b1d6
Child:
3:eb807d330292
Commit message:
Hardware is working

Changed in this revision

IsoTpHandler.cpp Show annotated file Show diff for this revision Revisions of this file
MODSERIAL.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
--- a/IsoTpHandler.cpp	Tue Apr 22 15:32:49 2014 +0000
+++ b/IsoTpHandler.cpp	Sun Apr 27 14:50:13 2014 +0000
@@ -1,4 +1,6 @@
 #include "IsoTpHandler.h"
+#include "MODSERIAL.h"
+extern MODSERIAL pc;
 
 enum IsoTpMessageType
 {
@@ -34,7 +36,7 @@
         uint8_t messageSize = message->data[0] & 0x0F;
         if (messageSize > message->len - 1)
         {
-            printf("Iso tp message is too short: iso len %d vs can len %d\n", messageSize, message->len);
+            pc.printf("Iso tp message is too short: iso len %d vs can len %d\r\n", messageSize, message->len);
             return;
         }
         context->handle_decoded_packet(&message->data[1], messageSize);
@@ -44,7 +46,7 @@
     {
         if (message->len != 8)
         {
-            printf("Invalid iso tp message length for FIRST_FRAME, length is %d\n", message->len);
+            pc.printf("Invalid iso tp message length for FIRST_FRAME, length is %d\r\n", message->len);
             return;
         }
         
@@ -55,16 +57,16 @@
     }
     if (messageType == CONSECUTIVE_FRAME)
     {
-        printf("Invalid iso tp message in idle state, because unexpected CONSECUTIVE_FRAME received\n");
+        pc.printf("Invalid iso tp message in idle state, because unexpected CONSECUTIVE_FRAME received\r\n");
         return;
     }
     if (messageType == FLOW_CONTOL_FRAME)
     {
-        printf("Invalid iso tp message, because unexpected FLOW_CONTOL_FRAME received\n");
+        pc.printf("Invalid iso tp message, because unexpected FLOW_CONTOL_FRAME received\r\n");
         return;
     }
     
-    printf("Invalid iso tp message ?!\n");
+    pc.printf("Invalid iso tp message ?!\r\n");
 }
 
 void IsoTpHandler::IdleState::onEnter(IsoTpHandler* context) const
@@ -88,12 +90,12 @@
     uint8_t messageType = message->data[0] >> 4;
     if (messageType == SINGLE_FRAME)
     {
-            printf("Received SINGLE_FRAME, expected consequitve frame\n");
+            pc.printf("Received SINGLE_FRAME, expected consequitve frame\r\n");
             return;
     }
     if (messageType == FIRST_FRAME)
     {
-        printf("Received FIRST_FRAME, expected consequitve frame\n");
+        pc.printf("Received FIRST_FRAME, expected consequitve frame\r\n");
         return;
     }
     if (messageType == CONSECUTIVE_FRAME)
@@ -101,7 +103,7 @@
         uint8_t index = message->data[0] & 0x0F;
         if (index != context->getExpectedIndex())
         {
-            printf("In consequiive frame, received index %d, expected %d\n", index, context->getExpectedIndex());
+            pc.printf("In consequiive frame, received index %d, expected %d\r\n", index, context->getExpectedIndex());
             context->setState(&IsoTpHandler::idleState);
             return;
     
@@ -109,19 +111,20 @@
         
         if (context->appendReceivedData(&message->data[1], message->len - 1))
         {
-            printf("In consequtive frame, change state\n");
+            pc.printf("In consequtive frame, change state\r\n");
             
             context->setState(&IsoTpHandler::idleState);
         }
+        context->incrementExpectedIndex();
         return;
     }
     if (messageType == FLOW_CONTOL_FRAME)
     {
-        printf("Received FLOW_CONTROL_FRAME, expected consequitve frame\n");
+        pc.printf("Received FLOW_CONTROL_FRAME, expected consequitve frame\r\n");
         return;
     }
     
-    printf("Invalid iso tp message, expected consequitve frame ?!\n");
+    pc.printf("Invalid iso tp message, expected consequitve frame ?!\r\n");
 }
 
 void IsoTpHandler::ConsequtiveTransferState::onEnter(IsoTpHandler* context) const
@@ -141,34 +144,34 @@
 
 void IsoTpHandler::processCanMessage(const CANMessage* message)
 {
-    printf("Received new CAN message:\n");
-    printf(" ID: 0x%X\n", message->id);
-    printf(" Len: %d\n", message->len);
-    printf(" Type: %s\n", (message->type == CANData ? "data" : "remote"));
-    printf(" Format: %s\n", (message->format == CANStandard ? "standard" : "extended"));
-    printf( "Data: ");
+    pc.printf("Received new CAN message:\r\n");
+    pc.printf(" ID: 0x%X\r\n", message->id);
+    pc.printf(" Len: %d\r\n", message->len);
+    pc.printf(" Type: %s\r\n", (message->type == CANData ? "data" : "remote"));
+    pc.printf(" Format: %s\r\n", (message->format == CANStandard ? "standard" : "extended"));
+    pc.printf( "Data: ");
     if (message->len > 8) {
         //paranoia
         error(" WRONG DATA LEN! ");
         return;
     }
     for (unsigned int i = 0; i < message->len; ++i) {
-        printf("%X ", message->data[i]);
+        pc.printf("%X ", message->data[i]);
     }
-    printf("\n");
+    pc.printf("\r\n");
     m_state->processInput(message, this);
 }
 
 void IsoTpHandler::handle_decoded_packet(const uint8_t* data, uint16_t length)
 {
     //todo write into mailbox so another thread can consume this or directly call a callback
-    printf("New decoded packet: Length: %d\n", length);
-    printf(" Data: ");
+    pc.printf("New decoded packet: Length: %d\r\n", length);
+    pc.printf(" Data: ");
     for (uint16_t i = 0; i < length; ++i)
     {
-        printf("%X ", data[i]);
+        pc.printf("%X ", data[i]);
     }
-    printf("\n");
+    pc.printf("\r\n");
 }
 
 void IsoTpHandler::init_consequtive_reading(uint16_t messageSize, const uint8_t* data)
@@ -184,7 +187,7 @@
     msgContent[5] = 0;
     msgContent[6] = 0;
     msgContent[7] = 0;
-    m_canInterface->write(CANMessage(0x7DF, msgContent, sizeof(msgContent)));
+    m_canInterface->write(CANMessage(0x7E0, msgContent, sizeof(msgContent)));  //or 7DF?
     
     memcpy(m_messageBuffer, data, 6);
     m_expectedMessageSize = messageSize;
@@ -208,13 +211,13 @@
 {
     if (message->len < 1)
     {
-        printf("Invalid iso tp message, length is zero\n");
+        pc.printf("Invalid iso tp message, length is zero\r\n");
         return false;
     } 
     uint8_t messageType = message->data[0] >> 4;
     if (messageType > FLOW_CONTOL_FRAME)
     {
-        printf("Invalid iso tp message type %d\n", messageType);
+        pc.printf("Invalid iso tp message type %d\r\n", messageType);
         return false;
     }
     return true;
@@ -238,13 +241,13 @@
 {
     if (sizeof(m_messageBuffer) < m_currentMessageSize + length)
     {
-        printf("Buffer in appendReceivedData too small, already got %d bytes, new %d bytes, expected %d bytes.\n", m_currentMessageSize, length, m_expectedMessageSize);
+        pc.printf("Buffer in appendReceivedData too small, already got %d bytes, new %d bytes, expected %d bytes.\r\n", m_currentMessageSize, length, m_expectedMessageSize);
         return true; //switch state
     }
     
     if (m_expectedMessageSize < m_currentMessageSize + length)
     {
-        printf("Got too much data in appendReceivedData, already got %d bytes, new %d bytes, expected %d bytes.\n", m_currentMessageSize, length, m_expectedMessageSize);
+        pc.printf("Got too much data in appendReceivedData, already got %d bytes, new %d bytes, expected %d bytes.\r\n", m_currentMessageSize, length, m_expectedMessageSize);
         length = m_expectedMessageSize - m_currentMessageSize;
     }
     
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MODSERIAL.lib	Sun Apr 27 14:50:13 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- 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();
+        }
     }
 }