From 0fccb086c80d6daf3df7bedfdf50dd0bb72bb772 Mon Sep 17 00:00:00 2001 From: Theiremi Date: Tue, 14 Nov 2023 16:58:12 +0100 Subject: [PATCH] Make the code compile, still untested --- SLGreen.ino | 225 +++++++++++++++++++++++----------------------------- 1 file changed, 100 insertions(+), 125 deletions(-) diff --git a/SLGreen.ino b/SLGreen.ino index 207dded..764c428 100644 --- a/SLGreen.ino +++ b/SLGreen.ino @@ -15,10 +15,10 @@ */ //----- CONFIGURATION -----// -#define MCP_CS 10; -#define MCP_FREQUENCY MCP_8MHZ //Available values : MCP_8MHZ, MCP_16MHZ, MCP_20MHZ -#define SERIAL_SPEED 115200 //Recommended values : 115200, 150000, 250000, 500000, 1000000, 2000000 -#DEFAULT_CAN_SPEED CAN_500KBPS; //Available values : CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_1000KBPS +#define MCP_CS 10 +#define MCP_FREQUENCY MCP_8MHZ //Available values : MCP_8MHZ, MCP_16MHZ, MCP_20MHZ +#define SERIAL_SPEED 115200 //Recommended values : 115200, 150000, 250000, 500000, 1000000, 2000000 +#define DEFAULT_CAN_SPEED CAN_500KBPS; //Available values : CAN_10KBPS, CAN_20KBPS, CAN_50KBPS, CAN_100KBPS, CAN_125KBPS, CAN_250KBPS, CAN_500KBPS, CAN_1000KBPS //----------// //Don't forget to search in mcp_can library sources to understand how functions works @@ -38,79 +38,52 @@ uint8_t rx_buffer_len = 0; uint8_t CAN_speed = CAN_500KBPS; uint8_t CAN_freq = MCP_8MHZ; bool CAN_active = false; -bool auto_poll = false; -uint8_t buffered_frame[25] = {0}; -uint8_t buffered_frame_len = 0; void loop() { - slcanCheckRX(); - - if (CAN.checkReceive() == CAN_MSGAVAIL && CAN_active) { - uint32_t id = 0; - uint8_t len = 0; - byte cdata[8] = {0}; - CAN.readMsgBuf(&id, &len, cdata); - - id = id & 0x1FFFFFFF; - - buffered_frame[0] = int2asciiHex((id >> 28) & 0xF); - buffered_frame[1] = int2asciiHex((id >> 24) & 0xF); - buffered_frame[2] = int2asciiHex((id >> 20) & 0xF); - buffered_frame[3] = int2asciiHex((id >> 16) & 0xF); - buffered_frame[4] = int2asciiHex((id >> 12) & 0xF); - buffered_frame[5] = int2asciiHex((id >> 8) & 0xF); - buffered_frame[6] = int2asciiHex((id >> 4) & 0xF); - buffered_frame[7] = int2asciiHex(id & 0xF); - buffered_frame[8] = int2asciiHex(len); - - for(int i = 0; i <= len*2; i++) - { - buffered_frame[9+i] = (i % 2 == 1) ? int2asciiHex(cdata[i / 2] >> 4) : int2asciiHex(cdata[i / 2] & 0xF); - } - - if(auto_poll) - { - slcanFrameTX(buffered_frame, 9 + len*2); - } - else - { - buffered_frame_len = 9 + len*2; - } - } + serialCheckRX(); + canCheckRX(); } -void slcanCheckRX() { +void serialCheckRX() { if(Serial.available()) { byte received_char = Serial.read(); - if(received_char != 13)//Process the character received + + // If the character is not a Carriage Return, we have received a character of a frame + // The character is added to the buffer and the function ends here + if(received_char != 13) { rx_buffer[rx_buffer_len] = received_char; rx_buffer_len++; - if(rx_buffer_len > 15) rx_buffer_len = 0; //Frame too long, destroying the buffer + + //If the frame is too long, delete the buffer content to avoid a buffer overflow + //The length 26 has been choosen as the max length of any incoming message (excluding the CR) + if(rx_buffer_len > 26) rx_buffer_len = 0; return; } + // If the character received is a CR, the function continues and the buffer is processed - if(rx_buffer_len < 1)//Frame too short, drop it - { - rx_buffer_len = 0; - return; - } - - slcanProcessRX(rx_buffer_len, rx_buffer); - rx_buffer_len = 0; + serialProcessRX(rx_buffer_len, rx_buffer); + rx_buffer_len = 0;//Reset the buffer } } -void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) +void serialProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) { + // No frame can be shorter than 1 character (excluding the CR) + if(rx_buffer_len < 1) + { + rx_buffer_len = 0; + return; + } + if(rx_buffer[0] == 'S') { if(rx_buffer_len != 2) return slcanInvalidRX(); if(CAN_active) return slcanInvalidRX(); - uint8_t speed = rx_buffer[1] - 0x30; + uint8_t speed = asciiHex2int(rx_buffer[1]); switch(speed) { @@ -138,8 +111,9 @@ void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) case 8: CAN_speed = CAN_1000KBPS; break; + case 7:// 800kbps not implemented default: - slcanInvalidRX(); + return slcanInvalidRX(); } Serial.write(13); @@ -149,11 +123,10 @@ void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) { if(CAN_active) return slcanInvalidRX(); - CAN_active = true; - if(CAN.begin(MCP_ANY, CAN_speed, CAN_freq) != CAN_OK) return slcanInvalidRX(); CAN.setMode(MCP_NORMAL); + CAN_active = true; Serial.write(13); } @@ -177,50 +150,41 @@ void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) Serial.write(13); } - else if(rx_buffer[0] == 't') + else if(rx_buffer[0] == 't' || rx_buffer[0] == 'T') { if(!CAN_active) return slcanInvalidRX(); - uint16_t address = (asciiHex2int(rx_buffer[1]) << 8) + (asciiHex2int(rx_buffer[2]) << 4) + asciiHex2int(rx_buffer[3]); - uint8_t length = asciiHex2int(rx_buffer[1]); + bool extended_frame = (rx_buffer[0] == 't') ? 0 : 1; - if(address > 0x7FF) return slcanInvalidRX(); - if(length > 8) return slcanInvalidRX(); - if(rx_buffer_len != length * 2 + 5) return slcanInvalidRX(); - - uint8_t buf[length] = {0}; - for(int i = 5; i < rx_buffer_len; i++) + uint32_t address = 0; + if(!extended_frame) { - buf[i] |= (i % 2 == 0) ? asciiHex2int(rx_buffer[i]) << 4 : asciiHex2int(rx_buffer[i]); + address = (asciiHex2int(rx_buffer[1]) << 8) + + (asciiHex2int(rx_buffer[2]) << 4) + + asciiHex2int(rx_buffer[3]); + } + else + { + address = ((uint32_t)asciiHex2int(rx_buffer[1]) << 28) + + ((uint32_t)asciiHex2int(rx_buffer[2]) << 24) + + ((uint32_t)asciiHex2int(rx_buffer[3]) << 20) + + ((uint32_t)asciiHex2int(rx_buffer[4]) << 16) + + ((uint32_t)asciiHex2int(rx_buffer[5]) << 12) + + ((uint32_t)asciiHex2int(rx_buffer[6]) << 8) + + ((uint32_t)asciiHex2int(rx_buffer[7]) << 4) + + ((uint32_t)asciiHex2int(rx_buffer[8]) << 0); } - canTX(address, length, buf); - - Serial.write(13); - } - - else if(rx_buffer[0] == 'T') - { - if(!CAN_active) return slcanInvalidRX(); - - uint32_t address = ((uint32_t)asciiHex2int(rx_buffer[1]) << 28) + - ((uint32_t)asciiHex2int(rx_buffer[2]) << 24) + - ((uint32_t)asciiHex2int(rx_buffer[3]) << 20) + - ((uint32_t)asciiHex2int(rx_buffer[4]) << 16) + - ((uint32_t)asciiHex2int(rx_buffer[5]) << 12) + - ((uint32_t)asciiHex2int(rx_buffer[6]) << 8) + - ((uint32_t)asciiHex2int(rx_buffer[7]) << 4) + - ((uint32_t)asciiHex2int(rx_buffer[8]) << 0); - uint8_t length = asciiHex2int(rx_buffer[9]); + uint8_t length = asciiHex2int(rx_buffer[4 + 5*extended_frame]); if(address > 0x1FFFFFFF) return slcanInvalidRX(); - if(length > 8) return slcanInvalidRX(); - if(rx_buffer_len != length * 2 + 10) return slcanInvalidRX(); + if(length > 8) return slcanInvalidRX(); + if(rx_buffer_len != length * 2 + 5 + 5*extended_frame) return slcanInvalidRX(); uint8_t buf[length] = {0}; - for(int i = 10; i < rx_buffer_len; i++) + for(int i = 5 + 5*extended_frame; i < rx_buffer_len; i++) { - buf[i] |= (i % 2 == 1) ? asciiHex2int(rx_buffer[i]) << 4 : asciiHex2int(rx_buffer[i]); + buf[i] |= ((i+extended_frame) % 2 == 0) ? asciiHex2int(rx_buffer[i]) << 4 : asciiHex2int(rx_buffer[i]); } canTX(address, length, buf); @@ -228,34 +192,6 @@ void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) Serial.write(13); } - else if(rx_buffer[0] == 'P' || rx_buffer[0] == 'A') - { - if(!CAN_active) return slcanInvalidRX(); - if(auto_poll) return slcanInvalidRX(); - - slcanFrameTX(buffered_frame, buffered_frame_len); - buffered_frame_len = 0; - Serial.write(13); - } - - else if(rx_buffer[0] == 'X') - { - if(rx_buffer_len != 2) return slcanInvalidRX(); - - switch(asciiHex2int(rx_buffer[1])) - { - case 0: - auto_poll = false; - break; - case 1: - auto_poll = true; - break; - default: - return slcanInvalidRX(); - } - Serial.write(13); - } - else if(rx_buffer[0] == 'V') { Serial.write('V'); @@ -269,13 +205,6 @@ void slcanProcessRX(uint8_t rx_buffer_len, uint8_t *rx_buffer) Serial.print("SLGR"); Serial.write(13); } - - else if(rx_buffer[0] == 'F') return; - else if(rx_buffer[0] == 'W') return; - else if(rx_buffer[0] == 'M') return; - else if(rx_buffer[0] == 'm') return; - else if(rx_buffer[0] == 'U') return; - else if(rx_buffer[0] == 'Q') return; } void slcanInvalidRX() @@ -283,7 +212,7 @@ void slcanInvalidRX() Serial.write(7); } -void slcanFrameTX(uint8_t *buf, uint8_t len) +void serialTX(uint8_t *buf, uint8_t len) { Serial.write('T'); for(int i = 0; i < len; i++) @@ -293,6 +222,52 @@ void slcanFrameTX(uint8_t *buf, uint8_t len) Serial.write(13); } +void canCheckRX() +{ + if (CAN.checkReceive() == CAN_MSGAVAIL && CAN_active) { + uint32_t id = 0; + uint8_t len = 0; + bool ext = true; + byte cdata[8] = {0}; + CAN.readMsgBuf(&id, &len, cdata); + + id = id & 0x1FFFFFFF; + if(id <= 0x7FF) ext = false; + + uint8_t frame[2+len*2+ext*5] = {0}; + + if(!ext) + { + frame[0] = int2asciiHex((id >> 8) & 0xF); + frame[1] = int2asciiHex((id >> 4) & 0xF); + frame[2] = int2asciiHex(id & 0xF); + } + else + { + frame[0] = int2asciiHex((id >> 28) & 0xF); + frame[1] = int2asciiHex((id >> 24) & 0xF); + frame[2] = int2asciiHex((id >> 20) & 0xF); + frame[3] = int2asciiHex((id >> 16) & 0xF); + frame[4] = int2asciiHex((id >> 12) & 0xF); + frame[5] = int2asciiHex((id >> 8) & 0xF); + frame[6] = int2asciiHex((id >> 4) & 0xF); + frame[7] = int2asciiHex(id & 0xF); + } + + frame[3+ext*5] = int2asciiHex(len); + + + + for(int i = 0; i < len*2; i++) + { + int i_bufpos = (len*2 - (i+1)) / 2; + frame[(4+ext*5)+i] = (i_bufpos % 2 == 1) ? int2asciiHex(cdata[i_bufpos / 2] >> 4) : int2asciiHex(cdata[i_bufpos / 2] & 0xF); + } + + serialTX(frame, 2+len*2+ext*5); + } +} + void canTX(uint32_t address, uint8_t len, uint8_t *buf) { CAN.sendMsgBuf(address, address > 0x7FF ? 1 : 0, len, buf);