From 1add450cf5ed4621c4ea91395273a766f17892ac Mon Sep 17 00:00:00 2001 From: Autohome2 Date: Thu, 27 Feb 2020 23:18:37 +0000 Subject: [PATCH] Branch 082019ma (#326) * fix to serial0 and serial3 when offset is 0 uses wrong command * fix to serial0 and serial3 when offset is 0 uses wrong command * fix hex num * add teensy canbus library teensy can read and write functions enabled * update to teensyduino 1.49 * part 1 prepare structure for obd can port works rename old can_command() to secondarySerial_command() for secondary serial and create new can_command for real CAN instruction decode. fix masking for teensy 3x and 4 * set mega as default build Co-authored-by: Josh Stewart --- platformio.ini | 5 ++- speeduino/board_teensy35.h | 13 ++++-- speeduino/board_teensy40.h | 11 +++-- speeduino/cancomms.h | 14 ++---- speeduino/cancomms.ino | 87 ++++++++++++++++++++++++++++++++++---- speeduino/init.ino | 5 +-- speeduino/speeduino.ino | 8 ++-- 7 files changed, 110 insertions(+), 33 deletions(-) diff --git a/platformio.ini b/platformio.ini index 5a3d3acb..483dc999 100644 --- a/platformio.ini +++ b/platformio.ini @@ -34,7 +34,7 @@ build_flags = -DUSE_MC33810 ;-DUSE_SPI_EEPROM platform=teensy board=teensy40 framework=arduino -lib_deps = EEPROM ;Needs FlexCAN added, but the lib is currently broken for Teensy4 +lib_deps = EEPROM, FlexCAN_T4 ;Not currently working ;[env:LaunchPad_tm4c1294ncpdt] @@ -107,7 +107,8 @@ src_dir=speeduino default_envs = megaatmega2560 ;The following lines are for testing / experimentation only. Comment the line above to try them out ;default_envs = black_F407VE -;env_default = teensy35 +;default_envs = teensy35 +;default_envs = teensy40 ;env_default = LaunchPad_tm4c1294ncpdt ;env_default = genericSTM32F103RB ;env_default = bluepill_f103c8 diff --git a/speeduino/board_teensy35.h b/speeduino/board_teensy35.h index 46630d68..612fc0e3 100644 --- a/speeduino/board_teensy35.h +++ b/speeduino/board_teensy35.h @@ -14,7 +14,6 @@ #define COUNTER_TYPE uint16_t #define BOARD_DIGITAL_GPIO_PINS 34 #define BOARD_NR_GPIO_PINS 34 - #define USE_SERIAL3 #ifdef USE_SPI_EEPROM #define EEPROM_LIB_H "src/SPIAsEEPROM/SPIAsEEPROM.h" #else @@ -137,7 +136,15 @@ *********************************************************************************************************** * CAN / Second serial */ - //Uart CANSerial (&sercom3, 0, 1, SERCOM_RX_PAD_1, UART_TX_PAD_0); - + #define USE_SERIAL3 // Secondary serial port to use + #include +#if defined(__MK64FX512__) // use for Teensy 3.5 only + FlexCAN_T4 Can0; +#elif defined(__MK66FX1M0__) // use for Teensy 3.6 only + FlexCAN_T4 Can0; + FlexCAN_T4 Can1; +#endif + static CAN_message_t outMsg; + static CAN_message_t inMsg; #endif //CORE_TEENSY #endif //TEENSY35_H \ No newline at end of file diff --git a/speeduino/board_teensy40.h b/speeduino/board_teensy40.h index 8d54bf85..51b2741d 100644 --- a/speeduino/board_teensy40.h +++ b/speeduino/board_teensy40.h @@ -14,7 +14,6 @@ #define COUNTER_TYPE uint32_t #define BOARD_DIGITAL_GPIO_PINS 34 #define BOARD_NR_GPIO_PINS 34 - #define USE_SERIAL3 #define EEPROM_LIB_H #define micros_safe() micros() //timer5 method is not used on anything but AVR, the micros_safe() macro is simply an alias for the normal micros() @@ -133,7 +132,13 @@ *********************************************************************************************************** * CAN / Second serial */ - //Uart CANSerial (&sercom3, 0, 1, SERCOM_RX_PAD_1, UART_TX_PAD_0); - + #define USE_SERIAL3 + #include + FlexCAN_T4 Can0; + FlexCAN_T4 Can1; + FlexCAN_T4 Can2; + static CAN_message_t outMsg; + static CAN_message_t inMsg; + #endif //CORE_TEENSY #endif //TEENSY40_H \ No newline at end of file diff --git a/speeduino/cancomms.h b/speeduino/cancomms.h index 7e83dd7f..3f59bfac 100644 --- a/speeduino/cancomms.h +++ b/speeduino/cancomms.h @@ -1,18 +1,10 @@ #ifndef CANCOMMS_H #define CANCOMMS_H -#if defined(CORE_TEENSY35) - #include - FlexCAN_T4 Can0; - - static CAN_message_t outMsg; - static CAN_message_t inMsg; -#endif - #define NEW_CAN_PACKET_SIZE 75 #define CAN_PACKET_SIZE 75 -uint8_t currentcanCommand; +uint8_t currentsecondserialCommand; uint8_t currentCanPage = 1;//Not the same as the speeduino config page numbers uint8_t nCanretry = 0; //no of retrys uint8_t cancmdfail = 0; //command fail yes/no @@ -37,8 +29,10 @@ bool canCmdPending = false; HardwareSerial &CANSerial = Serial2; #endif -void canCommand();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable. +void secondserial_Command();//This is the heart of the Command Line Interpeter. All that needed to be done was to make it human readable. void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portNum); +void can_Command(); void sendCancommand(uint8_t cmdtype , uint16_t canadddress, uint8_t candata1, uint8_t candata2, uint16_t sourcecanAddress); +void obd_response(uint8_t therequestedPID , uint8_t therequestedPIDlow, uint8_t therequestedPIDhigh); #endif // CANCOMMS_H diff --git a/speeduino/cancomms.ino b/speeduino/cancomms.ino index d2afb10c..77a064e6 100644 --- a/speeduino/cancomms.ino +++ b/speeduino/cancomms.ino @@ -6,9 +6,14 @@ can_comms was originally contributed by Darren Siepka */ /* -can_command is called when a command is received over serial3 from the Can interface -It parses the command and calls the relevant function -sendcancommand is called when a command is to be sent via serial3 to the Can interface +secondserial_command is called when a command is received from the secondary serial port +It parses the command and calls the relevant function. + +can_command is called when a command is recieved by the onboard/attached canbus module +It parses the command and calls the relevant function. + +sendcancommand is called when a command is to be sent either to serial3 +,to the external Can interface, or to the onboard/attached can interface */ #include "globals.h" #include "cancomms.h" @@ -16,11 +21,11 @@ sendcancommand is called when a command is to be sent via serial3 to the Can int #include "errors.h" #include "utils.h" -void canCommand() +void secondserial_Command() { - if (! canCmdPending) { currentcanCommand = CANSerial.read(); } + if (! canCmdPending) { currentsecondserialCommand = CANSerial.read(); } - switch (currentcanCommand) + switch (currentsecondserialCommand) { case 'A': // sends the bytes of realtime values from the OLD CAN list sendcanValues(0, CAN_PACKET_SIZE, 0x31, 1); //send values to serial3 @@ -275,7 +280,49 @@ void sendcanValues(uint16_t offset, uint16_t packetLength, byte cmd, byte portTy } - +void can_Command() +{ + //int currentcanCommand = inMsg.id; + #if defined(CORE_TEENSY) + currentStatus.canin[12] = (inMsg.id); + if ((inMsg.id == configPage9.obd_address) || (inMsg.id == 0x7DF)) + { + // The address is the speeduino specific ecu canbus address + // or the 0x7df(2015 dec) broadcast address + if (inMsg.buf[1] == 0x01) + { + // PID mode 0 , realtime data stream + obd_response(inMsg.buf[1], inMsg.buf[2], 0); // get the obd response based on the data in byte2 + outMsg.id = (0x7E8);//(configPage9.obd_address+8); + Can0.write(outMsg); // send the 8 bytes of obd data + } + if (inMsg.buf[1] == 0x22) + { + // PID mode 22h , custom mode , non standard data + obd_response(inMsg.buf[1], inMsg.buf[2], inMsg.buf[3]); // get the obd response based on the data in byte2 + outMsg.id = (0x7E8); //configPage9.obd_address+8); + Can0.write(outMsg); // send the 8 bytes of obd data + } + } + if (inMsg.id == configPage9.obd_address) + { + // The address is only the speeduino specific ecu canbus address + if (inMsg.buf[1] == 0x09) + { + // PID mode 9 , vehicle information request + if (inMsg.buf[2] == 02) + { + //send the VIN number , 17 char long VIN sent in 5 messages. + } + else if (inMsg.buf[2] == 0x0A) + { + //code 20: send 20 ascii characters with ECU name , "ECU -SpeeduinoXXXXXX" , change the XXXXXX ONLY as required. + } + } + } +#endif +} + // this routine sends a request(either "0" for a "G" , "1" for a "L" , "2" for a "R" to the Can interface or "3" sends the request via the actual local canbus void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint8_t candata2, uint16_t sourcecanAddress) { @@ -303,11 +350,12 @@ void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint case 3: //send to truecan send routine //canaddress == speeduino canid, candata1 == canin channel dest, paramgroup == can address to request from - #if defined(CORE_TEENSY35) //Scope guarding this for now, but this needs a bit of a rethink for how it can be handled better across multiple archs + //This section is to be moved to the correct can output routine later + #if defined(CORE_TEENSY) //Scope guarding this for now, but this needs a bit of a rethink for how it can be handled better across multiple archs outMsg.id = (canaddress); outMsg.len = 8; outMsg.buf[0] = 0x0B ; //11; - outMsg.buf[1] = 0x145; + outMsg.buf[1] = 0x15; outMsg.buf[2] = candata1; outMsg.buf[3] = 0x24; outMsg.buf[4] = 0x7F; @@ -322,3 +370,24 @@ void sendCancommand(uint8_t cmdtype, uint16_t canaddress, uint8_t candata1, uint break; } } + +// This routine builds the realtime data into packets that the obd requesting device can understand. This is only used by teensy and stm32 with onboard canbus +void obd_response(uint8_t thePIDmode, uint8_t therequestedPIDlow, uint8_t therequestedPIDhigh) +{ + +#if defined(CORE_STM32) || defined(CORE_TEENSY) +//only build the PID if the mcu has onboard/attached can + + uint16_t obdcalcA; //used in obd calcs + uint16_t obdcalcB; //used in obd calcs + uint16_t obdcalcC; //used in obd calcs + uint16_t obdcalcD; //used in obd calcs + uint32_t obdcalcE32; //used in calcs + uint32_t obdcalcF32; //used in calcs + uint16_t obdcalcG16; //used in calcs + uint16_t obdcalcH16; //used in calcs + + outMsg.len = 8; + +#endif +} diff --git a/speeduino/init.ino b/speeduino/init.ino index 417d3254..5b4e54ae 100644 --- a/speeduino/init.ino +++ b/speeduino/init.ino @@ -53,13 +53,12 @@ void initialiseAll() //STM32 can not currently enabled #endif - #if defined(CORE_TEENSY35) + #if defined(CORE_TEENSY) configPage9.intcan_available = 1; // device has internal canbus //Teensy uses the Flexcan_T4 library to use the internal canbus //enable local can interface //setup can interface to 500k - //volatile CAN_message_t outMsg; - //volatile CAN_message_t inMsg; + Can0.begin(); Can0.setBaudRate(500000); Can0.enableFIFO(); diff --git a/speeduino/speeduino.ino b/speeduino/speeduino.ino index a31aaac8..0dd17376 100644 --- a/speeduino/speeduino.ino +++ b/speeduino/speeduino.ino @@ -76,10 +76,10 @@ void loop() { if ( ((mainLoopCount & 31) == 1) or (CANSerial.available() > SERIAL_BUFFER_THRESHOLD) ) { - if (CANSerial.available() > 0) { canCommand(); } + if (CANSerial.available() > 0) { secondserial_Command(); } } } - #if defined(CORE_TEENSY35) + #if defined(CORE_TEENSY) //currentStatus.canin[12] = configPage9.enable_intcan; if (configPage9.enable_intcan == 1) // use internal can module { @@ -87,8 +87,10 @@ void loop() // if ( BIT_CHECK(LOOP_TIMER, BIT_TIMER_15HZ) or (CANbus0.available()) while (Can0.read(inMsg) ) { - Can0.read(inMsg); + can_Command(); + //Can0.read(inMsg); //currentStatus.canin[12] = inMsg.buf[5]; + //currentStatus.canin[13] = inMsg.id; } } #endif