Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers can232.cpp Source File

can232.cpp

00001 /*******************************************************************************
00002 
00003 can232.cpp
00004 (c) 2010 by Sophie Dexter
00005 portions (c) 2009, 2010 by Janis Silins (johnc)
00006 
00007 Lawicel CAN232 type functions for Just4Trionic by Just4pLeisure
00008 
00009 ********************************************************************************
00010 
00011 WARNING: Use at your own risk, sadly this software comes with no guarantees.
00012 This software is provided 'free' and in good faith, but the author does not
00013 accept liability for any damage arising from its use.
00014 
00015 *******************************************************************************/
00016 
00017 #include "can232.h"
00018 
00019 // constants
00020 #define CMD_BUF_LENGTH      32              ///< command buffer size
00021 
00022 // command characters
00023 
00024 #define CMD_CLOSE           'C'             ///< Close the CAN device
00025 #define CMD_OPEN            'O'             ///< Open the CAN device (do this before an S/s command)
00026 
00027 #define CMD_PRESET_SPEED    'S'             ///< Sn: set preconfigured speeds 
00028 #define CMD_SPEED_0         '0'             ///< 10 kbits (or 47,619 bits with 's')
00029 #define CMD_SPEED_1         '1'             ///< 20 kbits (or 500 kbits with 's')
00030 #define CMD_SPEED_2         '2'             ///< 50 kbits (or 615 kbits with 's')
00031 #define CMD_SPEED_3         '3'             ///< 100 kbits
00032 #define CMD_SPEED_4         '4'             ///< 125 kbits
00033 #define CMD_SPEED_5         '5'             ///< 250 kbits
00034 #define CMD_SPEED_6         '6'             ///< 500 kbits
00035 #define CMD_SPEED_7         '7'             ///< 800 kbits
00036 #define CMD_SPEED_8         '8'             ///< 1 mbits
00037 #define CMD_DIRECT_SPEED    's'             ///< sxxyy: set the CAN bus speed registers directly
00038 ///< xx: BTR0 register setting
00039 ///< yy: BTR1 register setting
00040 
00041 #define CMD_SEND_11BIT      't'             ///< tiiildd..: send 11 bit id CAN frame
00042 ///< iii: identfier 0x0..0x7ff
00043 ///< l: Number of data bytes in CAN frame 0..8
00044 ///< dd..: data byte values 0x0..0xff (l pairs)
00045 #define CMD_SEND_29BIT      'T'             ///< Tiiiiiiiildd..: send 29 bit id CAN frame
00046 ///< iiiiiiii: identifier 0x0..0x1fffffff
00047 ///< l: Number of data bytes in CAN frame 0..8
00048 ///< dd..: data byte values 0x0..0xff (l pairs)
00049 
00050 
00051 #define CMD_READ_FLAGS      'F'             ///< Read flags !?!
00052 
00053 #define CMD_FILTER          'f'             ///< Filter which CAN message types to allow
00054 #define CMD_FILTER_NONE     '0'             ///< Allow all CAN message types
00055 #define CMD_FILTER_T5       '5'             ///< Allow only Trionic 5 CAN message types
00056 #define CMD_FILTER_T7       '7'             ///< Allow only Trionic 5 CAN message types
00057 #define CMD_FILTER_T8       '8'             ///< Allow only Trionic 5 CAN message types
00058 
00059 #define CMD_ACCEPT_CODE     'M'             ///< Mxxxxxxxx: Acceptance code e.g. 0x00000000 } accept
00060 #define CMD_ACCEPT_MASK     'm'             ///< mxxxxxxxx: Acceptance mask e.g. 0xffffffff } all
00061 
00062 #define CMD_VERSION         'V'             ///< Replies with Firmware and hardware version numbers; 2 bytes each
00063 #define CMD_SERIAL_NUMBER   'N'             ///< Replies with serial number; 4 bytes
00064 
00065 #define CMD_TIMESTAMP       'Z'             ///< Zn: n=0 means timestamp off, n=1 means timestamp is on
00066 ///< Replies a value in milliseconds with two bytes 0x0..0xfa5f
00067 ///< equivalent to 0..60 seconds
00068 
00069 
00070 
00071 // static variables
00072 static char cmd_buffer[CMD_BUF_LENGTH];     ///< command string buffer
00073 static uint32_t can_id;                     ///< can message id
00074 static uint32_t can_len;                    ///< can message length
00075 static uint8_t can_msg[8];                  ///< can message frame - up to 8 bytes
00076 
00077 // private functions
00078 uint8_t execute_can_cmd();
00079 
00080 // command argument macros
00081 #define CHECK_ARGLENGTH(len) \
00082     if (cmd_length != len + 2) \
00083         return TERM_ERR
00084 
00085 #define GET_NUMBER(target, offset, len)    \
00086     if (!ascii2int(target, cmd_buffer + 2 + offset, len)) \
00087         return TERM_ERR
00088 
00089 
00090 
00091 void can232() {
00092 
00093     // main loop
00094     *cmd_buffer = '\0';
00095     char ret;
00096     char rx_char;
00097     while (true) {
00098         // read chars from USB
00099         if (pc.readable()) {
00100             // turn Error LED off for next command
00101             led4 = 0;
00102             rx_char = pc.getc();
00103             switch (rx_char) {
00104                     // 'ESC' key to go back to mbed Just4Trionic 'home' menu
00105                 case '\e':
00106                     can_close();
00107                     can.attach(NULL);
00108                     return;
00109                     // end-of-command reached
00110                 case TERM_OK :
00111                     // execute command and return flag via USB
00112                     ret = execute_can_cmd();
00113                     pc.putc(ret);
00114                     // reset command buffer
00115                     *cmd_buffer = '\0';
00116                     // light up LED
00117 //                    ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR);
00118                     ret == TERM_OK ? led3 = 1 : led4 = 1;
00119                     break;
00120                     // another command char
00121                 default:
00122                     // store in buffer if space permits
00123                     if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) {
00124                         StrAddc(cmd_buffer, rx_char);
00125                     }
00126                     break;
00127             }
00128         }
00129     }
00130 }
00131 
00132 //-----------------------------------------------------------------------------
00133 /**
00134     Executes a command and returns result flag (does not transmit the flag
00135     itself).
00136 
00137     @return                    command flag (success / failure)
00138 */
00139 
00140 uint8_t execute_can_cmd() {
00141     uint8_t cmd_length = strlen(cmd_buffer);
00142     char cmd = *(cmd_buffer + 1);
00143 
00144     // command groups
00145     switch (*cmd_buffer) {
00146             // adapter commands
00147         case CMD_SEND_11BIT:
00148             if (cmd_length < 7) return TERM_ERR;
00149             GET_NUMBER(&can_id, -1, 3);
00150             GET_NUMBER(&can_len, 2, 1);
00151             if (cmd_length < (4 + (can_len * 2))) return TERM_ERR;
00152             for (uint8_t i = 0; i < (uint8_t)can_len; i++) {
00153                 uint32_t result;
00154                 GET_NUMBER(&result, (3 + (i * 2)), 2);
00155                 can_msg[i] = (uint8_t)result;
00156             }
00157             return (can_send_timeout (can_id, (char*)can_msg, (uint8_t)can_len, 500)) ? TERM_OK : TERM_ERR;
00158 
00159         case CMD_SEND_29BIT:
00160             break;
00161 
00162         case CMD_CLOSE:
00163             can_close();
00164             return TERM_OK;
00165         case CMD_OPEN:
00166             can_open();
00167             return TERM_OK;
00168 
00169         case CMD_PRESET_SPEED:
00170             CHECK_ARGLENGTH(0);
00171 //            can.attach(NULL);
00172            switch (cmd) {
00173                 case CMD_SPEED_0:
00174                     can_configure(2, 10000, 0);
00175                     break;
00176                 case CMD_SPEED_1:
00177                     can_configure(2, 20000, 0);
00178                     break;
00179                 case CMD_SPEED_2:
00180                     can_configure(2, 50000, 0);
00181                     break;
00182                 case CMD_SPEED_3:
00183                     can_configure(2, 100000, 0);
00184                     break;
00185                 case CMD_SPEED_4:
00186                     can_configure(2, 125000, 0);
00187                     break;
00188                 case CMD_SPEED_5:
00189                     can_configure(2, 250000, 0);
00190                     break;
00191                 case CMD_SPEED_6:
00192                     can_configure(2, 500000, 0);
00193                     break;
00194                 case CMD_SPEED_7:
00195                     can_configure(2, 800000, 0);
00196                     break;
00197                 case CMD_SPEED_8:
00198                     can_configure(2, 1000000, 0);
00199                     break;
00200                 default:
00201                     return TERM_ERR;
00202             }
00203             can.attach(&show_can_message);
00204             return TERM_OK;
00205 
00206         case CMD_DIRECT_SPEED:
00207             CHECK_ARGLENGTH(0);
00208             switch (cmd) {
00209                 case CMD_SPEED_0:
00210                     can_configure(2, 47619, 0);
00211                     break;
00212                 case CMD_SPEED_1:
00213                     can_configure(2, 500000, 0);
00214                     break;
00215                 case CMD_SPEED_2:
00216                     can_configure(2, 615000, 0);
00217                     break;
00218                 default:
00219                     return TERM_ERR;
00220             }
00221             can.attach(&show_can_message);
00222             return TERM_OK;
00223 
00224         case CMD_FILTER:
00225             CHECK_ARGLENGTH(0);
00226             switch (cmd) {
00227                 case CMD_FILTER_NONE:
00228                     can_use_filters(FALSE);                             // Accept all messages (Acceptance Filters disabled)
00229                     return TERM_OK;
00230                 case CMD_FILTER_T5:
00231                     can_reset_filters();
00232                     can_add_filter(2, 0x005);         //005h -
00233                     can_add_filter(2, 0x006);         //006h -
00234                     can_add_filter(2, 0x00C);         //00Ch -
00235                     can_add_filter(2, 0x008);         //008h -
00236                     return TERM_OK;
00237                 case CMD_FILTER_T7:
00238                     can_reset_filters();
00239                     can_add_filter(2, 0x220);         //220h
00240                     can_add_filter(2, 0x238);         //238h
00241                     can_add_filter(2, 0x240);         //240h
00242                     can_add_filter(2, 0x258);         //258h
00243                     can_add_filter(2, 0x266);         //266h - Ack
00244                     return TERM_OK;
00245                     can_add_filter(2, 0x1A0);         //1A0h - Engine information
00246                     can_add_filter(2, 0x280);         //280h - Pedals, reverse gear
00247                     can_add_filter(2, 0x290);         //290h - Steering wheel and SID buttons
00248                     can_add_filter(2, 0x2F0);         //2F0h - Vehicle speed
00249                     can_add_filter(2, 0x320);         //320h - Doors, central locking and seat belts
00250                     can_add_filter(2, 0x370);         //370h - Mileage
00251                     can_add_filter(2, 0x3A0);         //3A0h - Vehicle speed
00252                     can_add_filter(2, 0x3B0);         //3B0h - Head lights
00253                     can_add_filter(2, 0x3E0);         //3E0h - Automatic Gearbox
00254                     can_add_filter(2, 0x410);         //410h - Light dimmer and light sensor
00255                     can_add_filter(2, 0x430);         //430h - SID beep request (interesting for Knock indicator?)
00256                     can_add_filter(2, 0x460);         //460h - Engine rpm and speed
00257                     can_add_filter(2, 0x4A0);         //4A0h - Steering wheel, Vehicle Identification Number
00258                     can_add_filter(2, 0x520);         //520h - ACC, inside temperature
00259                     can_add_filter(2, 0x530);         //530h - ACC
00260                     can_add_filter(2, 0x5C0);         //5C0h - Coolant temperature, air pressure
00261                     can_add_filter(2, 0x630);         //630h - Fuel usage
00262                     can_add_filter(2, 0x640);         //640h - Mileage
00263                     can_add_filter(2, 0x7A0);         //7A0h - Outside temperature
00264                     return TERM_OK;
00265                 case CMD_FILTER_T8:
00266                     can_reset_filters();
00267                     can_add_filter(2, 0x645);         //645h - CIM
00268                     can_add_filter(2, 0x7E0);         //7E0h -
00269                     can_add_filter(2, 0x7E8);         //7E8h -
00270                     can_add_filter(2, 0x311);         //311h -
00271                     can_add_filter(2, 0x5E8);         //5E8h -
00272                     //can_add_filter(2, 0x101);         //101h -
00273                     return TERM_OK;
00274             }
00275             break;
00276     }
00277 
00278     // unknown command
00279     return TERM_ERR;
00280 }