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

Committer:
chrta
Date:
Sun Apr 27 14:50:13 2014 +0000
Revision:
2:d3d61d9d323e
Parent:
1:ca506b88b1d6
Child:
3:eb807d330292
Hardware is working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chrta 0:6b1f6139fb25 1 #include "mbed.h"
chrta 0:6b1f6139fb25 2 #include "rtos.h"
chrta 0:6b1f6139fb25 3 #include "IsoTpHandler.h"
chrta 2:d3d61d9d323e 4 #include "MODSERIAL.h"
chrta 1:ca506b88b1d6 5
chrta 2:d3d61d9d323e 6 #define CAN1_TEST
chrta 2:d3d61d9d323e 7 #define CAN1_OBD_CAR_SIMULATOR
chrta 2:d3d61d9d323e 8
chrta 2:d3d61d9d323e 9 // Make TX buffer 1024bytes and RX buffer use 512bytes.
chrta 2:d3d61d9d323e 10 MODSERIAL pc(USBTX, USBRX, 2 * 1024, 512); // tx, rx
chrta 0:6b1f6139fb25 11 DigitalOut led1(LED1);
chrta 0:6b1f6139fb25 12 DigitalOut led2(LED2);
chrta 2:d3d61d9d323e 13 DigitalOut led3(LED3);
chrta 2:d3d61d9d323e 14 DigitalOut led4(LED4);
chrta 2:d3d61d9d323e 15
chrta 2:d3d61d9d323e 16 CAN can1(p9, p10);
chrta 2:d3d61d9d323e 17 DigitalOut can1_disable(p8);
chrta 0:6b1f6139fb25 18 CAN can2(p30, p29);
chrta 2:d3d61d9d323e 19 DigitalOut can2_disable(p28);
chrta 2:d3d61d9d323e 20
chrta 0:6b1f6139fb25 21 IsoTpHandler tpHandler(&can2);
chrta 0:6b1f6139fb25 22
chrta 0:6b1f6139fb25 23 void led2_thread(void const *args) {
chrta 0:6b1f6139fb25 24 while (true) {
chrta 0:6b1f6139fb25 25 led2 = !led2;
chrta 0:6b1f6139fb25 26 Thread::wait(1000);
chrta 0:6b1f6139fb25 27 }
chrta 0:6b1f6139fb25 28 }
chrta 0:6b1f6139fb25 29
chrta 0:6b1f6139fb25 30 Mail<CANMessage, 16> can_rx_queue;
chrta 0:6b1f6139fb25 31
chrta 0:6b1f6139fb25 32 void can_process_packets(void const *args) {
chrta 0:6b1f6139fb25 33 while (true) {
chrta 2:d3d61d9d323e 34 pc.printf("Th wait for can packet\r\n");
chrta 0:6b1f6139fb25 35 osEvent evt = can_rx_queue.get(osWaitForever);
chrta 2:d3d61d9d323e 36 pc.printf("Got evt %d\r\n", evt.status);
chrta 0:6b1f6139fb25 37 if (evt.status == osEventMail) {
chrta 2:d3d61d9d323e 38 pc.printf("Got can packet\r\n");
chrta 0:6b1f6139fb25 39 CANMessage *msg = (CANMessage*) evt.value.p;
chrta 2:d3d61d9d323e 40 pc.printf("Process can packet\r\n");
chrta 0:6b1f6139fb25 41 tpHandler.processCanMessage(msg);
chrta 2:d3d61d9d323e 42 pc.printf("Processed can packet\r\n");
chrta 0:6b1f6139fb25 43 can_rx_queue.free(msg);
chrta 2:d3d61d9d323e 44 pc.printf("Freed can packet\r\n");
chrta 0:6b1f6139fb25 45 }
chrta 0:6b1f6139fb25 46 }
chrta 0:6b1f6139fb25 47 }
chrta 0:6b1f6139fb25 48
chrta 0:6b1f6139fb25 49
chrta 0:6b1f6139fb25 50 void can_rx_int_handler() {
chrta 2:d3d61d9d323e 51 //pc.printf("can_rx_int_handler\r\n");
chrta 0:6b1f6139fb25 52 CANMessage* msg = can_rx_queue.alloc();
chrta 0:6b1f6139fb25 53 if (!can2.read(*msg))
chrta 0:6b1f6139fb25 54 {
chrta 2:d3d61d9d323e 55 //pc.printf("can_rx_int_handler no read\r\n");
chrta 0:6b1f6139fb25 56 //this should not happen, because this function is called from the rx interrupt
chrta 0:6b1f6139fb25 57 can_rx_queue.free(msg);
chrta 2:d3d61d9d323e 58 //pc.printf("can_rx_int_handler ret 1\r\n");
chrta 2:d3d61d9d323e 59 return;
chrta 2:d3d61d9d323e 60 }
chrta 2:d3d61d9d323e 61 if (msg->id != 0x7E8)
chrta 2:d3d61d9d323e 62 {
chrta 2:d3d61d9d323e 63 //no OBD message
chrta 2:d3d61d9d323e 64 can_rx_queue.free(msg);
chrta 0:6b1f6139fb25 65 return;
chrta 0:6b1f6139fb25 66 }
chrta 2:d3d61d9d323e 67 //pc.printf("can_rx_int_handler got packet\r\n");
chrta 2:d3d61d9d323e 68 osStatus error_code = can_rx_queue.put(msg);
chrta 2:d3d61d9d323e 69 //pc.printf("can_rx_int_handler in queue\r\n");
chrta 2:d3d61d9d323e 70 if (error_code != osOK) {
chrta 2:d3d61d9d323e 71 //pc.printf("can_rx_int_handler failed\r\n");
chrta 2:d3d61d9d323e 72 //error("Putting can message into mailbox failed with code %d!", error);
chrta 2:d3d61d9d323e 73 }
chrta 0:6b1f6139fb25 74
chrta 2:d3d61d9d323e 75 //pc.printf("can_rx_int_handler ok\r\n");
chrta 2:d3d61d9d323e 76 }
chrta 2:d3d61d9d323e 77
chrta 2:d3d61d9d323e 78 #ifdef CAN1_TEST
chrta 2:d3d61d9d323e 79 Mail<CANMessage, 16> can1_rx_queue;
chrta 2:d3d61d9d323e 80 CANMessage msg1;
chrta 2:d3d61d9d323e 81 void can1_rx_int_handler() {
chrta 2:d3d61d9d323e 82 led3 = !led3;
chrta 2:d3d61d9d323e 83 CANMessage* msg = can1_rx_queue.alloc();
chrta 2:d3d61d9d323e 84 if (!can1.read(*msg))
chrta 2:d3d61d9d323e 85 {
chrta 2:d3d61d9d323e 86 can1_rx_queue.free(msg);
chrta 2:d3d61d9d323e 87 return;
chrta 2:d3d61d9d323e 88 }
chrta 2:d3d61d9d323e 89 can1_rx_queue.put(msg);
chrta 2:d3d61d9d323e 90 led4 = !led4;
chrta 2:d3d61d9d323e 91 }
chrta 2:d3d61d9d323e 92
chrta 2:d3d61d9d323e 93
chrta 2:d3d61d9d323e 94 #ifdef CAN1_OBD_CAR_SIMULATOR
chrta 2:d3d61d9d323e 95
chrta 2:d3d61d9d323e 96 struct behaviour_t {
chrta 2:d3d61d9d323e 97 unsigned char rxData[8];
chrta 2:d3d61d9d323e 98 char txData[8];
chrta 2:d3d61d9d323e 99 };
chrta 2:d3d61d9d323e 100
chrta 2:d3d61d9d323e 101 behaviour_t behaviour[] =
chrta 2:d3d61d9d323e 102 {
chrta 2:d3d61d9d323e 103 {{0x02, 0x21, 0x01, 0, 0, 0, 0, 0}, {0x10, 0x1F, 0x61, 0x01, 0x51, 0, 0x37, 0x01}}, //first oil temp packet
chrta 2:d3d61d9d323e 104 {{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
chrta 2:d3d61d9d323e 105 {{0x02, 0x01, 0x21, 0, 0, 0, 0, 0}, {0x04, 0x41, 0x21, 0, 0, 0, 0, 0}},
chrta 2:d3d61d9d323e 106 {{0x02, 0x01, 0x0C, 0, 0, 0, 0, 0}, {0x04, 0x41, 0x0C, 0x0F, 0xA2, 0, 0, 0}},
chrta 2:d3d61d9d323e 107 {{0x02, 0x01, 0x11, 0, 0, 0, 0, 0}, {0x03, 0x41, 0x11, 0x26, 0, 0, 0, 0}},
chrta 2:d3d61d9d323e 108 {{0x02, 0x01, 0x05, 0, 0, 0, 0, 0}, {0x03, 0x41, 0x05, 0x4D, 0, 0, 0, 0}}, //engine coolant temp
chrta 2:d3d61d9d323e 109 };
chrta 2:d3d61d9d323e 110
chrta 2:d3d61d9d323e 111 Mail<CANMessage, 16> can1_tx_queue;
chrta 2:d3d61d9d323e 112
chrta 2:d3d61d9d323e 113 void can1_obd_car_simulator_process_packet(CANMessage &msg)
chrta 2:d3d61d9d323e 114 {
chrta 2:d3d61d9d323e 115 if (msg.id != 0x7E0)
chrta 2:d3d61d9d323e 116 {
chrta 2:d3d61d9d323e 117 return;
chrta 2:d3d61d9d323e 118 }
chrta 2:d3d61d9d323e 119
chrta 2:d3d61d9d323e 120 for (unsigned int i = 0; i < sizeof(behaviour) / sizeof (behaviour[0]); i++)
chrta 2:d3d61d9d323e 121 {
chrta 2:d3d61d9d323e 122 if (memcmp(msg.data, behaviour[i].rxData, 8) == 0)
chrta 2:d3d61d9d323e 123 {
chrta 2:d3d61d9d323e 124 CANMessage sendMsg(0x7E8, (char*) behaviour[i].txData, 8);
chrta 2:d3d61d9d323e 125 CANMessage* msg = can1_tx_queue.alloc();
chrta 2:d3d61d9d323e 126 *msg = sendMsg;
chrta 2:d3d61d9d323e 127 can1_tx_queue.put(msg);
chrta 2:d3d61d9d323e 128
chrta 2:d3d61d9d323e 129 if (i == 1)
chrta 2:d3d61d9d323e 130 {
chrta 2:d3d61d9d323e 131 //send additinal packets later
chrta 2:d3d61d9d323e 132 sendMsg.data[0] = 0x22;
chrta 2:d3d61d9d323e 133 msg = can1_tx_queue.alloc();
chrta 2:d3d61d9d323e 134 *msg = sendMsg;
chrta 2:d3d61d9d323e 135 can1_tx_queue.put(msg);
chrta 2:d3d61d9d323e 136 sendMsg.data[0] = 0x23;
chrta 2:d3d61d9d323e 137 msg = can1_tx_queue.alloc();
chrta 2:d3d61d9d323e 138 *msg = sendMsg;
chrta 2:d3d61d9d323e 139 can1_tx_queue.put(msg);
chrta 2:d3d61d9d323e 140 sendMsg.data[0] = 0x24;
chrta 2:d3d61d9d323e 141 msg = can1_tx_queue.alloc();
chrta 2:d3d61d9d323e 142 *msg = sendMsg;
chrta 2:d3d61d9d323e 143 can1_tx_queue.put(msg);
chrta 2:d3d61d9d323e 144 }
chrta 2:d3d61d9d323e 145 }
chrta 0:6b1f6139fb25 146 }
chrta 0:6b1f6139fb25 147 }
chrta 1:ca506b88b1d6 148
chrta 2:d3d61d9d323e 149 #endif //CAN1_OBD_CAR_SIMULATOR
chrta 2:d3d61d9d323e 150
chrta 2:d3d61d9d323e 151 void can1_process_packets(void const *args) {
chrta 2:d3d61d9d323e 152 while (true) {
chrta 2:d3d61d9d323e 153 osEvent evt = can1_rx_queue.get(osWaitForever);
chrta 2:d3d61d9d323e 154 if (evt.status == osEventMail) {
chrta 2:d3d61d9d323e 155 CANMessage *msg = (CANMessage*) evt.value.p;
chrta 2:d3d61d9d323e 156
chrta 2:d3d61d9d323e 157 pc.printf("\r\nRX1: '%d' '%d' '%d' '%x' '", msg->format, msg->type, msg->len, msg->id);
chrta 2:d3d61d9d323e 158 for (unsigned int i = 0; i < msg->len; i++)
chrta 2:d3d61d9d323e 159 {
chrta 2:d3d61d9d323e 160 pc.printf("%x ", msg->data[i]);
chrta 2:d3d61d9d323e 161 }
chrta 2:d3d61d9d323e 162 pc.printf("'\r\n");
chrta 2:d3d61d9d323e 163 #ifdef CAN1_OBD_CAR_SIMULATOR
chrta 2:d3d61d9d323e 164 can1_obd_car_simulator_process_packet(*msg);
chrta 2:d3d61d9d323e 165 #endif //CAN1_OBD_CAR_SIMULATOR
chrta 2:d3d61d9d323e 166 can1_rx_queue.free(msg);
chrta 2:d3d61d9d323e 167 }
chrta 2:d3d61d9d323e 168 }
chrta 2:d3d61d9d323e 169 }
chrta 2:d3d61d9d323e 170
chrta 2:d3d61d9d323e 171 void can1_send_packets(void const *args) {
chrta 2:d3d61d9d323e 172 pc.printf("TX1 start\r\n");
chrta 2:d3d61d9d323e 173 while (true) {
chrta 2:d3d61d9d323e 174 osEvent evt = can1_tx_queue.get(osWaitForever);
chrta 2:d3d61d9d323e 175 if (evt.status == osEventMail) {
chrta 2:d3d61d9d323e 176 CANMessage *msg = (CANMessage*) evt.value.p;
chrta 2:d3d61d9d323e 177 pc.printf("TX1 check\r\n");
chrta 2:d3d61d9d323e 178 if (can1.write(*msg))
chrta 2:d3d61d9d323e 179 {
chrta 2:d3d61d9d323e 180 pc.printf("TX1 send\r\n");
chrta 2:d3d61d9d323e 181 can1_tx_queue.free(msg);
chrta 2:d3d61d9d323e 182 }
chrta 2:d3d61d9d323e 183 else
chrta 2:d3d61d9d323e 184 {
chrta 2:d3d61d9d323e 185 pc.printf("TX1 wait \r\n");
chrta 2:d3d61d9d323e 186 Thread::wait(50);
chrta 2:d3d61d9d323e 187 }
chrta 2:d3d61d9d323e 188 }
chrta 2:d3d61d9d323e 189 }
chrta 2:d3d61d9d323e 190 }
chrta 2:d3d61d9d323e 191
chrta 2:d3d61d9d323e 192 #endif //CAN1_TEST
chrta 2:d3d61d9d323e 193
chrta 2:d3d61d9d323e 194 char can_msg[8] = {0};
chrta 2:d3d61d9d323e 195 CANMessage msg(0x7E0, can_msg, 8);
chrta 1:ca506b88b1d6 196 void serial_int_handler() {
chrta 1:ca506b88b1d6 197 if (!pc.readable()) {
chrta 1:ca506b88b1d6 198 return;
chrta 1:ca506b88b1d6 199 }
chrta 1:ca506b88b1d6 200 uint8_t character = pc.getc();
chrta 2:d3d61d9d323e 201 //pc.printf("Received '%c'\r\n", character);
chrta 1:ca506b88b1d6 202
chrta 2:d3d61d9d323e 203 msg.data[0] = 0x02;
chrta 2:d3d61d9d323e 204 msg.data[1] = 0x01;
chrta 1:ca506b88b1d6 205 char pid = 0;
chrta 1:ca506b88b1d6 206 switch (character)
chrta 1:ca506b88b1d6 207 {
chrta 1:ca506b88b1d6 208 case '1':
chrta 1:ca506b88b1d6 209 pid = 0x0C; //engine rpm
chrta 1:ca506b88b1d6 210 break;
chrta 1:ca506b88b1d6 211 case '2':
chrta 1:ca506b88b1d6 212 pid = 0x11; //throttle
chrta 1:ca506b88b1d6 213 break;
chrta 1:ca506b88b1d6 214 case '3': //oil 1
chrta 2:d3d61d9d323e 215 msg.data[1] = 0x21; //endian
chrta 1:ca506b88b1d6 216 pid = 1;
chrta 1:ca506b88b1d6 217 break;
chrta 1:ca506b88b1d6 218 case '4': //oil 2
chrta 2:d3d61d9d323e 219 msg.data[1] = 1; //endian
chrta 1:ca506b88b1d6 220 pid = 0x21;
chrta 1:ca506b88b1d6 221 break;
chrta 1:ca506b88b1d6 222 default:
chrta 1:ca506b88b1d6 223 pid = 0x05; //engine coolant temp
chrta 1:ca506b88b1d6 224 }
chrta 2:d3d61d9d323e 225 msg.data[2] = pid;
chrta 2:d3d61d9d323e 226 msg.len = 8;
chrta 1:ca506b88b1d6 227
chrta 2:d3d61d9d323e 228 //pc.printf("Sending message\r\n");
chrta 2:d3d61d9d323e 229 int result = can2.write(msg); //or 0x7DF ?
chrta 2:d3d61d9d323e 230 //pc.printf("Can write %d\r\n", result);
chrta 2:d3d61d9d323e 231 //pc.printf("ret 1\r\n");
chrta 1:ca506b88b1d6 232 }
chrta 0:6b1f6139fb25 233
chrta 0:6b1f6139fb25 234 int main() {
chrta 2:d3d61d9d323e 235 pc.baud(921600);
chrta 2:d3d61d9d323e 236 //pc.attach(&serial_int_handler);
chrta 2:d3d61d9d323e 237 can2_disable = 0;
chrta 0:6b1f6139fb25 238 can2.frequency(500000);
chrta 2:d3d61d9d323e 239 //mbed can filter is not working? check it later
chrta 2:d3d61d9d323e 240 //can2.filter
chrta 0:6b1f6139fb25 241 can2.attach(can_rx_int_handler);
chrta 0:6b1f6139fb25 242 Thread thread(led2_thread);
chrta 0:6b1f6139fb25 243 Thread can_thread(can_process_packets);
chrta 2:d3d61d9d323e 244 #ifdef CAN1_TEST
chrta 2:d3d61d9d323e 245 can1_disable = 0;
chrta 2:d3d61d9d323e 246 can1.frequency(500000);
chrta 2:d3d61d9d323e 247 can1.attach(&can1_rx_int_handler);
chrta 2:d3d61d9d323e 248 Thread can1_thread(can1_process_packets);
chrta 2:d3d61d9d323e 249 Thread can1_tx_thread(can1_send_packets);
chrta 2:d3d61d9d323e 250 #endif //CAN1_TEST
chrta 2:d3d61d9d323e 251 pc.printf("Start\r\n");
chrta 0:6b1f6139fb25 252 while (true) {
chrta 0:6b1f6139fb25 253 led1 = !led1;
chrta 0:6b1f6139fb25 254 Thread::wait(500);
chrta 2:d3d61d9d323e 255 if (pc.readable()) {
chrta 2:d3d61d9d323e 256 serial_int_handler();
chrta 2:d3d61d9d323e 257 }
chrta 0:6b1f6139fb25 258 }
chrta 0:6b1f6139fb25 259 }