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
Diff: main.cpp
- 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(); + } } }