Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Revision:
1:d5452e398b76
Parent:
0:e0b964252a05
Child:
2:bf3a2b29259a
--- a/main.cpp	Wed May 19 12:39:18 2010 +0000
+++ b/main.cpp	Tue Sep 14 21:02:04 2010 +0000
@@ -1,7 +1,8 @@
 /*******************************************************************************
 
-Just4Trionic by Just4pLeisure    
+Just4Trionic by Just4pLeisure
 *****************************
+(c) 2010 by Sophie Dexter
 
 Whilst I have written this program myself I could not have done it without
 a lot of help and the original ideas and programs written by:
@@ -12,7 +13,10 @@
 Tomi Liljemark - Lots of information and programs about the Saab CAN bus
 http://pikkupossu.1g.fi/tomi/projects/projects.html.
 Scott Howard - Author of the BDM software.
-Plus inspiration and ideas from many others, including johnc.
+Janis Silins - Valued contributor at http://www.ecuproject.com and creator of
+USBBDM. For sharing his BDM software (which also had a very useful method of
+entering commands)
+Plus inspiration and ideas from many others...
 
 Sophie x
 
@@ -24,7 +28,33 @@
 
 ********************************************************************************
 
-Version 1 (04/2010)- The basic functions are working, but not very easy to use
+Version 1.1 (09/2010) - Still very crude way of doing things
+
+Additions since Version 1:
+    The BDM interface is now working
+        Based on Janis Silin's BDM software with modifications and additions
+            Detect which type of FLASH chip is fitted to work out type of ECU
+            Modifications to FLASH algorithms - I think my algorithms are
+            closer to the datasheet methods. Still to do:
+                Separate pulse counters for 28Fxxx erase
+                DQ7 and DQ5 checking method for 29Fxxx FLASH
+        Works for T5.5 ECUs with 28F010 and 29F010 chips
+        Probably works with T5.2 ECUs (chip detection method)
+        MAY work with T7 ECUs ('prep' method may need changes - I can't test T7)
+        NOTE: Some of Janis' original BDM commands may not work, or at least
+        not as originally intended
+    Lawicell CAN232 interface partially working
+        Only a few Lawicell message types to open/close, set speed and write
+    Trionic5 CAN functions
+        All-in-one 'D' and 'F' commands to DUMP and FLASH BIN files
+            Lots of checking for errors, either works or says it failed
+            No need to interpret the cryptic CAN messages anymore
+        Should now work for T5.2 and T5.5 ECUs
+        Detects FLASH chip type and works out which ECU is connected T5.2/5.5
+
+********************************************************************************
+
+Version 1 (04/2010)- The basic CAN functions are working
 
 I have decided to 'release' this software somewhat prematurely because the FLASH
 chips in my spare ECU have 'died' and I don't know when I will be able to do
@@ -51,63 +81,126 @@
 *******************************************************************************/
 
 #include "mbed.h"
-
-#include "strings.h"
-#include "BDM.h"
-#include "CAN232.h"
-#include "Trionic5.h"
-
-Serial pc(USBTX, USBRX); // tx, rx
+//
+#include "common.h"
+#include "bdm.h"
+#include "can232.h"
+#include "t5can.h"
 
-#define CR 0x0D
-#define NL 0x0A
-#define BELL 0x07
+// constants
+#define CMD_BUF_LENGTH      32              ///< command buffer size
 
-#define TRUE 1
-#define FALSE 0
+// static variables
+static char cmd_buffer[CMD_BUF_LENGTH];     ///< command string buffer
 
-void ShowHelp();
+// private functions
+uint8_t execute_just4trionic_cmd();
+void show_just4trionic_help();
 
 int main() {
     // fast serial speed
 //    pc.baud(921600);
     pc.baud(115200);
-    // make plenty of space for command from RS232
-    char command[5];
-    ShowHelp();
-    while (1) {
-// Only get 2 characters, the command and \r
-// For now I cannot work out how to use gets() so only single characters
-// can be used for commands :-(
-//
-// At the moment only option '5' does anything - the Trionic5 functions
-//
-        pc.gets(command,2);
-        int len = strlen(command);
-        if (len != 1) 
-            printf ("\a");
-        else if (ToUpper(command[0]) == 'B')
-            BDM();
-        else if (ToUpper(command[0]) == 'O')
-            CAN232();
-        else if (ToUpper(command[0]) == '5')
-            Trionic5();
-        else if (ToUpper(command[0]) == 'H')
-            ShowHelp();
-//  Unrecognised so ring the BELL :(
-        else
-            printf ("\a");
+
+    // the address of the function to be attached (leds_off) and the interval (0.1 seconds)
+    // This 'ticker' turns off the activity LEDs so that they don't stay on if something has gone wrong
+    ticker.attach(&leds_off, 0.1);
+
+    // clear incoming buffer
+    // sometimes TeraTerm gets 'confused'. johnc does this in his code
+    // hopefully this will fix the problem
+    // unfortunately it doesn't, but it seems like a good idea
+    char rx_char;
+    while (pc.readable())
+        rx_char = pc.getc();
+
+    show_just4trionic_help();
+
+    // main loop
+    *cmd_buffer = '\0';
+    char ret;
+    while (true) {
+        // read chars from USB
+        // send received messages to the pc over USB connection
+        // This function displays any CAN messages that are 'missed' by the other functions
+        // Can messages might be 'missed' because they are received after a 'timeout' period
+        // or because they weren't expected, e.g. if the T5 ECU resets for some reason
+        t5_can_show_can_message();
+        if (pc.readable()) {
+            // turn Error LED off for next command
+            led4 = 0;
+            rx_char = pc.getc();
+            switch (rx_char) {
+                    // end-of-command reached
+                case TERM_OK :
+                    // execute command and return flag via USB
+                    timer.reset();
+                    timer.start();
+                    ret = execute_just4trionic_cmd();
+                    show_just4trionic_help();
+                    pc.putc(ret);
+                    // reset command buffer
+                    *cmd_buffer = '\0';
+                    // light up LED
+//                    ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR);
+                    ret == TERM_OK ? led3 = 1 : led4 = 1;
+                    break;
+                    // another command char
+                default:
+                    // store in buffer if space permits
+                    if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) {
+                        StrAddc(cmd_buffer, rx_char);
+                    }
+                    break;
+            }
+        }
     }
 }
 
-void ShowHelp() {
+//-----------------------------------------------------------------------------
+/**
+    Executes a command and returns result flag (does not transmit the flag
+    itself).
+
+    @return                    command flag (success / failure)
+*/
+uint8_t execute_just4trionic_cmd() {
+
+
+//    uint8_t cmd_length = strlen(cmd_buffer);
+    // command groups
+    switch (*cmd_buffer) {
+//            CHECK_ARGLENGTH(0);
+        case 'b':
+        case 'B':
+            bdm();
+            return TERM_OK;
+        case 'o':
+        case 'O':
+            can232();
+            return TERM_OK;
+        case '5':
+            t5_can();
+            return TERM_OK;
+        case 'h':
+        case 'H':
+            return TERM_OK;
+        default:
+            break;
+    }
+
+// unknown command
+    return TERM_ERR;
+}
+
+void show_just4trionic_help() {
     printf("Just4Trionic Command Menu\r\n");
     printf("=========================\r\n");
-    printf("b/B - Start BDM interface (NOT DONE)\r\n");
-    printf("o/O - Open Lawicel CAN232 type interface (NOT DONE)\r\n");
+    printf("b/B - Start BDM interface\r\n");
+    printf("o/O - Open Lawicel CAN232 type interface\r\n");
     printf("5   - Start Trionic5 ECU CAN interface\r\n");
     printf("\r\n");
     printf("h/H - show this help menu\r\n");
+    printf("\r\n");
     return;
-}
-
+}
\ No newline at end of file