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