Libraries to support working with GMLAN - General Motors CAN BUS network in most of their vehicles between 2007-present day. Please note this is a work in progress and not guaranteed to be correct, use at your own risk! Read commit logs / subscribe to see what has been added, it's a work in progress after all ;)
Diff: GMLAN.cpp
- Revision:
- 8:bc97fa5d306e
- Parent:
- 7:5ec65e6e8095
- Child:
- 9:4af02032daeb
diff -r 5ec65e6e8095 -r bc97fa5d306e GMLAN.cpp --- a/GMLAN.cpp Sun Apr 07 18:20:01 2013 +0000 +++ b/GMLAN.cpp Mon Apr 08 10:29:31 2013 +0000 @@ -77,10 +77,11 @@ return CANMessage(arbitration, datatochars, data.size(), CANData, CANStandard); } -GMLAN_11Bit_Request::GMLAN_11Bit_Request(int _id, vector<char> _request, bool _await_response) { +GMLAN_11Bit_Request::GMLAN_11Bit_Request(int _id, vector<char> _request, bool _await_response, bool _handle_flowcontrol) { id = _id; request_data = _request; await_response = _await_response; + handle_flowcontrol = _handle_flowcontrol; tx_bytes = rx_bytes = 0; tx_frame_counter = rx_frame_counter = 1; const char _fp [8] = {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA}; @@ -90,35 +91,51 @@ CANMessage GMLAN_11Bit_Request::getNextFrame(void) { char datatochars [8]; memcpy(datatochars, frame_padding, 8); - - if (request_data.size() < 8) { - // Unsegmented frame - datatochars[0] = (GMLAN_PCI_UNSEGMENTED << 4) | (request_data.size() & 0xF); - for (int i = 0; i < request_data.size(); i++) datatochars[i+1] = request_data[i]; - request_state = GMLAN_STATE_AWAITING_REPLY; - } else if (tx_bytes == 0) { - // First segmented frame - datatochars[0] = (GMLAN_PCI_SEGMENTED << 4) | ((request_data.size() >> 8) & 0xF); - datatochars[1] = request_data.size() & 0xFF; - for (int i = 0; i < 6; i++) { - datatochars[i+2] = request_data[i]; - tx_bytes++; + + if (handle_flowcontrol == true) { + // Only run this section if we need flow control + if (request_data.size() < 8) { + // Unsegmented frame + datatochars[0] = (GMLAN_PCI_UNSEGMENTED << 4) | (request_data.size() & 0xF); + for (int i = 0; i < request_data.size(); i++) { + datatochars[i+1] = request_data[i]; + tx_bytes++; + } + request_state = GMLAN_STATE_AWAITING_REPLY; + } else if (tx_bytes == 0) { + // First segmented frame + datatochars[0] = (GMLAN_PCI_SEGMENTED << 4) | ((request_data.size() >> 8) & 0xF); + datatochars[1] = request_data.size() & 0xFF; + for (int i = 0; i < 6; i++) { + datatochars[i+2] = request_data[i]; + tx_bytes++; + } + request_state = GMLAN_STATE_AWAITING_FC; + } else if (tx_bytes <= request_data.size()) { + // Additional segmented frame with data left to transmit + datatochars[0] = (GMLAN_PCI_ADDITIONAL << 4) | (tx_frame_counter & 0xF); + int old_tx_bytes = tx_bytes; + for (int i = old_tx_bytes; i < old_tx_bytes + 7; i++) { + if (i >= request_data.size()) break; + datatochars[(i+1)-old_tx_bytes] = request_data[i]; + tx_bytes++; + } + tx_frame_counter++; + if (tx_frame_counter > 0xF) tx_frame_counter = 0x0; } - request_state = GMLAN_STATE_AWAITING_FC; - } else if (tx_bytes <= request_data.size()) { - // Additional segmented frame with data left to transmit - datatochars[0] = (GMLAN_PCI_ADDITIONAL << 4) | (tx_frame_counter & 0xF); - int old_tx_bytes = tx_bytes; - for (int i = old_tx_bytes; i < old_tx_bytes + 7; i++) { - if (i >= request_data.size()) break; - datatochars[(i+1)-old_tx_bytes] = request_data[i]; - tx_bytes++; + if (tx_bytes >= request_data.size()) { + if (await_response == true) request_state = GMLAN_STATE_AWAITING_REPLY; + else request_state = GMLAN_STATE_COMPLETED; } - tx_frame_counter++; - if (tx_frame_counter > 0xF) tx_frame_counter = 0x0; - } - - if (tx_bytes >= request_data.size()) { + } else { + // No flow control required, build the frames without parsing but make sure we don't overshoot 8 bytes + for (int i = 0; i < request_data.size(); i++) { + if (i < 8) { + datatochars[i] = request_data[i]; + tx_bytes++; + } + else break; + } if (await_response == true) request_state = GMLAN_STATE_AWAITING_REPLY; else request_state = GMLAN_STATE_COMPLETED; }