CUER
/
charger_code
Code to run on the charger board (used to charge the car from the mains).
Diff: CANParserCharger.cpp
- Revision:
- 7:70cf5bff23f9
- Parent:
- 5:756fae795d37
- Child:
- 12:77d493b3320b
--- a/CANParserCharger.cpp Sun Jul 30 23:01:15 2017 +0000 +++ b/CANParserCharger.cpp Sun Sep 10 11:10:54 2017 +0000 @@ -6,6 +6,18 @@ using namespace CAN_IDs; +//CAN stuff. Not that there are two sets because there are two separate CAN buses here; one to communicate with the charger, and one to communicate with the rest of the car (importantly the BMS). +//The reason that there are two separate CAN buses is because the charger uses the extended CAN frame format, with a 29 bit ID, whereas the car uses the default 11 bit ID. +CAN car_can(CAR_CAN_READ_PIN, CAR_CAN_WRITE_PIN); //Create a CAN object to handle CAN comms +CANMessage car_buffer[CAN_BUFFER_SIZE]; //CAN receive buffer +bool car_safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer +bool car_CAN_data_sent = false; + +CAN charger_can(CHARGER_CAN_READ_PIN, CHARGER_CAN_WRITE_PIN); //Create a CAN object to handle CAN comms +CANMessage charger_buffer[CAN_BUFFER_SIZE]; //CAN receive buffer +bool charger_safe_to_write[CAN_BUFFER_SIZE]; //Semaphore bit indicating that it's safe to write to the software buffer +bool charger_CAN_data_sent = false; + void get_max_min_voltage(CANMessage msg, float &_min_cell_voltage, float &_max_cell_voltage) { CAN_Data data; data.importCANData(msg); @@ -91,4 +103,176 @@ msg.data[i] = data.get_u8(i); } return msg; -} \ No newline at end of file +} + +void get_CAN_data() { + + //Import the data from the buffer into a non-volatile, more usable format + CANMessage car_msgArray[CAN_BUFFER_SIZE]; //Same as above but some functions take message as their parameter + int car_received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far + for (int i = 0; i<CAN_BUFFER_SIZE; ++i) + { + car_safe_to_write[i] = false; + car_received_CAN_IDs[i] = car_buffer[i].id; + car_msgArray[i] = car_buffer[i]; + car_buffer[i].id = BLANK_ID; //this effectively clears the buffer, so that we never reuse old values + car_safe_to_write[i] = true; + + //Now actually import the data from the CAN packets into the global variables + switch (car_received_CAN_IDs[i]) { + + case BMS_BASE_ID: + break; + + case BMS_BASE_ID + MAX_MIN_VOLTAGE: + get_max_min_voltage(car_msgArray[i], min_cell_voltage, max_cell_voltage); + break; + + case BMS_BASE_ID + BATTERY_STATUS_ID: + get_battery_status(car_msgArray[i], bms_error); + break; + + case BMS_BASE_ID + BATTERY_PRECHARGE_ID: + check_precharge_status(car_msgArray[i], precharge_status); + break; + + case BLANK_ID: //This means we haven't received this type of message yet, so do nothing + break; + default: + break; + } + } + + //Import the data from the buffer into a non-volatile, more usable format + CANMessage charger_msgArray[CAN_BUFFER_SIZE]; //Same as above but some functions take message as their parameter + int charger_received_CAN_IDs[CAN_BUFFER_SIZE]; //needed to keep track of which IDs we've received so far + for (int i = 0; i<CAN_BUFFER_SIZE; ++i) + { + charger_safe_to_write[i] = false; + charger_received_CAN_IDs[i] = charger_buffer[i].id; + charger_msgArray[i] = charger_buffer[i]; + charger_buffer[i].id = BLANK_ID; + charger_safe_to_write[i] = true; + + //Now actually import the data from the CAN packets into the global variables + switch (charger_received_CAN_IDs[i]) { + + case CHARGER_VI_INFO_ID: + get_charger_VI_info(charger_msgArray[i], charger_voltage, charger_current, charger_status); + if(charger_status bitand 1 == 1) { + if (DEBUG) printf("Charger status: Hardware Failure\r\n"); + charger_failure = true; + } + + if(charger_status bitand 2 == 2) { + if (DEBUG) printf("Charger status: Over Temperature\r\n"); + charger_failure = true; + } + + if(charger_status bitand 4 == 4) { + if (DEBUG) printf("Charger status: Input Voltage Wrong\r\n"); + charger_failure = true; + } + + if(charger_status bitand 8 == 8) { + if (DEBUG) printf("Charger status: Reverse Polarity\r\n"); + charger_failure = true; + } + + if(charger_status bitand 16 == 16) { + if (DEBUG) printf("Charger status: communication timeout\r\n"); + charger_failure = true; + } + break; + case BLANK_ID: //This means we haven't received this type of message yet, so do nothing + break; + default: + break; + } + } +} + +void car_CANDataSentCallback(void) { + car_CAN_data_sent = true; +} + +void charger_CANDataSentCallback(void) { + charger_CAN_data_sent = true; +} + +void car_interruptHandler() +{ + CANMessage msg; + car_can.read(msg); + //if(DEBUG) printf("id %d incoming \r\n", msg.id); + if(idAccepted(msg.id)) { + for(int i=0; i<CAN_BUFFER_SIZE; i++) { + if((car_buffer[i].id == msg.id || car_buffer[i].id==BLANK_ID) && car_safe_to_write[i]) { + //("id %d added to buffer \r\n", msg.id); + car_buffer[i] = msg; + //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered + return; + } + } + } +} + +void charger_interruptHandler() +{ + CANMessage msg; + charger_can.read(msg); + //if(DEBUG) printf("id %d incoming \r\n", msg.id); + if(idAccepted(msg.id)) { + for(int i=0; i<CAN_BUFFER_SIZE; i++) { + if((charger_buffer[i].id == msg.id || charger_buffer[i].id==BLANK_ID) && charger_safe_to_write[i]) { + //("id %d added to buffer \r\n", msg.id); + charger_buffer[i] = msg; + //return required so that only first blank buffer entry is converted to incoming message ID each time new message ID is encountered + return; + } + } + } +} + +bool idAccepted(int id) +{ + switch(id) { + case BMS_BASE_ID: + timeouts.BMS_timeout.reset(); + return true; + + case BMS_BASE_ID + MAX_MIN_VOLTAGE: + case BMS_BASE_ID + BATTERY_STATUS_ID: + case BMS_BASE_ID + BATTERY_PRECHARGE_ID: + return true; + case CHARGER_VI_INFO_ID: + timeouts.charger_timeout.reset(); + return true; + default: + return false; + } +} + +void CAN_Init() { + for(int i=0; i<CAN_BUFFER_SIZE; i++) + { + car_buffer[i].id = BLANK_ID; + //("%d",buffer[i].id); + car_safe_to_write[i]= true; + + charger_buffer[i].id = BLANK_ID; + //("%d",buffer[i].id); + charger_safe_to_write[i]= true; + } + + //Initialise CAN stuff, attach CAN interrupt handlers + car_can.frequency(CAN_BIT_RATE); //set transmission rate to agreed bit rate + car_can.reset(); + car_can.attach(&car_interruptHandler, CAN::RxIrq); //receive interrupt handler + car_can.attach(&car_CANDataSentCallback, CAN::TxIrq); //send interrupt handler + + charger_can.frequency(CHARGER_CAN_BIT_RATE); //set transmission rate to agreed bit rate + charger_can.reset(); + charger_can.attach(&charger_interruptHandler, CAN::RxIrq); //receive interrupt handler + charger_can.attach(&charger_CANDataSentCallback, CAN::TxIrq); //send interrupt handler +}