Just4Trionic - CAN and BDM FLASH programmer for Saab cars

Dependencies:   mbed

Committer:
Just4pLeisure
Date:
Sat Apr 25 17:07:08 2015 +0000
Revision:
5:1775b4b13232
Version 1.5 Is a significant milestone.; ; Supports BDM and CAN read and write of T5.x, T7 and T8 ECU's plus T8 recovery.; A Target Resident Driver for BDM gives a big speed boost.; Supports many alternative replacement FLASH chips for T5.x ECU's;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Just4pLeisure 5:1775b4b13232 1 /*******************************************************************************
Just4pLeisure 5:1775b4b13232 2
Just4pLeisure 5:1775b4b13232 3 bdmdriver.cpp
Just4pLeisure 5:1775b4b13232 4 (c) 2014 by Sophie Dexter
Just4pLeisure 5:1775b4b13232 5
Just4pLeisure 5:1775b4b13232 6 BD32 like 'syscall' processor for BDM resident driver functions
Just4pLeisure 5:1775b4b13232 7
Just4pLeisure 5:1775b4b13232 8 ********************************************************************************
Just4pLeisure 5:1775b4b13232 9
Just4pLeisure 5:1775b4b13232 10 WARNING: Use at your own risk, sadly this software comes with no guarantees.
Just4pLeisure 5:1775b4b13232 11 This software is provided 'free' and in good faith, but the author does not
Just4pLeisure 5:1775b4b13232 12 accept liability for any damage arising from its use.
Just4pLeisure 5:1775b4b13232 13
Just4pLeisure 5:1775b4b13232 14 *******************************************************************************/
Just4pLeisure 5:1775b4b13232 15
Just4pLeisure 5:1775b4b13232 16 #include "bdmdriver.h"
Just4pLeisure 5:1775b4b13232 17
Just4pLeisure 5:1775b4b13232 18 FILE *fp = NULL;
Just4pLeisure 5:1775b4b13232 19
Just4pLeisure 5:1775b4b13232 20 //private functions
Just4pLeisure 5:1775b4b13232 21 bool bdmSyscallPuts (void);
Just4pLeisure 5:1775b4b13232 22 bool bdmSyscallPutchar(void);
Just4pLeisure 5:1775b4b13232 23 bool bdmSyscallGets(void);
Just4pLeisure 5:1775b4b13232 24 bool bdmSyscallGetchar(void);
Just4pLeisure 5:1775b4b13232 25 bool bdmSyscallGetstat(void);
Just4pLeisure 5:1775b4b13232 26 bool bdmSyscallFopen(void);
Just4pLeisure 5:1775b4b13232 27 bool bdmSyscallFclose(void);
Just4pLeisure 5:1775b4b13232 28 bool bdmSyscallFread(void);
Just4pLeisure 5:1775b4b13232 29 bool bdmSyscallFwrite(void);
Just4pLeisure 5:1775b4b13232 30 bool bdmSyscallFtell(void);
Just4pLeisure 5:1775b4b13232 31 bool bdmSyscallFseek(void);
Just4pLeisure 5:1775b4b13232 32 bool bdmSyscallFgets(void);
Just4pLeisure 5:1775b4b13232 33 bool bdmSyscallFputs(void);
Just4pLeisure 5:1775b4b13232 34 bool bdmSyscallEval(void);
Just4pLeisure 5:1775b4b13232 35 bool bdmSyscallFreadsrec(void);
Just4pLeisure 5:1775b4b13232 36
Just4pLeisure 5:1775b4b13232 37 //-----------------------------------------------------------------------------
Just4pLeisure 5:1775b4b13232 38 /**
Just4pLeisure 5:1775b4b13232 39 Loads the contenst of a uint8_t array into the target's memory starting at the
Just4pLeisure 5:1775b4b13232 40 specified address
Just4pLeisure 5:1775b4b13232 41
Just4pLeisure 5:1775b4b13232 42 @param dataArray[] uint8_t array conataining data for BDM tartget
Just4pLeisure 5:1775b4b13232 43 @param startAddress Start address to load BDM memory to
Just4pLeisure 5:1775b4b13232 44
Just4pLeisure 5:1775b4b13232 45 @return succ / fail
Just4pLeisure 5:1775b4b13232 46 */
Just4pLeisure 5:1775b4b13232 47 bool bdmLoadMemory(uint8_t dataArray[], uint32_t startAddress, uint32_t dataArraySize)
Just4pLeisure 5:1775b4b13232 48 {
Just4pLeisure 5:1775b4b13232 49 // for (uint32_t i = 0; i < sizeof(residentDriver); i++) {
Just4pLeisure 5:1775b4b13232 50 // if(memwrite_byte(&driverAddress, residentDriver[i]) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 51 // driverAddress++;
Just4pLeisure 5:1775b4b13232 52 // }
Just4pLeisure 5:1775b4b13232 53 uint32_t driverSize = dataArraySize;
Just4pLeisure 5:1775b4b13232 54 uint32_t driverOffset = 0;
Just4pLeisure 5:1775b4b13232 55 uint32_t driverLong = 0;
Just4pLeisure 5:1775b4b13232 56 uint16_t driverWord = 0;
Just4pLeisure 5:1775b4b13232 57 uint8_t driverByte = 0;
Just4pLeisure 5:1775b4b13232 58 // Check that there is something to send
Just4pLeisure 5:1775b4b13232 59 if (driverSize == 0) return false;
Just4pLeisure 5:1775b4b13232 60 // Send the first 1-4 bytes as efficiently as possible over BDM
Just4pLeisure 5:1775b4b13232 61 switch (driverSize % 4) {
Just4pLeisure 5:1775b4b13232 62 case 3:
Just4pLeisure 5:1775b4b13232 63 driverWord = (dataArray[driverOffset++] << 8) | dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 64 if(memwrite_word(&startAddress, driverWord) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 65 driverByte = dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 66 if(memfill_byte(driverByte) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 67 break;
Just4pLeisure 5:1775b4b13232 68 case 2:
Just4pLeisure 5:1775b4b13232 69 driverWord = (dataArray[driverOffset++] << 8) | dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 70 if(memwrite_word(&startAddress, driverWord) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 71 break;
Just4pLeisure 5:1775b4b13232 72 case 1:
Just4pLeisure 5:1775b4b13232 73 driverByte = dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 74 if(memwrite_byte(&startAddress, driverByte) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 75 break;
Just4pLeisure 5:1775b4b13232 76 case 0:
Just4pLeisure 5:1775b4b13232 77 for (uint32_t i = 0; i < 4; i++) {
Just4pLeisure 5:1775b4b13232 78 driverLong <<= 8;
Just4pLeisure 5:1775b4b13232 79 driverLong |= dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 80 }
Just4pLeisure 5:1775b4b13232 81 if(memwrite_long(&startAddress, &driverLong) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 82 break;
Just4pLeisure 5:1775b4b13232 83 // default: // There shouldn't be a default case
Just4pLeisure 5:1775b4b13232 84 }
Just4pLeisure 5:1775b4b13232 85 // transfer the rest as 'longs' to make best use of BDM transfer speed
Just4pLeisure 5:1775b4b13232 86 // printf("driverOffset 0x%08x, driverSize 0x%08x\r\n", driverOffset, driverSize);
Just4pLeisure 5:1775b4b13232 87 while (driverOffset < driverSize) {
Just4pLeisure 5:1775b4b13232 88 for (uint32_t i = 0; i < 4; i++) {
Just4pLeisure 5:1775b4b13232 89 driverLong <<= 8;
Just4pLeisure 5:1775b4b13232 90 driverLong |= dataArray[driverOffset++];
Just4pLeisure 5:1775b4b13232 91 }
Just4pLeisure 5:1775b4b13232 92 if(memfill_long(&driverLong) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 93 }
Just4pLeisure 5:1775b4b13232 94 // printf("driverOffset 0x%08x, driverSize 0x%08x\r\n", driverOffset, driverSize);
Just4pLeisure 5:1775b4b13232 95 return true;
Just4pLeisure 5:1775b4b13232 96 }
Just4pLeisure 5:1775b4b13232 97
Just4pLeisure 5:1775b4b13232 98 //-----------------------------------------------------------------------------
Just4pLeisure 5:1775b4b13232 99 /**
Just4pLeisure 5:1775b4b13232 100 Starts a BDM resident driver at the current PC (Program Counter) or a specified
Just4pLeisure 5:1775b4b13232 101 if given. The driver is allowed to run for a maximum period, maxtime, specified
Just4pLeisure 5:1775b4b13232 102 as milliseconds.
Just4pLeisure 5:1775b4b13232 103
Just4pLeisure 5:1775b4b13232 104 @param addr BDM driver address (0 to continue from current PC)
Just4pLeisure 5:1775b4b13232 105 @param maxtime how long to allow driver to execute (milliseconds)
Just4pLeisure 5:1775b4b13232 106
Just4pLeisure 5:1775b4b13232 107 @return succ / fail
Just4pLeisure 5:1775b4b13232 108 */
Just4pLeisure 5:1775b4b13232 109 bool bdmRunDriver(uint32_t addr, uint32_t maxtime)
Just4pLeisure 5:1775b4b13232 110 {
Just4pLeisure 5:1775b4b13232 111 // Start BDM driver and allow it up to 200 milliseconds to update 256 Bytes
Just4pLeisure 5:1775b4b13232 112 // Upto 25 pulses per byte, 16us per pulse, 256 Bytes
Just4pLeisure 5:1775b4b13232 113 // 25 * 16 * 256 = 102,400us plus overhead for driver code execution time
Just4pLeisure 5:1775b4b13232 114 // Allowing up to 200 milliseconds seems like a good allowance.
Just4pLeisure 5:1775b4b13232 115 if (run_chip(&addr) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 116 printf("Failed to start BDM driver.\r\n");
Just4pLeisure 5:1775b4b13232 117 return false;
Just4pLeisure 5:1775b4b13232 118 }
Just4pLeisure 5:1775b4b13232 119 timeout.reset();
Just4pLeisure 5:1775b4b13232 120 timeout.start();
Just4pLeisure 5:1775b4b13232 121 // T5 ECUs' BDM interface seem to have problems when the running the CPU and
Just4pLeisure 5:1775b4b13232 122 // sometimes shows the CPU briefly switching between showing BDM mode or that
Just4pLeisure 5:1775b4b13232 123 // the CPU is running.
Just4pLeisure 5:1775b4b13232 124 // I 'debounce' the interface state to workaround this erratic bahaviour
Just4pLeisure 5:1775b4b13232 125 for (uint32_t debounce = 0; debounce < 5; debounce++) {
Just4pLeisure 5:1775b4b13232 126 while (IS_RUNNING) {
Just4pLeisure 5:1775b4b13232 127 debounce = 0;
Just4pLeisure 5:1775b4b13232 128 if (timeout.read_ms() > maxtime) {
Just4pLeisure 5:1775b4b13232 129 printf("Driver did not return to BDM mode.\r\n");
Just4pLeisure 5:1775b4b13232 130 timeout.stop();
Just4pLeisure 5:1775b4b13232 131 return false;
Just4pLeisure 5:1775b4b13232 132 }
Just4pLeisure 5:1775b4b13232 133 }
Just4pLeisure 5:1775b4b13232 134 wait_us(1);
Just4pLeisure 5:1775b4b13232 135 }
Just4pLeisure 5:1775b4b13232 136 timeout.stop();
Just4pLeisure 5:1775b4b13232 137 return true;
Just4pLeisure 5:1775b4b13232 138 }
Just4pLeisure 5:1775b4b13232 139
Just4pLeisure 5:1775b4b13232 140
Just4pLeisure 5:1775b4b13232 141 //-----------------------------------------------------------------------------
Just4pLeisure 5:1775b4b13232 142 /**
Just4pLeisure 5:1775b4b13232 143 Starts a BDM resident driver at the current PC (Program Counter) or a specified
Just4pLeisure 5:1775b4b13232 144 if given. The driver is allowed to run for a maximum period, maxtime, specified
Just4pLeisure 5:1775b4b13232 145 as milliseconds.
Just4pLeisure 5:1775b4b13232 146
Just4pLeisure 5:1775b4b13232 147 @param addr BDM driver address (0 to continue from current PC)
Just4pLeisure 5:1775b4b13232 148 @param maxtime how long to allow driver to execute (milliseconds)
Just4pLeisure 5:1775b4b13232 149
Just4pLeisure 5:1775b4b13232 150 @return DONE, CONTINUE, ERROR
Just4pLeisure 5:1775b4b13232 151
Just4pLeisure 5:1775b4b13232 152 */
Just4pLeisure 5:1775b4b13232 153
Just4pLeisure 5:1775b4b13232 154 uint8_t bdmProcessSyscall(void)
Just4pLeisure 5:1775b4b13232 155 {
Just4pLeisure 5:1775b4b13232 156
Just4pLeisure 5:1775b4b13232 157 uint32_t syscall = 0xFFFFFFFF;
Just4pLeisure 5:1775b4b13232 158 if (adreg_read(&syscall, 0x0) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 159 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 160 return ERROR;
Just4pLeisure 5:1775b4b13232 161 }
Just4pLeisure 5:1775b4b13232 162 syscall &= 0xFF;
Just4pLeisure 5:1775b4b13232 163 // printf("SYSCALL 0x%08x\r\n", syscall);
Just4pLeisure 5:1775b4b13232 164 switch (syscall) {
Just4pLeisure 5:1775b4b13232 165 case QUIT:
Just4pLeisure 5:1775b4b13232 166 if (adreg_read(&syscall, 0x1) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 167 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 168 return ERROR;
Just4pLeisure 5:1775b4b13232 169 }
Just4pLeisure 5:1775b4b13232 170 return DONE;
Just4pLeisure 5:1775b4b13232 171 case PUTS:
Just4pLeisure 5:1775b4b13232 172 if (!bdmSyscallPuts()) return ERROR;
Just4pLeisure 5:1775b4b13232 173 break;
Just4pLeisure 5:1775b4b13232 174 case PUTCHAR:
Just4pLeisure 5:1775b4b13232 175 if (!bdmSyscallPutchar()) return ERROR;
Just4pLeisure 5:1775b4b13232 176 break;
Just4pLeisure 5:1775b4b13232 177 case GETS:
Just4pLeisure 5:1775b4b13232 178 if (!bdmSyscallGets()) return ERROR;
Just4pLeisure 5:1775b4b13232 179 break;
Just4pLeisure 5:1775b4b13232 180 case GETCHAR:
Just4pLeisure 5:1775b4b13232 181 if (!bdmSyscallGetchar()) return ERROR;
Just4pLeisure 5:1775b4b13232 182 break;
Just4pLeisure 5:1775b4b13232 183 case GETSTAT:
Just4pLeisure 5:1775b4b13232 184 if (!bdmSyscallGetstat()) return ERROR;
Just4pLeisure 5:1775b4b13232 185 break;
Just4pLeisure 5:1775b4b13232 186 case FOPEN:
Just4pLeisure 5:1775b4b13232 187 if (!bdmSyscallFopen()) return ERROR;
Just4pLeisure 5:1775b4b13232 188 break;
Just4pLeisure 5:1775b4b13232 189 case FCLOSE:
Just4pLeisure 5:1775b4b13232 190 if (!bdmSyscallFclose()) return ERROR;
Just4pLeisure 5:1775b4b13232 191 break;
Just4pLeisure 5:1775b4b13232 192 case FREAD:
Just4pLeisure 5:1775b4b13232 193 if (!bdmSyscallFread()) return ERROR;
Just4pLeisure 5:1775b4b13232 194 break;
Just4pLeisure 5:1775b4b13232 195 case FWRITE:
Just4pLeisure 5:1775b4b13232 196 if (!bdmSyscallFwrite()) return ERROR;
Just4pLeisure 5:1775b4b13232 197 break;
Just4pLeisure 5:1775b4b13232 198 case FTELL:
Just4pLeisure 5:1775b4b13232 199 if (!bdmSyscallFtell()) return ERROR;
Just4pLeisure 5:1775b4b13232 200 break;
Just4pLeisure 5:1775b4b13232 201 case FSEEK:
Just4pLeisure 5:1775b4b13232 202 if (!bdmSyscallFseek()) return ERROR;
Just4pLeisure 5:1775b4b13232 203 break;
Just4pLeisure 5:1775b4b13232 204 case FGETS:
Just4pLeisure 5:1775b4b13232 205 if (!bdmSyscallFgets()) return ERROR;
Just4pLeisure 5:1775b4b13232 206 break;
Just4pLeisure 5:1775b4b13232 207 case FPUTS:
Just4pLeisure 5:1775b4b13232 208 if (!bdmSyscallFputs()) return ERROR;
Just4pLeisure 5:1775b4b13232 209 break;
Just4pLeisure 5:1775b4b13232 210 case EVAL:
Just4pLeisure 5:1775b4b13232 211 if (!bdmSyscallEval()) return ERROR;
Just4pLeisure 5:1775b4b13232 212 break;
Just4pLeisure 5:1775b4b13232 213 case FREADSREC:
Just4pLeisure 5:1775b4b13232 214 if (!bdmSyscallFreadsrec()) return ERROR;
Just4pLeisure 5:1775b4b13232 215 break;
Just4pLeisure 5:1775b4b13232 216 default:
Just4pLeisure 5:1775b4b13232 217 printf("!!! Unknown BDM Syscall !!!\r\n");
Just4pLeisure 5:1775b4b13232 218 return ERROR;
Just4pLeisure 5:1775b4b13232 219 }
Just4pLeisure 5:1775b4b13232 220 return CONTINUE;
Just4pLeisure 5:1775b4b13232 221 }
Just4pLeisure 5:1775b4b13232 222
Just4pLeisure 5:1775b4b13232 223
Just4pLeisure 5:1775b4b13232 224 bool bdmSyscallPuts()
Just4pLeisure 5:1775b4b13232 225 {
Just4pLeisure 5:1775b4b13232 226 uint32_t bdm_string_address = 0, bdm_return = 0;
Just4pLeisure 5:1775b4b13232 227 if (adreg_read(&bdm_string_address, 0x8) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 228 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 229 return false;
Just4pLeisure 5:1775b4b13232 230 }
Just4pLeisure 5:1775b4b13232 231 // a loop to read chars from BDM into a string
Just4pLeisure 5:1775b4b13232 232 char bdm_string[256];
Just4pLeisure 5:1775b4b13232 233 for (uint32_t i = 0; i < sizeof(bdm_string); i++) {
Just4pLeisure 5:1775b4b13232 234 bdm_string[i] = 0x0;
Just4pLeisure 5:1775b4b13232 235 }
Just4pLeisure 5:1775b4b13232 236 uint32_t i = 0;
Just4pLeisure 5:1775b4b13232 237 do {
Just4pLeisure 5:1775b4b13232 238 if (memread_byte((uint8_t*)(bdm_string+i), &bdm_string_address) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 239 printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_string_address);
Just4pLeisure 5:1775b4b13232 240 return false;
Just4pLeisure 5:1775b4b13232 241 }
Just4pLeisure 5:1775b4b13232 242 bdm_string_address++;
Just4pLeisure 5:1775b4b13232 243 } while ( (bdm_string[i++] != 0x0) && (i < sizeof(bdm_string)) );
Just4pLeisure 5:1775b4b13232 244 // print the string to stdout (USB virtual serial port)
Just4pLeisure 5:1775b4b13232 245 printf(bdm_string);
Just4pLeisure 5:1775b4b13232 246 // Send BDM return code in D0 (always 0x0 for PUTS)
Just4pLeisure 5:1775b4b13232 247 if (adreg_write(0x0, &bdm_return) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 248 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 249 return false;
Just4pLeisure 5:1775b4b13232 250 }
Just4pLeisure 5:1775b4b13232 251 return true;
Just4pLeisure 5:1775b4b13232 252 }
Just4pLeisure 5:1775b4b13232 253
Just4pLeisure 5:1775b4b13232 254 bool bdmSyscallPutchar()
Just4pLeisure 5:1775b4b13232 255 {
Just4pLeisure 5:1775b4b13232 256 uint32_t bdm_character = 0, bdm_return = 0;
Just4pLeisure 5:1775b4b13232 257 // read char from BDM
Just4pLeisure 5:1775b4b13232 258 if (adreg_read(&bdm_character, 0x1) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 259 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 260 return false;
Just4pLeisure 5:1775b4b13232 261 }
Just4pLeisure 5:1775b4b13232 262 // print the char to USB virtual serial port
Just4pLeisure 5:1775b4b13232 263 pc.putc((char)bdm_character);
Just4pLeisure 5:1775b4b13232 264 // Send BDM return code in D0 (always 0x0 for PUTCHAR)
Just4pLeisure 5:1775b4b13232 265 if (adreg_write(0x0, &bdm_return) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 266 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 267 return false;
Just4pLeisure 5:1775b4b13232 268 }
Just4pLeisure 5:1775b4b13232 269 return true;
Just4pLeisure 5:1775b4b13232 270 }
Just4pLeisure 5:1775b4b13232 271
Just4pLeisure 5:1775b4b13232 272 bool bdmSyscallGets()
Just4pLeisure 5:1775b4b13232 273 {
Just4pLeisure 5:1775b4b13232 274 printf("BDM GETS Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 275 return ERROR;
Just4pLeisure 5:1775b4b13232 276 }
Just4pLeisure 5:1775b4b13232 277
Just4pLeisure 5:1775b4b13232 278 bool bdmSyscallGetchar()
Just4pLeisure 5:1775b4b13232 279 {
Just4pLeisure 5:1775b4b13232 280 // get a char from the USB virtual serial port
Just4pLeisure 5:1775b4b13232 281 uint32_t bdm_return = (uint32_t)pc.getc();
Just4pLeisure 5:1775b4b13232 282 // Send the char to BDM in D0
Just4pLeisure 5:1775b4b13232 283 if (adreg_write(0x0, &bdm_return) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 284 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 285 return false;
Just4pLeisure 5:1775b4b13232 286 }
Just4pLeisure 5:1775b4b13232 287 return true;
Just4pLeisure 5:1775b4b13232 288 }
Just4pLeisure 5:1775b4b13232 289
Just4pLeisure 5:1775b4b13232 290 bool bdmSyscallGetstat(void)
Just4pLeisure 5:1775b4b13232 291 {
Just4pLeisure 5:1775b4b13232 292 printf("BDM GETSTAT Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 293 return false;
Just4pLeisure 5:1775b4b13232 294 }
Just4pLeisure 5:1775b4b13232 295
Just4pLeisure 5:1775b4b13232 296 bool bdmSyscallFopen(void)
Just4pLeisure 5:1775b4b13232 297 {
Just4pLeisure 5:1775b4b13232 298 uint32_t bdm_filename_address = 0, bdm_filemode_address = 0;
Just4pLeisure 5:1775b4b13232 299 if (adreg_read(&bdm_filename_address, 0x8) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 300 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 301 return false;
Just4pLeisure 5:1775b4b13232 302 }
Just4pLeisure 5:1775b4b13232 303 if (adreg_read(&bdm_filemode_address, 0x9) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 304 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 305 return false;
Just4pLeisure 5:1775b4b13232 306 }
Just4pLeisure 5:1775b4b13232 307 // a loop to initialise the strings to 0x0
Just4pLeisure 5:1775b4b13232 308 char filename_string[80], filemode_string[5];
Just4pLeisure 5:1775b4b13232 309 uint32_t i = 0;
Just4pLeisure 5:1775b4b13232 310 for (i = 0; i < sizeof(filename_string); i++) {
Just4pLeisure 5:1775b4b13232 311 filename_string[i] = 0x0;
Just4pLeisure 5:1775b4b13232 312 }
Just4pLeisure 5:1775b4b13232 313 for (i = 0; i < sizeof(filemode_string); i++) {
Just4pLeisure 5:1775b4b13232 314 filemode_string[i] = 0x0;
Just4pLeisure 5:1775b4b13232 315 }
Just4pLeisure 5:1775b4b13232 316 i = 0;
Just4pLeisure 5:1775b4b13232 317 // a loop to read chars from BDM into a string
Just4pLeisure 5:1775b4b13232 318 do {
Just4pLeisure 5:1775b4b13232 319 if (memread_byte((uint8_t*)filename_string[i], &bdm_filename_address) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 320 printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_filename_address);
Just4pLeisure 5:1775b4b13232 321 return false;
Just4pLeisure 5:1775b4b13232 322 }
Just4pLeisure 5:1775b4b13232 323 bdm_filename_address++;
Just4pLeisure 5:1775b4b13232 324 } while ( (filename_string[i++] != 0x0) && (i < sizeof(filename_string)) );
Just4pLeisure 5:1775b4b13232 325 do {
Just4pLeisure 5:1775b4b13232 326 if (memread_byte((uint8_t*)filemode_string[i], &bdm_filemode_address) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 327 printf("Failed to read BDM memory at address 0x%08x.\r\n", bdm_filemode_address);
Just4pLeisure 5:1775b4b13232 328 return false;
Just4pLeisure 5:1775b4b13232 329 }
Just4pLeisure 5:1775b4b13232 330 bdm_filemode_address++;
Just4pLeisure 5:1775b4b13232 331 } while ( (filemode_string[i++] != 0x0) && (i < sizeof(filemode_string)) );
Just4pLeisure 5:1775b4b13232 332 // Open the file
Just4pLeisure 5:1775b4b13232 333 fp = fopen(filename_string, filemode_string); // Open "modified.hex" on the local file system for reading
Just4pLeisure 5:1775b4b13232 334 // Send BDM return code in D0
Just4pLeisure 5:1775b4b13232 335 if (adreg_write(0x0, (uint32_t*)fp) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 336 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 337 return false;
Just4pLeisure 5:1775b4b13232 338 }
Just4pLeisure 5:1775b4b13232 339 return true;
Just4pLeisure 5:1775b4b13232 340 }
Just4pLeisure 5:1775b4b13232 341
Just4pLeisure 5:1775b4b13232 342 bool bdmSyscallFclose(void)
Just4pLeisure 5:1775b4b13232 343 {
Just4pLeisure 5:1775b4b13232 344 uint32_t close_result = fclose(fp);
Just4pLeisure 5:1775b4b13232 345 // Send BDM return code in D0
Just4pLeisure 5:1775b4b13232 346 if (adreg_write(0x0, &close_result) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 347 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 348 return false;
Just4pLeisure 5:1775b4b13232 349 }
Just4pLeisure 5:1775b4b13232 350 return true;
Just4pLeisure 5:1775b4b13232 351 }
Just4pLeisure 5:1775b4b13232 352
Just4pLeisure 5:1775b4b13232 353 bool bdmSyscallFread(void)
Just4pLeisure 5:1775b4b13232 354 {
Just4pLeisure 5:1775b4b13232 355 uint32_t bdm_byte_count, bdm_buffer_address, bdm_file_handle = NULL;
Just4pLeisure 5:1775b4b13232 356 if (adreg_read(&bdm_file_handle, 0x1) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 357 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 358 return false;
Just4pLeisure 5:1775b4b13232 359 }
Just4pLeisure 5:1775b4b13232 360 if (adreg_read(&bdm_byte_count, 0x2) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 361 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 362 return false;
Just4pLeisure 5:1775b4b13232 363 }
Just4pLeisure 5:1775b4b13232 364 if (adreg_read(&bdm_buffer_address, 0x9) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 365 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 366 return false;
Just4pLeisure 5:1775b4b13232 367 }
Just4pLeisure 5:1775b4b13232 368 uint32_t bytes_read = fread(&file_buffer[0],1,bdm_byte_count,fp);
Just4pLeisure 5:1775b4b13232 369 for (uint32_t byte_count = 0; byte_count < bytes_read; byte_count++) {
Just4pLeisure 5:1775b4b13232 370 if (byte_count == 0x0) {
Just4pLeisure 5:1775b4b13232 371 if(memwrite_byte(&bdm_buffer_address, file_buffer[byte_count]) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 372 } else {
Just4pLeisure 5:1775b4b13232 373 if(memfill_byte(file_buffer[byte_count]) != TERM_OK) return false;
Just4pLeisure 5:1775b4b13232 374 }
Just4pLeisure 5:1775b4b13232 375 }
Just4pLeisure 5:1775b4b13232 376 if (adreg_write(0x0, &bytes_read) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 377 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 378 return false;
Just4pLeisure 5:1775b4b13232 379 }
Just4pLeisure 5:1775b4b13232 380 return true;
Just4pLeisure 5:1775b4b13232 381 }
Just4pLeisure 5:1775b4b13232 382
Just4pLeisure 5:1775b4b13232 383 bool bdmSyscallFwrite(void)
Just4pLeisure 5:1775b4b13232 384 {
Just4pLeisure 5:1775b4b13232 385 printf("BDM FWRITE Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 386 return false;
Just4pLeisure 5:1775b4b13232 387 }
Just4pLeisure 5:1775b4b13232 388
Just4pLeisure 5:1775b4b13232 389 bool bdmSyscallFtell(void)
Just4pLeisure 5:1775b4b13232 390 {
Just4pLeisure 5:1775b4b13232 391 printf("BDM FTELL Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 392 return false;
Just4pLeisure 5:1775b4b13232 393 }
Just4pLeisure 5:1775b4b13232 394
Just4pLeisure 5:1775b4b13232 395 bool bdmSyscallFseek(void)
Just4pLeisure 5:1775b4b13232 396 {
Just4pLeisure 5:1775b4b13232 397 uint32_t bdm_byte_offset, bdm_file_origin, bdm_file_handle = NULL;
Just4pLeisure 5:1775b4b13232 398 if (adreg_read(&bdm_file_handle, 0x1) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 399 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 400 return false;
Just4pLeisure 5:1775b4b13232 401 }
Just4pLeisure 5:1775b4b13232 402 if (adreg_read(&bdm_byte_offset, 0x2) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 403 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 404 return false;
Just4pLeisure 5:1775b4b13232 405 }
Just4pLeisure 5:1775b4b13232 406 if (adreg_read(&bdm_file_origin, 0x3) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 407 printf("Failed to read BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 408 return false;
Just4pLeisure 5:1775b4b13232 409 }
Just4pLeisure 5:1775b4b13232 410 uint32_t origin;
Just4pLeisure 5:1775b4b13232 411 switch (bdm_file_origin) {
Just4pLeisure 5:1775b4b13232 412 case 0x2:
Just4pLeisure 5:1775b4b13232 413 origin = SEEK_END;
Just4pLeisure 5:1775b4b13232 414 break;
Just4pLeisure 5:1775b4b13232 415 case 0x1:
Just4pLeisure 5:1775b4b13232 416 origin = SEEK_CUR;
Just4pLeisure 5:1775b4b13232 417 break;
Just4pLeisure 5:1775b4b13232 418 case 0x0:
Just4pLeisure 5:1775b4b13232 419 default:
Just4pLeisure 5:1775b4b13232 420 origin = SEEK_SET;
Just4pLeisure 5:1775b4b13232 421 break;
Just4pLeisure 5:1775b4b13232 422 }
Just4pLeisure 5:1775b4b13232 423 uint32_t fseek_result = fseek ( fp ,bdm_byte_offset ,origin );
Just4pLeisure 5:1775b4b13232 424 if (adreg_write(0x0, &fseek_result) != TERM_OK) {
Just4pLeisure 5:1775b4b13232 425 printf("Failed to write BDM register.\r\n");
Just4pLeisure 5:1775b4b13232 426 return false;
Just4pLeisure 5:1775b4b13232 427 }
Just4pLeisure 5:1775b4b13232 428 return true;
Just4pLeisure 5:1775b4b13232 429 }
Just4pLeisure 5:1775b4b13232 430
Just4pLeisure 5:1775b4b13232 431 bool bdmSyscallFgets(void)
Just4pLeisure 5:1775b4b13232 432 {
Just4pLeisure 5:1775b4b13232 433 printf("BDM FGETS Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 434 return false;
Just4pLeisure 5:1775b4b13232 435 }
Just4pLeisure 5:1775b4b13232 436
Just4pLeisure 5:1775b4b13232 437 bool bdmSyscallFputs(void)
Just4pLeisure 5:1775b4b13232 438 {
Just4pLeisure 5:1775b4b13232 439 printf("BDM FPUTS Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 440 return false;
Just4pLeisure 5:1775b4b13232 441 }
Just4pLeisure 5:1775b4b13232 442
Just4pLeisure 5:1775b4b13232 443 bool bdmSyscallEval(void)
Just4pLeisure 5:1775b4b13232 444 {
Just4pLeisure 5:1775b4b13232 445 printf("BDM EVAL Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 446 return false;
Just4pLeisure 5:1775b4b13232 447 }
Just4pLeisure 5:1775b4b13232 448
Just4pLeisure 5:1775b4b13232 449 bool bdmSyscallFreadsrec(void)
Just4pLeisure 5:1775b4b13232 450 {
Just4pLeisure 5:1775b4b13232 451 printf("BDM FREADSREC Syscall not supported.\r\n");
Just4pLeisure 5:1775b4b13232 452 return false;
Just4pLeisure 5:1775b4b13232 453 }