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, committed 2014-04-27
- 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
--- 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(); + } } }