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
main.cpp@2:d3d61d9d323e, 2014-04-27 (annotated)
- 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?
User | Revision | Line number | New 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 | } |