Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Committer:
Just4pLeisure
Date:
Wed Sep 11 11:55:51 2013 +0000
Revision:
4:682d96ff6d79
Parent:
2:bf3a2b29259a
Child:
5:1775b4b13232
This update adds T8 CAN DUMP and FLASH capability (recovery still to do)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Just4pLeisure 1:d5452e398b76 1 /*******************************************************************************
Just4pLeisure 1:d5452e398b76 2
Just4pLeisure 1:d5452e398b76 3 bdmtrionic.cpp
Just4pLeisure 1:d5452e398b76 4 (c) 2010 by Sophie Dexter
Just4pLeisure 1:d5452e398b76 5
Just4pLeisure 1:d5452e398b76 6 General purpose BDM functions for Just4Trionic by Just4pLeisure
Just4pLeisure 1:d5452e398b76 7
Just4pLeisure 1:d5452e398b76 8 A derivative work based on:
Just4pLeisure 1:d5452e398b76 9 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 10 // CAN/BDM adapter firmware
Just4pLeisure 1:d5452e398b76 11 // (C) Janis Silins, 2010
Just4pLeisure 1:d5452e398b76 12 // $id$
Just4pLeisure 1:d5452e398b76 13 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 14
Just4pLeisure 1:d5452e398b76 15 ********************************************************************************
Just4pLeisure 1:d5452e398b76 16
Just4pLeisure 1:d5452e398b76 17 WARNING: Use at your own risk, sadly this software comes with no guarantees.
Just4pLeisure 1:d5452e398b76 18 This software is provided 'free' and in good faith, but the author does not
Just4pLeisure 1:d5452e398b76 19 accept liability for any damage arising from its use.
Just4pLeisure 1:d5452e398b76 20
Just4pLeisure 1:d5452e398b76 21 *******************************************************************************/
Just4pLeisure 1:d5452e398b76 22
Just4pLeisure 1:d5452e398b76 23 #include "bdmtrionic.h"
Just4pLeisure 1:d5452e398b76 24
Just4pLeisure 1:d5452e398b76 25 // structure for command address/value pairs
Just4pLeisure 1:d5452e398b76 26 struct mempair_t {
Just4pLeisure 1:d5452e398b76 27 uint32_t addr; ///< target address
Just4pLeisure 1:d5452e398b76 28 uint16_t val; ///< word value
Just4pLeisure 1:d5452e398b76 29 };
Just4pLeisure 1:d5452e398b76 30
Just4pLeisure 1:d5452e398b76 31 // word write algorithm (29Fxxx)
Just4pLeisure 1:d5452e398b76 32 static const struct mempair_t am29_write [] = {
Just4pLeisure 1:d5452e398b76 33 {0xaaaa, 0xaaaa}, {0x5554, 0x5555}, {0xaaaa, 0xa0a0},
Just4pLeisure 1:d5452e398b76 34 };
Just4pLeisure 1:d5452e398b76 35
Just4pLeisure 1:d5452e398b76 36 // chip erase algorithms
Just4pLeisure 1:d5452e398b76 37 static const struct mempair_t am29_erase [] = {
Just4pLeisure 1:d5452e398b76 38 {0xaaaa, 0xaaaa}, {0x5554, 0x5555}, {0xaaaa, 0x8080},
Just4pLeisure 1:d5452e398b76 39 {0xaaaa, 0xaaaa}, {0x5554, 0x5555}, {0xaaaa, 0x1010}
Just4pLeisure 1:d5452e398b76 40 };
Just4pLeisure 1:d5452e398b76 41
Just4pLeisure 1:d5452e398b76 42 // reset algorithms
Just4pLeisure 1:d5452e398b76 43 //static const struct mempair_t am29_reset = {0xfffe, 0xf0f0};
Just4pLeisure 1:d5452e398b76 44 static const struct mempair_t am29_reset [] = {
Just4pLeisure 1:d5452e398b76 45 {0xaaaa, 0xaaaa}, {0x5554, 0x5555}, {0xaaaa, 0xf0f0},
Just4pLeisure 1:d5452e398b76 46 };
Just4pLeisure 1:d5452e398b76 47
Just4pLeisure 1:d5452e398b76 48 // chip id algorithms
Just4pLeisure 1:d5452e398b76 49 static const struct mempair_t am29_id [] = {
Just4pLeisure 1:d5452e398b76 50 {0xaaaa, 0xaaaa}, {0x5554, 0x5555}, {0xaaaa, 0x9090},
Just4pLeisure 1:d5452e398b76 51 };
Just4pLeisure 1:d5452e398b76 52
Just4pLeisure 1:d5452e398b76 53 // ;-)
Just4pLeisure 1:d5452e398b76 54 static const struct mempair_t flash_tag [] = {
Just4pLeisure 1:d5452e398b76 55 {0x7fe00, 0xFF4A}, {0x7fe02, 0x7573}, {0x7fe04, 0x7434}, {0x7fe06, 0x704C},
Just4pLeisure 1:d5452e398b76 56 {0x7fe08, 0x6569}, {0x7fe0a, 0x7375}, {0x7fe0c, 0x7265}, {0x7fe0e, 0x3B29},
Just4pLeisure 1:d5452e398b76 57 };
Just4pLeisure 1:d5452e398b76 58
Just4pLeisure 1:d5452e398b76 59 // local functions
Just4pLeisure 1:d5452e398b76 60 bool reset_am29(void);
Just4pLeisure 1:d5452e398b76 61 bool erase_am29();
Just4pLeisure 1:d5452e398b76 62 bool flash_am29(const uint32_t* addr, uint16_t value);
Just4pLeisure 1:d5452e398b76 63 bool reset_am28(void);
Just4pLeisure 1:d5452e398b76 64 bool erase_am28(const uint32_t* start_addr, const uint32_t* end_addr);
Just4pLeisure 1:d5452e398b76 65 bool flash_am28(const uint32_t* addr, uint16_t value);
Just4pLeisure 1:d5452e398b76 66 bool get_flash_id(uint8_t* make, uint8_t* type);
Just4pLeisure 1:d5452e398b76 67
Just4pLeisure 1:d5452e398b76 68
Just4pLeisure 1:d5452e398b76 69 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 70 /**
Just4pLeisure 1:d5452e398b76 71 Dumps contents of a memory block from [start_addr] up to, but not including,
Just4pLeisure 1:d5452e398b76 72 the [end_addr] as long words (word-aligned addresses). MCU must be in
Just4pLeisure 1:d5452e398b76 73 background mode. The operation interrupts if the break character is
Just4pLeisure 1:d5452e398b76 74 received.
Just4pLeisure 1:d5452e398b76 75
Just4pLeisure 1:d5452e398b76 76 @param start_addr block start address
Just4pLeisure 1:d5452e398b76 77 @param end_addr block end address
Just4pLeisure 1:d5452e398b76 78
Just4pLeisure 1:d5452e398b76 79 @return status flag
Just4pLeisure 1:d5452e398b76 80 */
Just4pLeisure 1:d5452e398b76 81
Just4pLeisure 1:d5452e398b76 82
Just4pLeisure 4:682d96ff6d79 83 uint8_t dump_flash(const uint32_t* start_addr, const uint32_t* end_addr)
Just4pLeisure 4:682d96ff6d79 84 {
Just4pLeisure 1:d5452e398b76 85
Just4pLeisure 1:d5452e398b76 86 // check parametres
Just4pLeisure 1:d5452e398b76 87 if (*start_addr > *end_addr) {
Just4pLeisure 1:d5452e398b76 88 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 89 }
Just4pLeisure 1:d5452e398b76 90
Just4pLeisure 1:d5452e398b76 91 // dump memory contents
Just4pLeisure 1:d5452e398b76 92 uint32_t curr_addr = *start_addr;
Just4pLeisure 1:d5452e398b76 93 uint32_t value;
Just4pLeisure 1:d5452e398b76 94
Just4pLeisure 1:d5452e398b76 95 while ((curr_addr < *end_addr) && (pc.getc() != TERM_BREAK)) {
Just4pLeisure 1:d5452e398b76 96 // read long word
Just4pLeisure 1:d5452e398b76 97 if (curr_addr > *start_addr) {
Just4pLeisure 1:d5452e398b76 98 if (memdump_long(&value) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 99 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 100 }
Just4pLeisure 1:d5452e398b76 101 } else {
Just4pLeisure 1:d5452e398b76 102 if (memread_long(&value, &curr_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 103 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 104 }
Just4pLeisure 1:d5452e398b76 105 }
Just4pLeisure 1:d5452e398b76 106
Just4pLeisure 1:d5452e398b76 107 // send memory value to host
Just4pLeisure 1:d5452e398b76 108 printf("%08X", value);
Just4pLeisure 4:682d96ff6d79 109 printf("\r\n");
Just4pLeisure 1:d5452e398b76 110
Just4pLeisure 1:d5452e398b76 111 // add the terminating character
Just4pLeisure 1:d5452e398b76 112 if (curr_addr < *end_addr - 4) {
Just4pLeisure 1:d5452e398b76 113 pc.putc(TERM_OK);
Just4pLeisure 1:d5452e398b76 114 // light up the activity LED
Just4pLeisure 2:bf3a2b29259a 115 ACTIVITYLEDON;
Just4pLeisure 1:d5452e398b76 116 }
Just4pLeisure 1:d5452e398b76 117
Just4pLeisure 1:d5452e398b76 118 curr_addr += 4;
Just4pLeisure 1:d5452e398b76 119 }
Just4pLeisure 1:d5452e398b76 120
Just4pLeisure 1:d5452e398b76 121 return TERM_OK;
Just4pLeisure 1:d5452e398b76 122 }
Just4pLeisure 1:d5452e398b76 123
Just4pLeisure 1:d5452e398b76 124 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 125 /**
Just4pLeisure 1:d5452e398b76 126 Dumps the contents of a T5 ECU to a BIN file on the mbed 'disk'
Just4pLeisure 1:d5452e398b76 127 from [start_addr] up to, but not including, the [end_addr].
Just4pLeisure 1:d5452e398b76 128 MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 129
Just4pLeisure 1:d5452e398b76 130 @param start_addr block start address
Just4pLeisure 1:d5452e398b76 131 @param end_addr block end address
Just4pLeisure 1:d5452e398b76 132
Just4pLeisure 1:d5452e398b76 133 @return status flag
Just4pLeisure 1:d5452e398b76 134 */
Just4pLeisure 1:d5452e398b76 135
Just4pLeisure 4:682d96ff6d79 136 uint8_t dump_trionic()
Just4pLeisure 4:682d96ff6d79 137 {
Just4pLeisure 1:d5452e398b76 138
Just4pLeisure 1:d5452e398b76 139 // Configure the MC68332 register values to prepare for flashing
Just4pLeisure 1:d5452e398b76 140 printf("I am trying to discover what type of Trionic ECU I am connected to...\r\n");
Just4pLeisure 1:d5452e398b76 141 prep_t5_do();
Just4pLeisure 1:d5452e398b76 142 // Work out what type of FLASH chips we want to make a dump file for
Just4pLeisure 1:d5452e398b76 143 uint8_t make;
Just4pLeisure 1:d5452e398b76 144 uint8_t type;
Just4pLeisure 1:d5452e398b76 145 get_flash_id(&make, &type);
Just4pLeisure 1:d5452e398b76 146 // set up chip-specific functions
Just4pLeisure 1:d5452e398b76 147 bool (*reset_func)();
Just4pLeisure 1:d5452e398b76 148 uint32_t flash_size;
Just4pLeisure 1:d5452e398b76 149
Just4pLeisure 1:d5452e398b76 150 switch (type) {
Just4pLeisure 4:682d96ff6d79 151 case AMD29BL802C:
Just4pLeisure 4:682d96ff6d79 152 printf("I have found AMD29BL802C type FLASH chips; I must be connected to a T8 ECU :-)\r\n");
Just4pLeisure 4:682d96ff6d79 153 reset_func = &reset_am29;
Just4pLeisure 4:682d96ff6d79 154 flash_size = T8FLASHSIZE;
Just4pLeisure 4:682d96ff6d79 155 break;
Just4pLeisure 1:d5452e398b76 156 case AMD29F400B:
Just4pLeisure 1:d5452e398b76 157 case AMD29F400T:
Just4pLeisure 1:d5452e398b76 158 printf("I have found AMD29F400 type FLASH chips; I must be connected to a T7 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 159 reset_func = &reset_am29;
Just4pLeisure 1:d5452e398b76 160 flash_size = T7FLASHSIZE;
Just4pLeisure 1:d5452e398b76 161 break;
Just4pLeisure 1:d5452e398b76 162 case AMD29F010:
Just4pLeisure 1:d5452e398b76 163 printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 164 reset_func = &reset_am29;
Just4pLeisure 1:d5452e398b76 165 flash_size = T55FLASHSIZE;
Just4pLeisure 1:d5452e398b76 166 break;
Just4pLeisure 1:d5452e398b76 167 case AMD28F010:
Just4pLeisure 1:d5452e398b76 168 case INTEL28F010:
Just4pLeisure 1:d5452e398b76 169 printf("I have found 28F010 type FLASH chips; I must be connected to a T5.5 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 170 reset_func = &reset_am28;
Just4pLeisure 1:d5452e398b76 171 flash_size = T55FLASHSIZE;
Just4pLeisure 1:d5452e398b76 172 break;
Just4pLeisure 1:d5452e398b76 173 case AMD28F512:
Just4pLeisure 1:d5452e398b76 174 case INTEL28F512:
Just4pLeisure 1:d5452e398b76 175 printf("I have found 28F512 type FLASH chips; I must be connected to a T5.2 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 176 reset_func = &reset_am28;
Just4pLeisure 1:d5452e398b76 177 flash_size = T52FLASHSIZE;
Just4pLeisure 1:d5452e398b76 178 break;
Just4pLeisure 1:d5452e398b76 179 default:
Just4pLeisure 1:d5452e398b76 180 // unknown flash type
Just4pLeisure 1:d5452e398b76 181 printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n");
Just4pLeisure 1:d5452e398b76 182 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 183 }
Just4pLeisure 1:d5452e398b76 184
Just4pLeisure 1:d5452e398b76 185 // reset the FLASH chips
Just4pLeisure 1:d5452e398b76 186 if (!reset_func()) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 187
Just4pLeisure 1:d5452e398b76 188 printf("Creating FLASH dump file...\r\n");
Just4pLeisure 1:d5452e398b76 189 FILE *fp = fopen("/local/original.bin", "w"); // Open "original.bin" on the local file system for writing
Just4pLeisure 1:d5452e398b76 190 if (!fp) {
Just4pLeisure 1:d5452e398b76 191 perror ("The following error occured");
Just4pLeisure 1:d5452e398b76 192 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 193 }
Just4pLeisure 1:d5452e398b76 194
Just4pLeisure 1:d5452e398b76 195 // dump memory contents
Just4pLeisure 1:d5452e398b76 196 uint32_t addr = 0x00;
Just4pLeisure 1:d5452e398b76 197 uint32_t long_value;
Just4pLeisure 1:d5452e398b76 198
Just4pLeisure 1:d5452e398b76 199 // setup start address to dump from
Just4pLeisure 1:d5452e398b76 200 if (memread_long_cmd(&addr) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 201
Just4pLeisure 1:d5452e398b76 202 timer.reset();
Just4pLeisure 1:d5452e398b76 203 timer.start();
Just4pLeisure 4:682d96ff6d79 204 printf(" 0.00 %% complete.\r");
Just4pLeisure 1:d5452e398b76 205 while (addr < flash_size) {
Just4pLeisure 1:d5452e398b76 206 uint16_t byte_count = 0;
Just4pLeisure 1:d5452e398b76 207 while (byte_count < FILE_BUF_LENGTH) {
Just4pLeisure 1:d5452e398b76 208 // get long word
Just4pLeisure 1:d5452e398b76 209 if (memget_long(&long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 210 addr += 4;
Just4pLeisure 1:d5452e398b76 211 // send memory value to file_buffer before saving to mbed 'disk'
Just4pLeisure 1:d5452e398b76 212 file_buffer[byte_count] = ((uint8_t)(long_value >> 24));
Just4pLeisure 1:d5452e398b76 213 file_buffer[byte_count+1] = ((uint8_t)(long_value >> 16));
Just4pLeisure 1:d5452e398b76 214 file_buffer[byte_count+2] = ((uint8_t)(long_value >> 8));
Just4pLeisure 1:d5452e398b76 215 file_buffer[byte_count+3] = ((uint8_t)long_value);
Just4pLeisure 1:d5452e398b76 216 byte_count +=4;
Just4pLeisure 2:bf3a2b29259a 217 // make the activity led twinkle
Just4pLeisure 4:682d96ff6d79 218 ACTIVITYLEDON;
Just4pLeisure 1:d5452e398b76 219 }
Just4pLeisure 1:d5452e398b76 220 fwrite(file_buffer, 1, FILE_BUF_LENGTH, fp);
Just4pLeisure 1:d5452e398b76 221 if (ferror (fp)) {
Just4pLeisure 1:d5452e398b76 222 fclose (fp);
Just4pLeisure 1:d5452e398b76 223 printf ("Error writing to the FLASH BIN file.\r\n");
Just4pLeisure 1:d5452e398b76 224 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 225 }
Just4pLeisure 4:682d96ff6d79 226 printf("%6.2f\r", 100*(float)addr/(float)flash_size );
Just4pLeisure 1:d5452e398b76 227 }
Just4pLeisure 4:682d96ff6d79 228 printf("\n");
Just4pLeisure 1:d5452e398b76 229 // should 'clear' the BDM connection here but bdm_clear won't compile from here
Just4pLeisure 1:d5452e398b76 230 // instead do a memread (or anything really) but ignore the result because it's not needed for anything
Just4pLeisure 1:d5452e398b76 231 memread_long(&long_value, &addr);
Just4pLeisure 1:d5452e398b76 232 timer.stop();
Just4pLeisure 1:d5452e398b76 233 printf("Getting the FLASH dump took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 1:d5452e398b76 234 fclose(fp);
Just4pLeisure 1:d5452e398b76 235 return TERM_OK;
Just4pLeisure 1:d5452e398b76 236 }
Just4pLeisure 1:d5452e398b76 237
Just4pLeisure 1:d5452e398b76 238 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 239 /**
Just4pLeisure 1:d5452e398b76 240 Erases the flash memory chip starting from [start_addr] up to, but not
Just4pLeisure 1:d5452e398b76 241 including [end_addr] and optionally verifies the result; MCU must be in
Just4pLeisure 1:d5452e398b76 242 background mode.
Just4pLeisure 1:d5452e398b76 243
Just4pLeisure 1:d5452e398b76 244 @param flash_type type of flash chip
Just4pLeisure 1:d5452e398b76 245 @param start_addr flash start address
Just4pLeisure 1:d5452e398b76 246 @param end_addr flash end address
Just4pLeisure 1:d5452e398b76 247
Just4pLeisure 1:d5452e398b76 248 @return status flag
Just4pLeisure 1:d5452e398b76 249 */
Just4pLeisure 1:d5452e398b76 250 uint8_t erase_flash(const char* flash_type, const uint32_t* start_addr,
Just4pLeisure 4:682d96ff6d79 251 const uint32_t* end_addr)
Just4pLeisure 4:682d96ff6d79 252 {
Just4pLeisure 1:d5452e398b76 253 // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7)
Just4pLeisure 1:d5452e398b76 254 if (strncmp(flash_type, "29f010", 6) == 0 ||
Just4pLeisure 1:d5452e398b76 255 strncmp(flash_type, "29f400", 6) == 0) {
Just4pLeisure 1:d5452e398b76 256 return erase_am29() ? TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 257 }
Just4pLeisure 1:d5452e398b76 258
Just4pLeisure 1:d5452e398b76 259 // AM28F010 chip (Trionic 5.x original)
Just4pLeisure 1:d5452e398b76 260 if (strncmp(flash_type, "28f010", 6) == 0) {
Just4pLeisure 1:d5452e398b76 261 return erase_am28(start_addr, end_addr) ? TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 262 }
Just4pLeisure 1:d5452e398b76 263
Just4pLeisure 1:d5452e398b76 264 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 265 }
Just4pLeisure 1:d5452e398b76 266
Just4pLeisure 1:d5452e398b76 267 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 268 /**
Just4pLeisure 1:d5452e398b76 269 Writes a batch of long words to the flash starting from [start_addr]. The
Just4pLeisure 1:d5452e398b76 270 operation interrupts if a break character is received. MCU must be in
Just4pLeisure 1:d5452e398b76 271 background mode.
Just4pLeisure 1:d5452e398b76 272
Just4pLeisure 1:d5452e398b76 273 @param flash_type type of flash chip
Just4pLeisure 1:d5452e398b76 274 @param start_addr block start address
Just4pLeisure 1:d5452e398b76 275
Just4pLeisure 1:d5452e398b76 276 @return status flag
Just4pLeisure 1:d5452e398b76 277 */
Just4pLeisure 4:682d96ff6d79 278 uint8_t write_flash(const char* flash_type, const uint32_t* start_addr)
Just4pLeisure 4:682d96ff6d79 279 {
Just4pLeisure 1:d5452e398b76 280 // set up chip-specific functions
Just4pLeisure 1:d5452e398b76 281 bool (*reset_func)(void);
Just4pLeisure 1:d5452e398b76 282 bool (*flash_func)(const uint32_t*, uint16_t);
Just4pLeisure 1:d5452e398b76 283
Just4pLeisure 1:d5452e398b76 284 // AM29Fxxx chips (retrofitted to Trionic 5.x, original to T7)
Just4pLeisure 1:d5452e398b76 285 if (strncmp(flash_type, "29f010", 6) == 0 ||
Just4pLeisure 1:d5452e398b76 286 strncmp(flash_type, "29f400", 6) == 0) {
Just4pLeisure 1:d5452e398b76 287 reset_func = &reset_am29;
Just4pLeisure 1:d5452e398b76 288 flash_func = &flash_am29;
Just4pLeisure 1:d5452e398b76 289 } else if (strncmp(flash_type, "28f010", 6) == 0) {
Just4pLeisure 1:d5452e398b76 290 // AM28F010 chip (Trionic 5.x original)
Just4pLeisure 1:d5452e398b76 291 reset_func = &reset_am28;
Just4pLeisure 1:d5452e398b76 292 flash_func = &flash_am28;
Just4pLeisure 1:d5452e398b76 293 } else {
Just4pLeisure 1:d5452e398b76 294 // unknown flash type
Just4pLeisure 1:d5452e398b76 295 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 296 }
Just4pLeisure 1:d5452e398b76 297
Just4pLeisure 1:d5452e398b76 298 // reset the flash
Just4pLeisure 1:d5452e398b76 299 if (!reset_func()) {
Just4pLeisure 1:d5452e398b76 300 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 301 }
Just4pLeisure 1:d5452e398b76 302
Just4pLeisure 1:d5452e398b76 303 uint32_t curr_addr = *start_addr;
Just4pLeisure 1:d5452e398b76 304 if (strncmp(flash_type, "29f010", 6) == 0) {
Just4pLeisure 1:d5452e398b76 305 curr_addr = 0;
Just4pLeisure 1:d5452e398b76 306 }
Just4pLeisure 1:d5452e398b76 307
Just4pLeisure 1:d5452e398b76 308 int rx_char = 0;
Just4pLeisure 1:d5452e398b76 309 char rx_buf[8];
Just4pLeisure 1:d5452e398b76 310 char* rx_ptr;
Just4pLeisure 1:d5452e398b76 311 uint32_t long_value;
Just4pLeisure 1:d5452e398b76 312 bool ret = true;
Just4pLeisure 1:d5452e398b76 313
Just4pLeisure 1:d5452e398b76 314 // ready to receive data
Just4pLeisure 1:d5452e398b76 315 pc.putc(TERM_OK);
Just4pLeisure 1:d5452e398b76 316
Just4pLeisure 1:d5452e398b76 317 while (true) {
Just4pLeisure 1:d5452e398b76 318 // receive long words from USB
Just4pLeisure 1:d5452e398b76 319 printf("receive long words from USB\r\n");
Just4pLeisure 1:d5452e398b76 320 rx_ptr = rx_buf;
Just4pLeisure 1:d5452e398b76 321 do {
Just4pLeisure 1:d5452e398b76 322 rx_char = pc.getc();
Just4pLeisure 1:d5452e398b76 323 if (rx_char != EOF) {
Just4pLeisure 1:d5452e398b76 324 // have got all characters for one long word
Just4pLeisure 1:d5452e398b76 325 if (rx_ptr > &rx_buf[7]) {
Just4pLeisure 1:d5452e398b76 326 ret = (rx_char == TERM_OK);
Just4pLeisure 1:d5452e398b76 327 break;
Just4pLeisure 1:d5452e398b76 328 }
Just4pLeisure 1:d5452e398b76 329
Just4pLeisure 1:d5452e398b76 330 // save the character
Just4pLeisure 1:d5452e398b76 331 *rx_ptr++ = (char)rx_char;
Just4pLeisure 1:d5452e398b76 332 }
Just4pLeisure 1:d5452e398b76 333 } while (rx_char != TERM_OK && rx_char != TERM_BREAK);
Just4pLeisure 1:d5452e398b76 334 // end writing
Just4pLeisure 1:d5452e398b76 335 printf("end writing\r\n");
Just4pLeisure 1:d5452e398b76 336 if (!ret || rx_char == TERM_BREAK) {
Just4pLeisure 1:d5452e398b76 337 break;
Just4pLeisure 1:d5452e398b76 338 }
Just4pLeisure 1:d5452e398b76 339
Just4pLeisure 1:d5452e398b76 340 // convert value to long word
Just4pLeisure 1:d5452e398b76 341 printf("convert value to long word\r\n");
Just4pLeisure 1:d5452e398b76 342 if (!ascii2int(&long_value, rx_buf, 8)) {
Just4pLeisure 1:d5452e398b76 343 ret = false;
Just4pLeisure 1:d5452e398b76 344 break;
Just4pLeisure 1:d5452e398b76 345 }
Just4pLeisure 1:d5452e398b76 346 printf("long value %08x \r\n", long_value);
Just4pLeisure 1:d5452e398b76 347
Just4pLeisure 1:d5452e398b76 348 // write the first word
Just4pLeisure 1:d5452e398b76 349 printf("write the first word\r\n");
Just4pLeisure 1:d5452e398b76 350 if (!flash_func(&curr_addr, (uint16_t)(long_value >> 16))) {
Just4pLeisure 1:d5452e398b76 351 ret = false;
Just4pLeisure 1:d5452e398b76 352 break;
Just4pLeisure 1:d5452e398b76 353 }
Just4pLeisure 1:d5452e398b76 354 curr_addr += 2;
Just4pLeisure 1:d5452e398b76 355 // write the second word
Just4pLeisure 1:d5452e398b76 356 printf("write the second word\r\n");
Just4pLeisure 1:d5452e398b76 357 if (!flash_func(&curr_addr, (uint16_t)long_value)) {
Just4pLeisure 1:d5452e398b76 358 ret = false;
Just4pLeisure 1:d5452e398b76 359 break;
Just4pLeisure 1:d5452e398b76 360 }
Just4pLeisure 1:d5452e398b76 361 curr_addr += 2;
Just4pLeisure 1:d5452e398b76 362
Just4pLeisure 1:d5452e398b76 363 // light up the activity LED
Just4pLeisure 4:682d96ff6d79 364 ACTIVITYLEDON;
Just4pLeisure 1:d5452e398b76 365 }
Just4pLeisure 1:d5452e398b76 366
Just4pLeisure 1:d5452e398b76 367 // reset flash
Just4pLeisure 1:d5452e398b76 368 return (reset_func() && ret) ? TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 369 }
Just4pLeisure 1:d5452e398b76 370
Just4pLeisure 1:d5452e398b76 371 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 372 /**
Just4pLeisure 1:d5452e398b76 373 Writes a BIN file to the flash starting from [start_addr].
Just4pLeisure 1:d5452e398b76 374 The operation ends when no more bytes can be read from the BIN file.
Just4pLeisure 1:d5452e398b76 375 MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 376
Just4pLeisure 1:d5452e398b76 377 @param flash_type type of flash chip
Just4pLeisure 1:d5452e398b76 378 @param start_addr block start address
Just4pLeisure 1:d5452e398b76 379
Just4pLeisure 1:d5452e398b76 380 @return status flag
Just4pLeisure 1:d5452e398b76 381 */
Just4pLeisure 4:682d96ff6d79 382 uint8_t flash_trionic()
Just4pLeisure 4:682d96ff6d79 383 {
Just4pLeisure 1:d5452e398b76 384 // Configure the MC68332 register values to prepare for flashing
Just4pLeisure 1:d5452e398b76 385 printf("I am trying to discover what type of Trionic ECU I am connected to...\r\n");
Just4pLeisure 1:d5452e398b76 386 prep_t5_do();
Just4pLeisure 1:d5452e398b76 387 // Work out what type of FLASH chips we want to program
Just4pLeisure 1:d5452e398b76 388 uint8_t make;
Just4pLeisure 1:d5452e398b76 389 uint8_t type;
Just4pLeisure 1:d5452e398b76 390 get_flash_id(&make, &type);
Just4pLeisure 1:d5452e398b76 391 // set up chip-specific functions
Just4pLeisure 1:d5452e398b76 392 bool (*reset_func)();
Just4pLeisure 1:d5452e398b76 393 bool (*flash_func)(const uint32_t*, uint16_t);
Just4pLeisure 1:d5452e398b76 394 uint32_t flash_size;
Just4pLeisure 1:d5452e398b76 395
Just4pLeisure 1:d5452e398b76 396 switch (type) {
Just4pLeisure 4:682d96ff6d79 397 case AMD29BL802C:
Just4pLeisure 4:682d96ff6d79 398 printf("I have found AMD29BL802C type FLASH chips; I must be connected to a T8 ECU :-)\r\n");
Just4pLeisure 4:682d96ff6d79 399 reset_func = &reset_am29;
Just4pLeisure 4:682d96ff6d79 400 flash_func = &flash_am29;
Just4pLeisure 4:682d96ff6d79 401 flash_size = T8FLASHSIZE;
Just4pLeisure 4:682d96ff6d79 402 break;
Just4pLeisure 1:d5452e398b76 403 case AMD29F400B:
Just4pLeisure 1:d5452e398b76 404 case AMD29F400T:
Just4pLeisure 1:d5452e398b76 405 printf("I have found AMD29F400 type FLASH chips; I must be connected to a T7 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 406 reset_func = &reset_am29;
Just4pLeisure 1:d5452e398b76 407 flash_func = &flash_am29;
Just4pLeisure 1:d5452e398b76 408 flash_size = T7FLASHSIZE;
Just4pLeisure 1:d5452e398b76 409 break;
Just4pLeisure 1:d5452e398b76 410 case AMD29F010:
Just4pLeisure 1:d5452e398b76 411 printf("I have found AMD29F010 type FLASH chips; I must be connected to a repaired T5.5 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 412 reset_func = &reset_am29;
Just4pLeisure 1:d5452e398b76 413 flash_func = &flash_am29;
Just4pLeisure 1:d5452e398b76 414 flash_size = T55FLASHSIZE;
Just4pLeisure 1:d5452e398b76 415 break;
Just4pLeisure 1:d5452e398b76 416 case AMD28F010:
Just4pLeisure 1:d5452e398b76 417 case INTEL28F010:
Just4pLeisure 1:d5452e398b76 418 printf("I have found 28F010 type FLASH chips; I must be connected to a T5.5 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 419 reset_func = &reset_am28;
Just4pLeisure 1:d5452e398b76 420 flash_func = &flash_am28;
Just4pLeisure 1:d5452e398b76 421 flash_size = T55FLASHSIZE;
Just4pLeisure 1:d5452e398b76 422 break;
Just4pLeisure 1:d5452e398b76 423 case AMD28F512:
Just4pLeisure 1:d5452e398b76 424 case INTEL28F512:
Just4pLeisure 1:d5452e398b76 425 printf("I have found 28F512 type FLASH chips; I must be connected to a T5.2 ECU :-)\r\n");
Just4pLeisure 1:d5452e398b76 426 reset_func = &reset_am28;
Just4pLeisure 1:d5452e398b76 427 flash_func = &flash_am28;
Just4pLeisure 1:d5452e398b76 428 flash_size = T52FLASHSIZE;
Just4pLeisure 1:d5452e398b76 429 break;
Just4pLeisure 1:d5452e398b76 430 default:
Just4pLeisure 1:d5452e398b76 431 // unknown flash type
Just4pLeisure 1:d5452e398b76 432 printf("I could not work out what FLASH chips or TRIONIC ECU I am connected to :-(\r\n");
Just4pLeisure 1:d5452e398b76 433 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 434 }
Just4pLeisure 1:d5452e398b76 435
Just4pLeisure 1:d5452e398b76 436 // reset the FLASH chips
Just4pLeisure 4:682d96ff6d79 437 printf("Reset the FLASH chip(s) to prepare them for Erasing\r\n");
Just4pLeisure 1:d5452e398b76 438 if (!reset_func()) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 439
Just4pLeisure 1:d5452e398b76 440 printf("Checking the FLASH BIN file...\r\n");
Just4pLeisure 1:d5452e398b76 441 FILE *fp = fopen("/local/modified.hex", "r"); // Open "modified.hex" on the local file system for reading
Just4pLeisure 1:d5452e398b76 442 if (!fp) {
Just4pLeisure 1:d5452e398b76 443 printf("Error: I could not find the BIN file MODIFIED.HEX\r\n");;
Just4pLeisure 1:d5452e398b76 444 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 445 }
Just4pLeisure 1:d5452e398b76 446 // obtain file size - it should match the size of the FLASH chips:
Just4pLeisure 1:d5452e398b76 447 fseek (fp , 0 , SEEK_END);
Just4pLeisure 1:d5452e398b76 448 uint32_t file_size = ftell (fp);
Just4pLeisure 1:d5452e398b76 449 rewind (fp);
Just4pLeisure 1:d5452e398b76 450
Just4pLeisure 1:d5452e398b76 451 // read the initial stack pointer value in the BIN file - it should match the value expected for the type of ECU
Just4pLeisure 1:d5452e398b76 452 uint8_t stack_byte = 0;
Just4pLeisure 1:d5452e398b76 453 uint32_t stack_long = 0;
Just4pLeisure 1:d5452e398b76 454 if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 455 stack_long |= (stack_byte << 24);
Just4pLeisure 1:d5452e398b76 456 if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 457 stack_long |= (stack_byte << 16);
Just4pLeisure 1:d5452e398b76 458 if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 459 stack_long |= (stack_byte << 8);
Just4pLeisure 1:d5452e398b76 460 if (!fread(&stack_byte,1,1,fp)) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 461 stack_long |= stack_byte;
Just4pLeisure 1:d5452e398b76 462 rewind (fp);
Just4pLeisure 1:d5452e398b76 463
Just4pLeisure 1:d5452e398b76 464 if (flash_size == T52FLASHSIZE && (file_size != T52FLASHSIZE || stack_long != T5POINTER)) {
Just4pLeisure 1:d5452e398b76 465 fclose(fp);
Just4pLeisure 1:d5452e398b76 466 printf("The BIN file does not appear to be for a T5.2 ECU :-(\r\n");
Just4pLeisure 1:d5452e398b76 467 printf("BIN file size: %#10x, FLASH chip size: %#010x, Pointer: %#10x.\r\n", file_size, flash_size, stack_long);
Just4pLeisure 1:d5452e398b76 468 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 469 }
Just4pLeisure 1:d5452e398b76 470 if (flash_size == T55FLASHSIZE && (file_size != T55FLASHSIZE || stack_long != T5POINTER)) {
Just4pLeisure 1:d5452e398b76 471 fclose(fp);
Just4pLeisure 1:d5452e398b76 472 printf("The BIN file does not appear to be for a T5.5 ECU :-(\r\n");
Just4pLeisure 1:d5452e398b76 473 printf("BIN file size: %#10x, FLASH chip size: %#010x, Pointer: %#10x.\r\n", file_size, flash_size, stack_long);
Just4pLeisure 1:d5452e398b76 474 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 475 }
Just4pLeisure 1:d5452e398b76 476 if (flash_size == T7FLASHSIZE && (file_size != T7FLASHSIZE || stack_long != T7POINTER)) {
Just4pLeisure 1:d5452e398b76 477 fclose(fp);
Just4pLeisure 1:d5452e398b76 478 printf("The BIN file does not appear to be for a T7 ECU :-(\r\n");
Just4pLeisure 1:d5452e398b76 479 printf("BIN file size: %#10x, FLASH chip size: %#010x, Pointer: %#10x.\r\n", file_size, flash_size, stack_long);
Just4pLeisure 1:d5452e398b76 480 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 481 }
Just4pLeisure 4:682d96ff6d79 482 if (flash_size == T8FLASHSIZE && (file_size != T8FLASHSIZE || stack_long != T8POINTER)) {
Just4pLeisure 4:682d96ff6d79 483 fclose(fp);
Just4pLeisure 4:682d96ff6d79 484 printf("The BIN file does not appear to be for a T8 ECU :-(\r\n");
Just4pLeisure 4:682d96ff6d79 485 printf("BIN file size: %#10x, FLASH chip size: %#010x, Pointer: %#10x.\r\n", file_size, flash_size, stack_long);
Just4pLeisure 4:682d96ff6d79 486 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 487 }
Just4pLeisure 1:d5452e398b76 488
Just4pLeisure 1:d5452e398b76 489 timer.reset();
Just4pLeisure 1:d5452e398b76 490 timer.start();
Just4pLeisure 1:d5452e398b76 491
Just4pLeisure 1:d5452e398b76 492 uint32_t curr_addr = 0;
Just4pLeisure 1:d5452e398b76 493
Just4pLeisure 1:d5452e398b76 494 switch (type) {
Just4pLeisure 1:d5452e398b76 495 // AM29Fxxx chips (retrofitted to Trionic 5.x; original to T7)
Just4pLeisure 4:682d96ff6d79 496 case AMD29BL802C:
Just4pLeisure 1:d5452e398b76 497 case AMD29F400B:
Just4pLeisure 1:d5452e398b76 498 case AMD29F400T:
Just4pLeisure 1:d5452e398b76 499 case AMD29F010:
Just4pLeisure 4:682d96ff6d79 500 printf("Erasing 29BL802/F400/010 type FLASH chips...\r\n");
Just4pLeisure 2:bf3a2b29259a 501 if (!erase_am29()) {
Just4pLeisure 1:d5452e398b76 502 printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
Just4pLeisure 1:d5452e398b76 503 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 504 }
Just4pLeisure 1:d5452e398b76 505 break;
Just4pLeisure 1:d5452e398b76 506 // AM28F010 chip (Trionic 5.x original)
Just4pLeisure 1:d5452e398b76 507 case AMD28F010:
Just4pLeisure 1:d5452e398b76 508 case INTEL28F010:
Just4pLeisure 1:d5452e398b76 509 case AMD28F512:
Just4pLeisure 1:d5452e398b76 510 case INTEL28F512:
Just4pLeisure 1:d5452e398b76 511 printf("Erasing 28F010/512 type FLASH chips...\r\n");
Just4pLeisure 2:bf3a2b29259a 512 if (!erase_am28(&curr_addr, &flash_size)) {
Just4pLeisure 1:d5452e398b76 513 printf("WARNING: An error occured when I tried to erase the FLASH chips :-(\r\n");
Just4pLeisure 1:d5452e398b76 514 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 515 }
Just4pLeisure 1:d5452e398b76 516 break;
Just4pLeisure 1:d5452e398b76 517 default:
Just4pLeisure 4:682d96ff6d79 518 // unknown flash type - shouldn't get here hence "Strange!"
Just4pLeisure 1:d5452e398b76 519 printf("Strange! I couldn't work out how to erase the FLASH chips in the TRIONIC ECU that I am connected to :-(\r\n");
Just4pLeisure 1:d5452e398b76 520 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 521 }
Just4pLeisure 1:d5452e398b76 522
Just4pLeisure 1:d5452e398b76 523 timer.stop();
Just4pLeisure 1:d5452e398b76 524 printf("Erasing took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 1:d5452e398b76 525
Just4pLeisure 1:d5452e398b76 526 printf("Programming the FLASH chips...\r\n");
Just4pLeisure 1:d5452e398b76 527
Just4pLeisure 1:d5452e398b76 528 timer.reset();
Just4pLeisure 1:d5452e398b76 529 timer.start();
Just4pLeisure 1:d5452e398b76 530
Just4pLeisure 1:d5452e398b76 531 uint16_t word_value = 0;
Just4pLeisure 1:d5452e398b76 532 uint8_t byte_value = 0;
Just4pLeisure 1:d5452e398b76 533 // bool ret = true;
Just4pLeisure 1:d5452e398b76 534
Just4pLeisure 1:d5452e398b76 535 // ready to receive data
Just4pLeisure 4:682d96ff6d79 536 printf(" 0.00 %% complete.\r");
Just4pLeisure 1:d5452e398b76 537 while (curr_addr < flash_size) {
Just4pLeisure 1:d5452e398b76 538 // receive bytes from BIN file
Just4pLeisure 1:d5452e398b76 539 //Get a byte - break if no more bytes to get
Just4pLeisure 1:d5452e398b76 540 if (!fread(&byte_value,1,1,fp)) {
Just4pLeisure 1:d5452e398b76 541 fclose(fp);
Just4pLeisure 1:d5452e398b76 542 printf("Error reading the BIN file MODIFIED.HEX");
Just4pLeisure 1:d5452e398b76 543 break;
Just4pLeisure 1:d5452e398b76 544 }
Just4pLeisure 1:d5452e398b76 545 word_value = (byte_value << 8);
Just4pLeisure 1:d5452e398b76 546 if (!fread(&byte_value,1,1,fp)) {
Just4pLeisure 1:d5452e398b76 547 fclose(fp);
Just4pLeisure 1:d5452e398b76 548 printf("Error reading the BIN file MODIFIED.HEX");
Just4pLeisure 1:d5452e398b76 549 break;
Just4pLeisure 1:d5452e398b76 550 }
Just4pLeisure 1:d5452e398b76 551 word_value |= byte_value;
Just4pLeisure 1:d5452e398b76 552
Just4pLeisure 1:d5452e398b76 553 // write the word if it is not 0xffff
Just4pLeisure 1:d5452e398b76 554 if (word_value != 0xffff) {
Just4pLeisure 1:d5452e398b76 555 if (!flash_func(&curr_addr, word_value)) break;
Just4pLeisure 1:d5452e398b76 556 }
Just4pLeisure 1:d5452e398b76 557 curr_addr += 2;
Just4pLeisure 1:d5452e398b76 558
Just4pLeisure 1:d5452e398b76 559 // make the activity LED twinkle
Just4pLeisure 4:682d96ff6d79 560 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 561 if (!(curr_addr % 0x80))
Just4pLeisure 4:682d96ff6d79 562 printf("%6.2f\r", 100*(float)curr_addr/(float)flash_size );
Just4pLeisure 1:d5452e398b76 563 }
Just4pLeisure 4:682d96ff6d79 564 printf("\n");
Just4pLeisure 1:d5452e398b76 565 timer.stop();
Just4pLeisure 1:d5452e398b76 566 fclose(fp);
Just4pLeisure 1:d5452e398b76 567
Just4pLeisure 1:d5452e398b76 568 if (curr_addr == flash_size) {
Just4pLeisure 1:d5452e398b76 569 printf("Programming took %#.1f seconds.\r\n",timer.read());
Just4pLeisure 1:d5452e398b76 570
Just4pLeisure 4:682d96ff6d79 571 // "Just4pleisure;)" 'tag' in the empty space at the end of the FLASH chip
Just4pLeisure 4:682d96ff6d79 572 // Removed for now because it conflicts with some information that Dilemma places in this empty space
Just4pLeisure 4:682d96ff6d79 573 // and because it is unsafe for Trionic 8 ECUs which have much bigger BIN files and FLASH chips
Just4pLeisure 4:682d96ff6d79 574 // reset_func();
Just4pLeisure 4:682d96ff6d79 575 // for (uint8_t i = 0; i < 8; ++i) {
Just4pLeisure 4:682d96ff6d79 576 // memread_word(&word_value, &flash_tag[i].addr);
Just4pLeisure 4:682d96ff6d79 577 // flash_func(&flash_tag[i].addr, (flash_tag[i].val & word_value));
Just4pLeisure 4:682d96ff6d79 578 // }
Just4pLeisure 4:682d96ff6d79 579
Just4pLeisure 4:682d96ff6d79 580 } else
Just4pLeisure 1:d5452e398b76 581 printf("WARNING: Oh dear, I couldn't program the FLASH at address 0x%8x.\r\n", curr_addr);
Just4pLeisure 1:d5452e398b76 582
Just4pLeisure 4:682d96ff6d79 583 // reset flash
Just4pLeisure 1:d5452e398b76 584 return (reset_func() && (curr_addr == flash_size)) ? TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 585 }
Just4pLeisure 1:d5452e398b76 586
Just4pLeisure 1:d5452e398b76 587 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 588 /**
Just4pLeisure 4:682d96ff6d79 589 Resets an AM29Fxxx flash memory chip. MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 590
Just4pLeisure 4:682d96ff6d79 591 @param none
Just4pLeisure 1:d5452e398b76 592
Just4pLeisure 4:682d96ff6d79 593 @return succ / fail
Just4pLeisure 1:d5452e398b76 594 */
Just4pLeisure 4:682d96ff6d79 595 bool reset_am29(void)
Just4pLeisure 4:682d96ff6d79 596 {
Just4pLeisure 1:d5452e398b76 597 // execute the reset command
Just4pLeisure 4:682d96ff6d79 598 // uint32_t addr = 0xfffe;
Just4pLeisure 4:682d96ff6d79 599 // return (memwrite_word(&addr, 0xf0f0) == TERM_OK);
Just4pLeisure 1:d5452e398b76 600 // execute the algorithm
Just4pLeisure 1:d5452e398b76 601 for (uint8_t i = 0; i < 3; ++i) {
Just4pLeisure 1:d5452e398b76 602 if (memwrite_word(&am29_reset[i].addr, am29_reset[i].val) != TERM_OK) return false;
Just4pLeisure 1:d5452e398b76 603 }
Just4pLeisure 1:d5452e398b76 604 return true;
Just4pLeisure 1:d5452e398b76 605 }
Just4pLeisure 1:d5452e398b76 606
Just4pLeisure 1:d5452e398b76 607 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 608 /**
Just4pLeisure 4:682d96ff6d79 609 Erases an AM29Fxxx flash memory chip and verifies the result; MCU must be
Just4pLeisure 4:682d96ff6d79 610 in background mode.
Just4pLeisure 1:d5452e398b76 611
Just4pLeisure 4:682d96ff6d79 612 @return succ / fail
Just4pLeisure 1:d5452e398b76 613 */
Just4pLeisure 4:682d96ff6d79 614 bool erase_am29()
Just4pLeisure 4:682d96ff6d79 615 {
Just4pLeisure 1:d5452e398b76 616 // reset flash
Just4pLeisure 1:d5452e398b76 617 if (!reset_am29()) {
Just4pLeisure 1:d5452e398b76 618 return false;
Just4pLeisure 1:d5452e398b76 619 }
Just4pLeisure 4:682d96ff6d79 620 printf("Erasing AMD 29Fxxx FLASH chips.\r\n");
Just4pLeisure 4:682d96ff6d79 621 printf("This can take up to a minute for a T8,\r\n");
Just4pLeisure 4:682d96ff6d79 622 printf("30s for a T7 or 15s for a T5 ECU.\r\n");
Just4pLeisure 1:d5452e398b76 623 // execute the algorithm
Just4pLeisure 1:d5452e398b76 624 for (uint8_t i = 0; i < 6; ++i) {
Just4pLeisure 1:d5452e398b76 625 if (memwrite_word(&am29_erase[i].addr, am29_erase[i].val) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 626 reset_am29();
Just4pLeisure 1:d5452e398b76 627 return false;
Just4pLeisure 1:d5452e398b76 628 }
Just4pLeisure 1:d5452e398b76 629 }
Just4pLeisure 1:d5452e398b76 630
Just4pLeisure 1:d5452e398b76 631 // verify the result
Just4pLeisure 1:d5452e398b76 632 uint32_t addr = 0x0;
Just4pLeisure 1:d5452e398b76 633 uint16_t verify_value;
Just4pLeisure 1:d5452e398b76 634
Just4pLeisure 4:682d96ff6d79 635 printf(" 0.0 seconds.\r");
Just4pLeisure 1:d5452e398b76 636 uint8_t err_cnt = ERR_COUNT;
Just4pLeisure 1:d5452e398b76 637 while (--err_cnt) {
Just4pLeisure 1:d5452e398b76 638 // typical erase time = 1s
Just4pLeisure 1:d5452e398b76 639 // Allow up to 25.5 seconds erase time
Just4pLeisure 1:d5452e398b76 640 wait_ms(100);
Just4pLeisure 4:682d96ff6d79 641 wait_ms(100);
Just4pLeisure 1:d5452e398b76 642 if (memread_word(&verify_value, &addr) == TERM_OK && verify_value == 0xffff) {
Just4pLeisure 1:d5452e398b76 643 // erase completed normally
Just4pLeisure 1:d5452e398b76 644 reset_am29();
Just4pLeisure 4:682d96ff6d79 645 printf("\n");
Just4pLeisure 1:d5452e398b76 646 return true;
Just4pLeisure 1:d5452e398b76 647 }
Just4pLeisure 4:682d96ff6d79 648 // make the activity LED twinkle
Just4pLeisure 4:682d96ff6d79 649 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 650 printf("%4.1f\r", (float)ERR_COUNT/5 - (float)err_cnt/5 );
Just4pLeisure 1:d5452e398b76 651 }
Just4pLeisure 4:682d96ff6d79 652 printf("\n");
Just4pLeisure 1:d5452e398b76 653
Just4pLeisure 1:d5452e398b76 654 // erase failed
Just4pLeisure 1:d5452e398b76 655 reset_am29();
Just4pLeisure 1:d5452e398b76 656 return false;
Just4pLeisure 1:d5452e398b76 657 }
Just4pLeisure 1:d5452e398b76 658
Just4pLeisure 1:d5452e398b76 659 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 660 /**
Just4pLeisure 4:682d96ff6d79 661 Writes a word to AM29Fxxx flash memory chip and optionally verifies the
Just4pLeisure 4:682d96ff6d79 662 result; MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 663
Just4pLeisure 4:682d96ff6d79 664 @param addr destination address
Just4pLeisure 4:682d96ff6d79 665 @param val value
Just4pLeisure 1:d5452e398b76 666
Just4pLeisure 4:682d96ff6d79 667 @return succ / fail
Just4pLeisure 1:d5452e398b76 668 */
Just4pLeisure 4:682d96ff6d79 669 bool flash_am29(const uint32_t* addr, uint16_t value)
Just4pLeisure 4:682d96ff6d79 670 {
Just4pLeisure 1:d5452e398b76 671
Just4pLeisure 1:d5452e398b76 672 // execute the algorithm
Just4pLeisure 1:d5452e398b76 673 for (uint8_t i = 0; i < 3; ++i) {
Just4pLeisure 1:d5452e398b76 674 if (memwrite_word(&am29_write[i].addr, am29_write[i].val) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 675 reset_am29();
Just4pLeisure 1:d5452e398b76 676 return false;
Just4pLeisure 1:d5452e398b76 677 }
Just4pLeisure 1:d5452e398b76 678 }
Just4pLeisure 1:d5452e398b76 679 // write the value
Just4pLeisure 1:d5452e398b76 680 if (memwrite_word(addr, value) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 681 reset_am29();
Just4pLeisure 1:d5452e398b76 682 return false;
Just4pLeisure 1:d5452e398b76 683 }
Just4pLeisure 1:d5452e398b76 684 // verify the result
Just4pLeisure 1:d5452e398b76 685 uint8_t err_cnt = ERR_COUNT;
Just4pLeisure 1:d5452e398b76 686 while (--err_cnt) {
Just4pLeisure 1:d5452e398b76 687 // Allow up to approx 2.55 milliseconds program time (255 * ~10us BDM memread time)
Just4pLeisure 4:682d96ff6d79 688 // wait_ms(10);
Just4pLeisure 4:682d96ff6d79 689 wait_us(100);
Just4pLeisure 1:d5452e398b76 690 uint16_t verify_value;
Just4pLeisure 1:d5452e398b76 691 if ((memread_word(&verify_value, addr) == TERM_OK) &&
Just4pLeisure 1:d5452e398b76 692 (verify_value == value)) {
Just4pLeisure 1:d5452e398b76 693 // flashing successful
Just4pLeisure 1:d5452e398b76 694 return true;
Just4pLeisure 1:d5452e398b76 695 }
Just4pLeisure 1:d5452e398b76 696 }
Just4pLeisure 1:d5452e398b76 697 // writing failed
Just4pLeisure 1:d5452e398b76 698 reset_am29();
Just4pLeisure 1:d5452e398b76 699 return false;
Just4pLeisure 1:d5452e398b76 700 }
Just4pLeisure 1:d5452e398b76 701
Just4pLeisure 1:d5452e398b76 702 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 703 /**
Just4pLeisure 4:682d96ff6d79 704 Resets a AM28Fxxx flash memory chip. MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 705
Just4pLeisure 4:682d96ff6d79 706 @param start_addr flash start address
Just4pLeisure 1:d5452e398b76 707
Just4pLeisure 4:682d96ff6d79 708 @return succ / fail
Just4pLeisure 1:d5452e398b76 709 */
Just4pLeisure 4:682d96ff6d79 710 bool reset_am28(void)
Just4pLeisure 4:682d96ff6d79 711 {
Just4pLeisure 1:d5452e398b76 712 uint32_t start_addr = 0x0;
Just4pLeisure 2:bf3a2b29259a 713 return (memwrite_word_write_word(&start_addr, 0xffff, 0xffff) == TERM_OK);
Just4pLeisure 1:d5452e398b76 714 }
Just4pLeisure 1:d5452e398b76 715
Just4pLeisure 1:d5452e398b76 716 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 717 /**
Just4pLeisure 4:682d96ff6d79 718 Erases an AM28Fxxx flash memory chip and verifies the result; MCU must be
Just4pLeisure 4:682d96ff6d79 719 in background mode.
Just4pLeisure 1:d5452e398b76 720
Just4pLeisure 4:682d96ff6d79 721 @param start_addr flash start address
Just4pLeisure 4:682d96ff6d79 722 @param end_addr flash end address
Just4pLeisure 1:d5452e398b76 723
Just4pLeisure 4:682d96ff6d79 724 @return succ / fail
Just4pLeisure 1:d5452e398b76 725 */
Just4pLeisure 4:682d96ff6d79 726 bool erase_am28(const uint32_t* start_addr, const uint32_t* end_addr)
Just4pLeisure 4:682d96ff6d79 727 {
Just4pLeisure 1:d5452e398b76 728
Just4pLeisure 1:d5452e398b76 729 // check the addresses
Just4pLeisure 1:d5452e398b76 730 if (!start_addr || !end_addr) return false;
Just4pLeisure 1:d5452e398b76 731
Just4pLeisure 1:d5452e398b76 732 // reset flash
Just4pLeisure 1:d5452e398b76 733 if (!reset_am28()) return false;
Just4pLeisure 1:d5452e398b76 734
Just4pLeisure 1:d5452e398b76 735 // write zeroes over entire flash space
Just4pLeisure 1:d5452e398b76 736 uint32_t addr = *start_addr;
Just4pLeisure 1:d5452e398b76 737
Just4pLeisure 4:682d96ff6d79 738 printf("First write 0x00 to all FLASH addresses.\r\n");
Just4pLeisure 4:682d96ff6d79 739 printf(" 0.00 %% complete.\r");
Just4pLeisure 1:d5452e398b76 740 while (addr < *end_addr) {
Just4pLeisure 1:d5452e398b76 741 if (!flash_am28(&addr, 0x0000)) return false;
Just4pLeisure 1:d5452e398b76 742 addr += 2;
Just4pLeisure 4:682d96ff6d79 743 // // feedback to host computer
Just4pLeisure 4:682d96ff6d79 744 // pc.putc(TERM_OK);
Just4pLeisure 1:d5452e398b76 745 // make the activity LED twinkle
Just4pLeisure 4:682d96ff6d79 746 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 747 if (!(addr % 0x80))
Just4pLeisure 4:682d96ff6d79 748 printf("%6.2f\r", 100*(float)addr/(float)*end_addr );
Just4pLeisure 1:d5452e398b76 749 }
Just4pLeisure 4:682d96ff6d79 750 printf("\n");
Just4pLeisure 1:d5452e398b76 751
Just4pLeisure 1:d5452e398b76 752 // erase flash
Just4pLeisure 1:d5452e398b76 753 addr = *start_addr;
Just4pLeisure 1:d5452e398b76 754 uint8_t verify_value;
Just4pLeisure 1:d5452e398b76 755
Just4pLeisure 4:682d96ff6d79 756 printf("Now erasing FLASH and verfiying that all addresses are 0xFF.\r\n");
Just4pLeisure 4:682d96ff6d79 757 printf(" 0.00 %% complete.\r");
Just4pLeisure 1:d5452e398b76 758 uint16_t pulse_cnt = 0;
Just4pLeisure 1:d5452e398b76 759 if (memwrite_byte_cmd(NULL) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 760 reset_am28();
Just4pLeisure 1:d5452e398b76 761 return false;
Just4pLeisure 1:d5452e398b76 762 }
Just4pLeisure 1:d5452e398b76 763 while ((++pulse_cnt < 1000) && (addr < *end_addr)) {
Just4pLeisure 1:d5452e398b76 764 // issue the erase command
Just4pLeisure 1:d5452e398b76 765 if (memwrite_write_byte(&addr, 0x20) != TERM_OK ||
Just4pLeisure 1:d5452e398b76 766 memwrite_write_byte(&addr, 0x20) != TERM_OK) break;
Just4pLeisure 1:d5452e398b76 767 wait_ms(10);
Just4pLeisure 1:d5452e398b76 768
Just4pLeisure 1:d5452e398b76 769 while (addr < *end_addr) {
Just4pLeisure 1:d5452e398b76 770 // issue the verify command
Just4pLeisure 1:d5452e398b76 771 if (memwrite_read_byte(&addr, 0xa0) != TERM_OK) break;
Just4pLeisure 4:682d96ff6d79 772 // wait_us(6);
Just4pLeisure 1:d5452e398b76 773 // check the written value
Just4pLeisure 1:d5452e398b76 774 if (memread_write_byte(&verify_value, &addr) != TERM_OK) break;
Just4pLeisure 1:d5452e398b76 775 if (verify_value != 0xff) break;
Just4pLeisure 1:d5452e398b76 776 // succeeded need to check next address
Just4pLeisure 1:d5452e398b76 777 addr++;
Just4pLeisure 1:d5452e398b76 778 // make the activity LED twinkle
Just4pLeisure 4:682d96ff6d79 779 ACTIVITYLEDON;
Just4pLeisure 4:682d96ff6d79 780 if (!(addr % 0x80))
Just4pLeisure 4:682d96ff6d79 781 printf("%6.2f\r", 100*(float)addr/(float)*end_addr );
Just4pLeisure 1:d5452e398b76 782 }
Just4pLeisure 1:d5452e398b76 783 }
Just4pLeisure 4:682d96ff6d79 784 printf("\n");
Just4pLeisure 1:d5452e398b76 785 // the erase process ends with a BDM_WRITE + BDM_BYTESIZE command left in the BDM
Just4pLeisure 1:d5452e398b76 786 // it is safe to use it to put one of the FLASH chips into read mode and thereby
Just4pLeisure 1:d5452e398b76 787 // leave the BDM ready for the next command
Just4pLeisure 1:d5452e398b76 788 memwrite_nop_byte(start_addr, 0x00);
Just4pLeisure 1:d5452e398b76 789
Just4pLeisure 1:d5452e398b76 790 reset_am28();
Just4pLeisure 1:d5452e398b76 791 // check for success
Just4pLeisure 1:d5452e398b76 792 return (addr == *end_addr) ? true : false;
Just4pLeisure 1:d5452e398b76 793 }
Just4pLeisure 1:d5452e398b76 794
Just4pLeisure 1:d5452e398b76 795 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 796 /**
Just4pLeisure 4:682d96ff6d79 797 Writes a byte to AM28Fxxx flash memory chip and verifies the result
Just4pLeisure 4:682d96ff6d79 798 A so called 'mask' method checks the FLASH contents and only tries
Just4pLeisure 4:682d96ff6d79 799 to program bytes that need to be programmed.
Just4pLeisure 4:682d96ff6d79 800 MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 801
Just4pLeisure 4:682d96ff6d79 802 @param addr destination address
Just4pLeisure 4:682d96ff6d79 803 @param val value
Just4pLeisure 1:d5452e398b76 804
Just4pLeisure 4:682d96ff6d79 805 @return succ / fail
Just4pLeisure 1:d5452e398b76 806 */
Just4pLeisure 4:682d96ff6d79 807 bool flash_am28(const uint32_t* addr, uint16_t value)
Just4pLeisure 4:682d96ff6d79 808 {
Just4pLeisure 1:d5452e398b76 809
Just4pLeisure 1:d5452e398b76 810 if (!addr) return false;
Just4pLeisure 1:d5452e398b76 811
Just4pLeisure 1:d5452e398b76 812 uint8_t pulse_cnt = 0;
Just4pLeisure 1:d5452e398b76 813 uint16_t verify_value = 0;
Just4pLeisure 1:d5452e398b76 814 uint16_t mask_value = 0xffff;
Just4pLeisure 1:d5452e398b76 815
Just4pLeisure 1:d5452e398b76 816 // put flash into read mode and read address
Just4pLeisure 1:d5452e398b76 817 if (memwrite_word_read_word(&verify_value, addr, 0x0000) != TERM_OK) return false;
Just4pLeisure 1:d5452e398b76 818 // return if FLASH already has the correct value - e.g. not all of the FLASH is used and is 0xff
Just4pLeisure 1:d5452e398b76 819 if (verify_value == value) return true;
Just4pLeisure 1:d5452e398b76 820
Just4pLeisure 1:d5452e398b76 821 while (++pulse_cnt < 25) {
Just4pLeisure 1:d5452e398b76 822
Just4pLeisure 1:d5452e398b76 823 // set a mask
Just4pLeisure 2:bf3a2b29259a 824 if ((uint8_t)verify_value == (uint8_t)value)
Just4pLeisure 2:bf3a2b29259a 825 mask_value &= 0xff00;
Just4pLeisure 2:bf3a2b29259a 826 if ((uint8_t)(verify_value >> 8) == (uint8_t)(value >> 8))
Just4pLeisure 2:bf3a2b29259a 827 mask_value &= 0x00ff;
Just4pLeisure 1:d5452e398b76 828
Just4pLeisure 1:d5452e398b76 829 // write the new value
Just4pLeisure 1:d5452e398b76 830 if (memwrite_word_write_word(addr, (0x4040 & mask_value), value) != TERM_OK) break;
Just4pLeisure 1:d5452e398b76 831 // NOTE the BDM interface is slow enough that there is no need for a 10us delay before verifying
Just4pLeisure 1:d5452e398b76 832 // issue the verification command
Just4pLeisure 1:d5452e398b76 833 // NOTE the BDM interface is slow enough that there is no need for a 6us delay before reading back
Just4pLeisure 1:d5452e398b76 834 if (memwrite_word_read_word(&verify_value, addr, (0xc0c0 & mask_value)) != TERM_OK) break;
Just4pLeisure 1:d5452e398b76 835 // check if flashing was successful;
Just4pLeisure 1:d5452e398b76 836 if (verify_value == value) return true;
Just4pLeisure 1:d5452e398b76 837 }
Just4pLeisure 1:d5452e398b76 838
Just4pLeisure 1:d5452e398b76 839 // something went wrong; reset the flash chip and return failed
Just4pLeisure 1:d5452e398b76 840 reset_am28();
Just4pLeisure 1:d5452e398b76 841 return false;
Just4pLeisure 1:d5452e398b76 842 }
Just4pLeisure 1:d5452e398b76 843
Just4pLeisure 1:d5452e398b76 844 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 845 /**
Just4pLeisure 4:682d96ff6d79 846 Does the equivalent of do prept5.do in BD32
Just4pLeisure 4:682d96ff6d79 847 Sets up all of the control registers in the MC68332 so that we can program
Just4pLeisure 4:682d96ff6d79 848 the FLASH chips
Just4pLeisure 1:d5452e398b76 849
Just4pLeisure 4:682d96ff6d79 850 @param none
Just4pLeisure 1:d5452e398b76 851
Just4pLeisure 4:682d96ff6d79 852 @return succ / fail
Just4pLeisure 1:d5452e398b76 853 */
Just4pLeisure 1:d5452e398b76 854
Just4pLeisure 4:682d96ff6d79 855 //uint8_t prep_t5_do(void) {
Just4pLeisure 4:682d96ff6d79 856 uint8_t prep_t8_do(void)
Just4pLeisure 4:682d96ff6d79 857 {
Just4pLeisure 1:d5452e398b76 858
Just4pLeisure 1:d5452e398b76 859 // reset and freeze the MC68332 chip
Just4pLeisure 1:d5452e398b76 860 if (restart_chip() != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 861
Just4pLeisure 1:d5452e398b76 862 // set the 'fc' registers to allow supervisor mode access
Just4pLeisure 1:d5452e398b76 863 uint32_t long_value = 0x05;
Just4pLeisure 1:d5452e398b76 864 if (sysreg_write(0x0e, &long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 865 if (sysreg_write(0x0f, &long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 866
Just4pLeisure 4:682d96ff6d79 867 // Set MC68332 to 16 MHz (actually 16.78 MHz) (SYNCR)
Just4pLeisure 1:d5452e398b76 868 long_value = 0x00fffa04;
Just4pLeisure 1:d5452e398b76 869 if (memwrite_word(&long_value, 0x7f00) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 870
Just4pLeisure 4:682d96ff6d79 871 // Disable watchdog and monitors (SYPCR)
Just4pLeisure 1:d5452e398b76 872 long_value = 0x00fffa21;
Just4pLeisure 1:d5452e398b76 873 if (memwrite_byte(&long_value, 0x00) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 874
Just4pLeisure 4:682d96ff6d79 875
Just4pLeisure 4:682d96ff6d79 876 // Chip select pin assignments (CSPAR0)
Just4pLeisure 1:d5452e398b76 877 long_value = 0x00fffa44;
Just4pLeisure 1:d5452e398b76 878 if (memwrite_word(&long_value, 0x3fff) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 879
Just4pLeisure 4:682d96ff6d79 880 // Boot Chip select read only, one wait state (CSBARBT)
Just4pLeisure 1:d5452e398b76 881 long_value = 0x00fffa48;
Just4pLeisure 1:d5452e398b76 882 if (memwrite_word(&long_value, 0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 883 if (memfill_word(0x6870) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 884
Just4pLeisure 4:682d96ff6d79 885 // Chip select 1 and 2 upper lower bytes, zero wait states (CSBAR1, CSOR1, CSBAR2, CSBAR2)
Just4pLeisure 1:d5452e398b76 886 long_value = 0x00fffa50;
Just4pLeisure 1:d5452e398b76 887 if (memwrite_word(&long_value, 0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 888 if (memfill_word(0x3030) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 889 if (memfill_word(0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 890 if (memfill_word(0x5030) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 891
Just4pLeisure 4:682d96ff6d79 892 // PQS Data - turn on VPPH (PORTQS)
Just4pLeisure 1:d5452e398b76 893 long_value = 0x00fffc14;
Just4pLeisure 1:d5452e398b76 894 if (memwrite_word(&long_value, 0x0040) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 895
Just4pLeisure 4:682d96ff6d79 896 // PQS Data Direction output (DDRQS)
Just4pLeisure 1:d5452e398b76 897 long_value = 0x00fffc17;
Just4pLeisure 1:d5452e398b76 898 if (memwrite_byte(&long_value, 0x40) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 899 // wait for programming voltage to be ready
Just4pLeisure 1:d5452e398b76 900 wait_ms(10);
Just4pLeisure 1:d5452e398b76 901
Just4pLeisure 4:682d96ff6d79 902 // // Enable internal 2kByte RAM of 68332 at address 0x00100000 (TRAMBAR)
Just4pLeisure 4:682d96ff6d79 903 // long_value = 0x00fffb04;
Just4pLeisure 4:682d96ff6d79 904 // if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR;
Just4pLeisure 1:d5452e398b76 905 return TERM_OK;
Just4pLeisure 1:d5452e398b76 906 }
Just4pLeisure 1:d5452e398b76 907
Just4pLeisure 1:d5452e398b76 908 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 909 /**
Just4pLeisure 4:682d96ff6d79 910 Does the equivalent of do prept5/7/8.do in BD32
Just4pLeisure 4:682d96ff6d79 911 Sets up all of the control registers in the MC68332/377 so that we can
Just4pLeisure 4:682d96ff6d79 912 program the FLASH chips
Just4pLeisure 4:682d96ff6d79 913
Just4pLeisure 4:682d96ff6d79 914 @param none
Just4pLeisure 4:682d96ff6d79 915
Just4pLeisure 4:682d96ff6d79 916 @return succ / fail
Just4pLeisure 4:682d96ff6d79 917 */
Just4pLeisure 4:682d96ff6d79 918
Just4pLeisure 4:682d96ff6d79 919 uint8_t prep_t5_do(void)
Just4pLeisure 4:682d96ff6d79 920 {
Just4pLeisure 4:682d96ff6d79 921
Just4pLeisure 4:682d96ff6d79 922 // reset and freeze the MC68332/377 chip
Just4pLeisure 4:682d96ff6d79 923 if (restart_chip() != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 924
Just4pLeisure 4:682d96ff6d79 925 // define some variables to store address and data values
Just4pLeisure 4:682d96ff6d79 926 uint32_t long_value = 0x05;
Just4pLeisure 4:682d96ff6d79 927 uint16_t verify_value;
Just4pLeisure 4:682d96ff6d79 928
Just4pLeisure 4:682d96ff6d79 929 // set the 'fc' registers to allow supervisor mode access
Just4pLeisure 4:682d96ff6d79 930 if (sysreg_write(0x0e, &long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 931 if (sysreg_write(0x0f, &long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 932
Just4pLeisure 4:682d96ff6d79 933 // Read MC68332/377 Module Control Register (SIMCR/MCR)
Just4pLeisure 4:682d96ff6d79 934 // and use the value to work out if ECU is a T5/7 or a T8
Just4pLeisure 4:682d96ff6d79 935 long_value = 0x00fffa00;
Just4pLeisure 4:682d96ff6d79 936 if (memread_word(&verify_value, &long_value) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 937 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Just4pLeisure 4:682d96ff6d79 938 // verify_value = 0x7E4F;
Just4pLeisure 4:682d96ff6d79 939 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Just4pLeisure 4:682d96ff6d79 940 // MC68377 MCR = x111111x01001111 binary after a reset
Just4pLeisure 4:682d96ff6d79 941 if ((verify_value & 0x7E4F) == 0x7E4F) {
Just4pLeisure 4:682d96ff6d79 942 printf ("I have found a Trionic 8 ECU.\r\n");
Just4pLeisure 4:682d96ff6d79 943 // Set MC68377 to double it's default speed (16 MHz?) (SYNCR)
Just4pLeisure 4:682d96ff6d79 944 long_value = 0x00fffa08;
Just4pLeisure 4:682d96ff6d79 945 // First set the MFD part (change 4x to 8x)
Just4pLeisure 4:682d96ff6d79 946 if (memwrite_word(&long_value, 0x6908) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 947 // wait for everything to settle (should really check the PLL lock register)
Just4pLeisure 4:682d96ff6d79 948 wait_ms(100);
Just4pLeisure 4:682d96ff6d79 949 // Now set the RFD part (change /2 to /1)
Just4pLeisure 4:682d96ff6d79 950 if (memwrite_word(&long_value, 0x6808) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 951 // Disable watchdog and monitors (SYPCR)
Just4pLeisure 4:682d96ff6d79 952 long_value = 0x00fffa50;
Just4pLeisure 4:682d96ff6d79 953 if (memwrite_word(&long_value, 0x0000) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 954 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 955 }
Just4pLeisure 4:682d96ff6d79 956 // MC68332 SIMCR = 0000x00011001111 binary after a reset
Just4pLeisure 4:682d96ff6d79 957 //if ((verify_value & 0x00CF) == 0x00CF) {
Just4pLeisure 4:682d96ff6d79 958 else {
Just4pLeisure 4:682d96ff6d79 959 printf ("I have found a Trionic 5 or 7 ECU.\r\n");
Just4pLeisure 4:682d96ff6d79 960 // Set MC68332 to 16 MHz (actually 16.78 MHz) (SYNCR)
Just4pLeisure 4:682d96ff6d79 961 long_value = 0x00fffa04;
Just4pLeisure 4:682d96ff6d79 962 if (memwrite_word(&long_value, 0x7f00) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 963 // Disable watchdog and monitors (SYPCR)
Just4pLeisure 4:682d96ff6d79 964 long_value = 0x00fffa21;
Just4pLeisure 4:682d96ff6d79 965 if (memwrite_byte(&long_value, 0x00) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 966 // Chip select pin assignments (CSPAR0)
Just4pLeisure 4:682d96ff6d79 967 long_value = 0x00fffa44;
Just4pLeisure 4:682d96ff6d79 968 if (memwrite_word(&long_value, 0x3fff) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 969 // Boot Chip select read only, one wait state (CSBARBT)
Just4pLeisure 4:682d96ff6d79 970 long_value = 0x00fffa48;
Just4pLeisure 4:682d96ff6d79 971 if (memwrite_word(&long_value, 0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 972 if (memfill_word(0x6870) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 973 // Chip select 1 and 2 upper lower bytes, zero wait states (CSBAR1, CSOR1, CSBAR2, CSBAR2)
Just4pLeisure 4:682d96ff6d79 974 long_value = 0x00fffa50;
Just4pLeisure 4:682d96ff6d79 975 if (memwrite_word(&long_value, 0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 976 if (memfill_word(0x3030) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 977 if (memfill_word(0x0007) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 978 if (memfill_word(0x5030) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 979 // PQS Data - turn on VPPH (PORTQS)
Just4pLeisure 4:682d96ff6d79 980 long_value = 0x00fffc14;
Just4pLeisure 4:682d96ff6d79 981 if (memwrite_word(&long_value, 0x0040) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 982 // PQS Data Direction output (DDRQS)
Just4pLeisure 4:682d96ff6d79 983 long_value = 0x00fffc17;
Just4pLeisure 4:682d96ff6d79 984 if (memwrite_byte(&long_value, 0x40) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 985 // wait for programming voltage to be ready
Just4pLeisure 4:682d96ff6d79 986 wait_ms(10);
Just4pLeisure 4:682d96ff6d79 987 // Enable internal 2kByte RAM of 68332 at address 0x00100000 (TRAMBAR)
Just4pLeisure 4:682d96ff6d79 988 //long_value = 0x00fffb04;
Just4pLeisure 4:682d96ff6d79 989 //if (memwrite_word(&long_value, 0x1000) != TERM_OK) return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 990 return TERM_OK;
Just4pLeisure 4:682d96ff6d79 991 }
Just4pLeisure 4:682d96ff6d79 992 // Unknown MC683xx chip if code reaches this point
Just4pLeisure 4:682d96ff6d79 993 return TERM_ERR;
Just4pLeisure 4:682d96ff6d79 994 }
Just4pLeisure 4:682d96ff6d79 995
Just4pLeisure 4:682d96ff6d79 996
Just4pLeisure 4:682d96ff6d79 997 //-----------------------------------------------------------------------------
Just4pLeisure 4:682d96ff6d79 998 /**
Just4pLeisure 1:d5452e398b76 999 Works out what type of flash chip is fitted in the ECU by reading
Just4pLeisure 1:d5452e398b76 1000 the manufacturer byte codes.
Just4pLeisure 1:d5452e398b76 1001 It is enough to use the 29Fxxx flash id algorithm because 28Fxxx
Just4pLeisure 1:d5452e398b76 1002 FLASH chips ignore the first few writes needed by the 29Fxxx chips
Just4pLeisure 1:d5452e398b76 1003 MCU must be in background mode.
Just4pLeisure 1:d5452e398b76 1004
Just4pLeisure 1:d5452e398b76 1005 @param make (out)
Just4pLeisure 1:d5452e398b76 1006 type (out)
Just4pLeisure 1:d5452e398b76 1007
Just4pLeisure 1:d5452e398b76 1008 @return succ / fail
Just4pLeisure 1:d5452e398b76 1009 */
Just4pLeisure 4:682d96ff6d79 1010 bool get_flash_id(uint8_t* make, uint8_t* type)
Just4pLeisure 4:682d96ff6d79 1011 {
Just4pLeisure 1:d5452e398b76 1012
Just4pLeisure 1:d5452e398b76 1013 uint32_t addr = 0x0;
Just4pLeisure 1:d5452e398b76 1014 uint32_t value;
Just4pLeisure 1:d5452e398b76 1015 bool ret;
Just4pLeisure 1:d5452e398b76 1016 // read id bytes algorithm for 29F010/400 FLASH chips
Just4pLeisure 1:d5452e398b76 1017 for (uint8_t i = 0; i < 3; ++i) {
Just4pLeisure 4:682d96ff6d79 1018 //printf("Getting FLASH chip ID.\r\n");
Just4pLeisure 4:682d96ff6d79 1019 if (memwrite_word(&am29_id[i].addr, am29_id[i].val) != TERM_OK) {
Just4pLeisure 4:682d96ff6d79 1020 printf("There was an error when I tried to request the FLASH chip ID.\r\n");
Just4pLeisure 4:682d96ff6d79 1021 return false;
Just4pLeisure 4:682d96ff6d79 1022 }
Just4pLeisure 1:d5452e398b76 1023 }
Just4pLeisure 4:682d96ff6d79 1024 if (memread_long(&value, &addr) != TERM_OK) {
Just4pLeisure 4:682d96ff6d79 1025 printf("Error Reading FLASH chip types in get_flash_id\r\n");
Just4pLeisure 4:682d96ff6d79 1026 return false;
Just4pLeisure 4:682d96ff6d79 1027 }
Just4pLeisure 2:bf3a2b29259a 1028 // *make = (uint8_t)(value >> 24);
Just4pLeisure 2:bf3a2b29259a 1029 // *type = (uint8_t)(value >> 8);
Just4pLeisure 2:bf3a2b29259a 1030 *make = (uint8_t)(value >> 16);
Just4pLeisure 2:bf3a2b29259a 1031 *type = (uint8_t)(value);
Just4pLeisure 1:d5452e398b76 1032 printf("FLASH id bytes: %08x, make: %02x, type: %02x\r\n", value, *make, *type);
Just4pLeisure 1:d5452e398b76 1033 switch (*type) {
Just4pLeisure 4:682d96ff6d79 1034 case AMD29BL802C:
Just4pLeisure 1:d5452e398b76 1035 case AMD29F400B:
Just4pLeisure 1:d5452e398b76 1036 case AMD29F400T:
Just4pLeisure 1:d5452e398b76 1037 case AMD29F010:
Just4pLeisure 1:d5452e398b76 1038 case AMD28F010:
Just4pLeisure 1:d5452e398b76 1039 case INTEL28F010:
Just4pLeisure 1:d5452e398b76 1040 case AMD28F512:
Just4pLeisure 1:d5452e398b76 1041 case INTEL28F512:
Just4pLeisure 1:d5452e398b76 1042 ret = true;
Just4pLeisure 1:d5452e398b76 1043 default:
Just4pLeisure 1:d5452e398b76 1044 ret = false;
Just4pLeisure 1:d5452e398b76 1045 }
Just4pLeisure 1:d5452e398b76 1046 return ret;
Just4pLeisure 1:d5452e398b76 1047 }
Just4pLeisure 1:d5452e398b76 1048
Just4pLeisure 1:d5452e398b76 1049 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 1050 // EOF
Just4pLeisure 1:d5452e398b76 1051 //-----------------------------------------------------------------------------