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 bdm.cpp
Just4pLeisure 1:d5452e398b76 4 (c) 2010 by Sophie Dexter
Just4pLeisure 1:d5452e398b76 5
Just4pLeisure 1:d5452e398b76 6 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 // Firmware for USB BDM v2.0
Just4pLeisure 1:d5452e398b76 11 // (C) johnc, 2009
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 "bdm.h"
Just4pLeisure 1:d5452e398b76 24
Just4pLeisure 1:d5452e398b76 25 // constants
Just4pLeisure 1:d5452e398b76 26 #define CMD_BUF_LENGTH 32 ///< command buffer size
Just4pLeisure 1:d5452e398b76 27
Just4pLeisure 1:d5452e398b76 28 // LED constants and macros
Just4pLeisure 1:d5452e398b76 29 #define LED_ONTIME 5 ///< LED 'on' time, ms
Just4pLeisure 1:d5452e398b76 30 #define LED_TCNT (255 - (unsigned char)((unsigned long)(LED_ONTIME * 1000L) \
Just4pLeisure 1:d5452e398b76 31 / (1000000L / (float)((unsigned long)XTAL_CPU / 1024L))))
Just4pLeisure 1:d5452e398b76 32
Just4pLeisure 1:d5452e398b76 33 // command characters
Just4pLeisure 1:d5452e398b76 34 #define CMDGROUP_ADAPTER 'a' ///< adapter commands
Just4pLeisure 1:d5452e398b76 35 #define CMD_VERSION 'v' ///< firmware version
Just4pLeisure 1:d5452e398b76 36 #define CMD_PINSTATUS 's' ///< momentary status of BDM pins
Just4pLeisure 1:d5452e398b76 37 #define CMD_BKPTLOW '1' ///< pull BKPT low
Just4pLeisure 1:d5452e398b76 38 #define CMD_BKPTHIGH '2' ///< pull BKPT high
Just4pLeisure 1:d5452e398b76 39 #define CMD_RESETLOW '3' ///< pull RESET low
Just4pLeisure 1:d5452e398b76 40 #define CMD_RESETHIGH '4' ///< pull RESET high
Just4pLeisure 1:d5452e398b76 41
Just4pLeisure 1:d5452e398b76 42 #define CMDGROUP_MCU 'c' ///< target MCU management commands
Just4pLeisure 1:d5452e398b76 43 #define CMD_STOPCHIP 'S' ///< stop
Just4pLeisure 1:d5452e398b76 44 #define CMD_RESETCHIP 'R' ///< reset
Just4pLeisure 1:d5452e398b76 45 #define CMD_RUNCHIP 'r' ///< run from given address
Just4pLeisure 1:d5452e398b76 46 #define CMD_RESTART 's' ///< restart
Just4pLeisure 1:d5452e398b76 47 #define CMD_STEP 'b' ///< step
Just4pLeisure 1:d5452e398b76 48
Just4pLeisure 1:d5452e398b76 49 #define CMDGROUP_FLASH 'f'
Just4pLeisure 1:d5452e398b76 50 #define CMD_GETVERIFY 'v' ///< gets verification status
Just4pLeisure 1:d5452e398b76 51 #define CMD_SETVERIFY 'V' ///< sets verification on/off
Just4pLeisure 1:d5452e398b76 52 #define CMD_DUMP 'd' ///< dumps memory contents
Just4pLeisure 1:d5452e398b76 53 #define CMD_ERASE 'E' ///< erase entire flash memory
Just4pLeisure 1:d5452e398b76 54 #define CMD_WRITE 'w' ///< writes to flash memory
Just4pLeisure 1:d5452e398b76 55
Just4pLeisure 1:d5452e398b76 56 #define CMDGROUP_MEMORY 'm' ///< target MCU memory commands
Just4pLeisure 1:d5452e398b76 57 #define CMD_READBYTE 'b' ///< read byte from memory
Just4pLeisure 1:d5452e398b76 58 #define CMD_READWORD 'w' ///< read word (2 bytes) from memory
Just4pLeisure 1:d5452e398b76 59 #define CMD_READLONG 'l' ///< read long word (4 bytes) from memory
Just4pLeisure 1:d5452e398b76 60 #define CMD_DUMPBYTE 'z' ///< dump byte from memory
Just4pLeisure 1:d5452e398b76 61 #define CMD_DUMPWORD 'x' ///< dump word from memory
Just4pLeisure 1:d5452e398b76 62 #define CMD_DUMPLONG 'c' ///< dump long word from memory
Just4pLeisure 1:d5452e398b76 63 #define CMD_WRITEBYTE 'B' ///< write byte to memory
Just4pLeisure 1:d5452e398b76 64 #define CMD_WRITEWORD 'W' ///< write word to memory
Just4pLeisure 1:d5452e398b76 65 #define CMD_WRITELONG 'L' ///< write long word to memory
Just4pLeisure 1:d5452e398b76 66 #define CMD_FILLBYTE 'f' ///< fill byte in memory
Just4pLeisure 1:d5452e398b76 67 #define CMD_FILLWORD 'F' ///< fill word in memory
Just4pLeisure 1:d5452e398b76 68 #define CMD_FILLLONG 'M' ///< fill long word in memory
Just4pLeisure 1:d5452e398b76 69
Just4pLeisure 1:d5452e398b76 70 #define CMDGROUP_REGISTER 'r' ///< register commands
Just4pLeisure 1:d5452e398b76 71 #define CMD_READSYSREG 'r' ///< read system register
Just4pLeisure 1:d5452e398b76 72 #define CMD_WRITESYSREG 'W' ///< write system register
Just4pLeisure 1:d5452e398b76 73 #define CMD_READADREG 'a' ///< read A/D register
Just4pLeisure 1:d5452e398b76 74 #define CMD_WRITEADREG 'A' ///< write A/D register
Just4pLeisure 1:d5452e398b76 75
Just4pLeisure 1:d5452e398b76 76 #define CMDGROUP_TRIONIC 'T'
Just4pLeisure 1:d5452e398b76 77 #define CMD_TRIONICDUMP 'D' ///< dumps memory contents
Just4pLeisure 1:d5452e398b76 78 #define CMD_TRIONICWRITE 'F' ///< writes to flash memory
Just4pLeisure 1:d5452e398b76 79
Just4pLeisure 1:d5452e398b76 80 // static variables
Just4pLeisure 1:d5452e398b76 81 static char cmd_buffer[CMD_BUF_LENGTH]; ///< command string buffer
Just4pLeisure 1:d5452e398b76 82 static uint32_t cmd_addr; ///< address (optional)
Just4pLeisure 1:d5452e398b76 83 static uint32_t cmd_value; ///< value (optional)
Just4pLeisure 1:d5452e398b76 84 static uint32_t cmd_result; ///< result
Just4pLeisure 1:d5452e398b76 85
Just4pLeisure 1:d5452e398b76 86 // private functions
Just4pLeisure 1:d5452e398b76 87 uint8_t execute_bdm_cmd();
Just4pLeisure 1:d5452e398b76 88
Just4pLeisure 1:d5452e398b76 89 void bdm_show_help();
Just4pLeisure 1:d5452e398b76 90 void bdm_show_full_help();
Just4pLeisure 1:d5452e398b76 91
Just4pLeisure 1:d5452e398b76 92 // command argument macros
Just4pLeisure 1:d5452e398b76 93 #define CHECK_ARGLENGTH(len) \
Just4pLeisure 1:d5452e398b76 94 if (cmd_length != len + 2) \
Just4pLeisure 1:d5452e398b76 95 return TERM_ERR
Just4pLeisure 1:d5452e398b76 96
Just4pLeisure 1:d5452e398b76 97 #define GET_NUMBER(target, offset, len) \
Just4pLeisure 1:d5452e398b76 98 if (!ascii2int(target, cmd_buffer + 2 + offset, len)) \
Just4pLeisure 1:d5452e398b76 99 return TERM_ERR
Just4pLeisure 1:d5452e398b76 100
Just4pLeisure 1:d5452e398b76 101
Just4pLeisure 1:d5452e398b76 102 void bdm() {
Just4pLeisure 1:d5452e398b76 103
Just4pLeisure 1:d5452e398b76 104 bdm_show_help();
Just4pLeisure 1:d5452e398b76 105 // set up LED pins
Just4pLeisure 1:d5452e398b76 106 // SETBIT(LED_DIR, _BV(LED_ERR) | _BV(LED_ACT));
Just4pLeisure 1:d5452e398b76 107 // set up USB_RD and USB_WR pins
Just4pLeisure 1:d5452e398b76 108 // SETBIT(USB_RXTX_DIR, _BV(USB_RD) | _BV(USB_WR));
Just4pLeisure 1:d5452e398b76 109
Just4pLeisure 1:d5452e398b76 110 // enable interrupts
Just4pLeisure 1:d5452e398b76 111 // sei();
Just4pLeisure 1:d5452e398b76 112
Just4pLeisure 1:d5452e398b76 113 // load configuration from EEPROM
Just4pLeisure 1:d5452e398b76 114 // verify_flash = eeprom_read_byte(&ee_verify);
Just4pLeisure 1:d5452e398b76 115
Just4pLeisure 1:d5452e398b76 116 // Set some initial values to help with checking if the BDM connector is plugged in
Just4pLeisure 1:d5452e398b76 117 PIN_PWR.mode(PullDown);
Just4pLeisure 1:d5452e398b76 118 PIN_NC.mode(PullUp);
Just4pLeisure 2:bf3a2b29259a 119 // PIN_DS.mode(PullUp);
Just4pLeisure 1:d5452e398b76 120 PIN_FREEZE.mode(PullUp);
Just4pLeisure 1:d5452e398b76 121 PIN_DSO.mode(PullUp);
Just4pLeisure 1:d5452e398b76 122
Just4pLeisure 1:d5452e398b76 123 verify_flash = true;
Just4pLeisure 1:d5452e398b76 124
Just4pLeisure 1:d5452e398b76 125 // main loop
Just4pLeisure 1:d5452e398b76 126 *cmd_buffer = '\0';
Just4pLeisure 1:d5452e398b76 127 char ret;
Just4pLeisure 1:d5452e398b76 128 char rx_char;
Just4pLeisure 1:d5452e398b76 129 while (true) {
Just4pLeisure 1:d5452e398b76 130 // read chars from USB
Just4pLeisure 1:d5452e398b76 131 if (pc.readable()) {
Just4pLeisure 1:d5452e398b76 132 // turn Error LED off for next command
Just4pLeisure 1:d5452e398b76 133 led4 = 0;
Just4pLeisure 1:d5452e398b76 134 rx_char = pc.getc();
Just4pLeisure 1:d5452e398b76 135 switch (rx_char) {
Just4pLeisure 1:d5452e398b76 136 // 'ESC' key to go back to mbed Just4Trionic 'home' menu
Just4pLeisure 1:d5452e398b76 137 case '\e':
Just4pLeisure 1:d5452e398b76 138 reset_chip();
Just4pLeisure 1:d5452e398b76 139 return;
Just4pLeisure 1:d5452e398b76 140 // end-of-command reached
Just4pLeisure 1:d5452e398b76 141 case TERM_OK :
Just4pLeisure 1:d5452e398b76 142 // execute command and return flag via USB
Just4pLeisure 1:d5452e398b76 143 ret = execute_bdm_cmd();
Just4pLeisure 1:d5452e398b76 144 pc.putc(ret);
Just4pLeisure 1:d5452e398b76 145 // reset command buffer
Just4pLeisure 1:d5452e398b76 146 *cmd_buffer = '\0';
Just4pLeisure 1:d5452e398b76 147 // light up LED
Just4pLeisure 1:d5452e398b76 148 // ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR);
Just4pLeisure 1:d5452e398b76 149 ret == TERM_OK ? led3 = 1 : led4 = 1;
Just4pLeisure 1:d5452e398b76 150 break;
Just4pLeisure 1:d5452e398b76 151 // another command char
Just4pLeisure 1:d5452e398b76 152 default:
Just4pLeisure 1:d5452e398b76 153 // store in buffer if space permits
Just4pLeisure 1:d5452e398b76 154 if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) {
Just4pLeisure 1:d5452e398b76 155 StrAddc(cmd_buffer, rx_char);
Just4pLeisure 1:d5452e398b76 156 }
Just4pLeisure 1:d5452e398b76 157 break;
Just4pLeisure 1:d5452e398b76 158 }
Just4pLeisure 1:d5452e398b76 159 }
Just4pLeisure 1:d5452e398b76 160 }
Just4pLeisure 1:d5452e398b76 161 }
Just4pLeisure 1:d5452e398b76 162
Just4pLeisure 1:d5452e398b76 163 //-----------------------------------------------------------------------------
Just4pLeisure 1:d5452e398b76 164 /**
Just4pLeisure 1:d5452e398b76 165 Executes a command and returns result flag (does not transmit the flag
Just4pLeisure 1:d5452e398b76 166 itself).
Just4pLeisure 1:d5452e398b76 167
Just4pLeisure 1:d5452e398b76 168 @return command flag (success / failure)
Just4pLeisure 1:d5452e398b76 169 */
Just4pLeisure 1:d5452e398b76 170 uint8_t execute_bdm_cmd() {
Just4pLeisure 1:d5452e398b76 171 uint8_t cmd_length = strlen(cmd_buffer);
Just4pLeisure 1:d5452e398b76 172 char cmd = *(cmd_buffer + 1);
Just4pLeisure 1:d5452e398b76 173
Just4pLeisure 1:d5452e398b76 174 // command groups
Just4pLeisure 1:d5452e398b76 175 switch (*cmd_buffer) {
Just4pLeisure 1:d5452e398b76 176 // adapter commands
Just4pLeisure 1:d5452e398b76 177 case CMDGROUP_ADAPTER:
Just4pLeisure 1:d5452e398b76 178 CHECK_ARGLENGTH(0);
Just4pLeisure 1:d5452e398b76 179 switch (cmd) {
Just4pLeisure 1:d5452e398b76 180 // get firmware version
Just4pLeisure 1:d5452e398b76 181 case CMD_VERSION:
Just4pLeisure 1:d5452e398b76 182 printf("%02x", FW_VERSION_MAJOR);
Just4pLeisure 1:d5452e398b76 183 printf("%02x", FW_VERSION_MINOR);
Just4pLeisure 4:682d96ff6d79 184 printf("\r\n");
Just4pLeisure 1:d5452e398b76 185 return TERM_OK;
Just4pLeisure 1:d5452e398b76 186
Just4pLeisure 1:d5452e398b76 187 // get momentary status of BDM pins 0...5 (for debugging)
Just4pLeisure 1:d5452e398b76 188 case CMD_PINSTATUS:
Just4pLeisure 1:d5452e398b76 189 // printf("%02x", (BDM_PIN & 0x3f));
Just4pLeisure 1:d5452e398b76 190 printf("PWR %d, ", PIN_PWR.read());
Just4pLeisure 1:d5452e398b76 191 printf("NC %d, ", PIN_NC.read());
Just4pLeisure 2:bf3a2b29259a 192 // printf("DS %d, ", PIN_DS.read());
Just4pLeisure 1:d5452e398b76 193 printf("FREEZE %d, ", PIN_FREEZE.read());
Just4pLeisure 1:d5452e398b76 194 printf("DSO %d, ", PIN_DSO.read());
Just4pLeisure 4:682d96ff6d79 195 printf("\r\n");
Just4pLeisure 1:d5452e398b76 196 return TERM_OK;
Just4pLeisure 1:d5452e398b76 197
Just4pLeisure 1:d5452e398b76 198 // pull BKPT low
Just4pLeisure 1:d5452e398b76 199 case CMD_BKPTLOW:
Just4pLeisure 1:d5452e398b76 200 return bkpt_low();
Just4pLeisure 1:d5452e398b76 201
Just4pLeisure 1:d5452e398b76 202 // pull BKPT high
Just4pLeisure 1:d5452e398b76 203 case CMD_BKPTHIGH:
Just4pLeisure 1:d5452e398b76 204 return bkpt_high();
Just4pLeisure 1:d5452e398b76 205
Just4pLeisure 1:d5452e398b76 206 // pull RESET low
Just4pLeisure 1:d5452e398b76 207 case CMD_RESETLOW:
Just4pLeisure 1:d5452e398b76 208 return reset_low();
Just4pLeisure 1:d5452e398b76 209
Just4pLeisure 1:d5452e398b76 210 // pull RESET high
Just4pLeisure 1:d5452e398b76 211 case CMD_RESETHIGH:
Just4pLeisure 1:d5452e398b76 212 return reset_high();
Just4pLeisure 1:d5452e398b76 213 }
Just4pLeisure 1:d5452e398b76 214 break;
Just4pLeisure 1:d5452e398b76 215
Just4pLeisure 1:d5452e398b76 216 // MCU management
Just4pLeisure 1:d5452e398b76 217 case CMDGROUP_MCU:
Just4pLeisure 1:d5452e398b76 218 switch (cmd) {
Just4pLeisure 1:d5452e398b76 219 // stop target MCU
Just4pLeisure 1:d5452e398b76 220 case CMD_STOPCHIP:
Just4pLeisure 1:d5452e398b76 221 return stop_chip();
Just4pLeisure 1:d5452e398b76 222
Just4pLeisure 1:d5452e398b76 223 // reset target MCU
Just4pLeisure 1:d5452e398b76 224 case CMD_RESETCHIP:
Just4pLeisure 1:d5452e398b76 225 return reset_chip();
Just4pLeisure 1:d5452e398b76 226
Just4pLeisure 1:d5452e398b76 227 // run target MCU from given address
Just4pLeisure 1:d5452e398b76 228 case CMD_RUNCHIP:
Just4pLeisure 1:d5452e398b76 229 CHECK_ARGLENGTH(8);
Just4pLeisure 1:d5452e398b76 230 GET_NUMBER(&cmd_addr, 0, 8);
Just4pLeisure 1:d5452e398b76 231 return run_chip(&cmd_addr);
Just4pLeisure 1:d5452e398b76 232
Just4pLeisure 1:d5452e398b76 233 // restart
Just4pLeisure 1:d5452e398b76 234 case CMD_RESTART:
Just4pLeisure 1:d5452e398b76 235 return restart_chip();
Just4pLeisure 1:d5452e398b76 236
Just4pLeisure 1:d5452e398b76 237 // step
Just4pLeisure 1:d5452e398b76 238 case CMD_STEP:
Just4pLeisure 1:d5452e398b76 239 return step_chip();
Just4pLeisure 1:d5452e398b76 240 }
Just4pLeisure 1:d5452e398b76 241 break;
Just4pLeisure 1:d5452e398b76 242
Just4pLeisure 1:d5452e398b76 243 // Trionic dumping and flashing
Just4pLeisure 1:d5452e398b76 244 case CMDGROUP_FLASH:
Just4pLeisure 1:d5452e398b76 245 switch (cmd) {
Just4pLeisure 1:d5452e398b76 246 // get verification flag
Just4pLeisure 1:d5452e398b76 247 case CMD_GETVERIFY:
Just4pLeisure 1:d5452e398b76 248 CHECK_ARGLENGTH(0);
Just4pLeisure 1:d5452e398b76 249 printf("%02x", (uint8_t)verify_flash);
Just4pLeisure 4:682d96ff6d79 250 printf("\r\n");
Just4pLeisure 1:d5452e398b76 251 return TERM_OK;
Just4pLeisure 1:d5452e398b76 252
Just4pLeisure 1:d5452e398b76 253 // set verification flag
Just4pLeisure 1:d5452e398b76 254 case CMD_SETVERIFY:
Just4pLeisure 1:d5452e398b76 255 CHECK_ARGLENGTH(2);
Just4pLeisure 1:d5452e398b76 256 GET_NUMBER(&cmd_addr, 0, 2);
Just4pLeisure 1:d5452e398b76 257 verify_flash = (bool)cmd_addr;
Just4pLeisure 1:d5452e398b76 258 // eeprom_write_byte(&ee_verify, verify_flash);
Just4pLeisure 1:d5452e398b76 259 return TERM_OK;
Just4pLeisure 1:d5452e398b76 260
Just4pLeisure 1:d5452e398b76 261 // dump flash contents as block
Just4pLeisure 1:d5452e398b76 262 case CMD_DUMP:
Just4pLeisure 1:d5452e398b76 263 CHECK_ARGLENGTH(16);
Just4pLeisure 1:d5452e398b76 264 GET_NUMBER(&cmd_addr, 0, 8);
Just4pLeisure 1:d5452e398b76 265 GET_NUMBER(&cmd_value, 8, 8);
Just4pLeisure 1:d5452e398b76 266 return dump_flash(&cmd_addr, &cmd_value);
Just4pLeisure 1:d5452e398b76 267
Just4pLeisure 1:d5452e398b76 268 // erase entire flash memory
Just4pLeisure 1:d5452e398b76 269 case CMD_ERASE:
Just4pLeisure 1:d5452e398b76 270 CHECK_ARGLENGTH(22);
Just4pLeisure 1:d5452e398b76 271 GET_NUMBER(&cmd_addr, 6, 8);
Just4pLeisure 1:d5452e398b76 272 GET_NUMBER(&cmd_value, 14, 8);
Just4pLeisure 1:d5452e398b76 273 return erase_flash(cmd_buffer + 2, &cmd_addr, &cmd_value);
Just4pLeisure 1:d5452e398b76 274
Just4pLeisure 1:d5452e398b76 275 // write data block to flash memory
Just4pLeisure 1:d5452e398b76 276 case CMD_WRITE:
Just4pLeisure 1:d5452e398b76 277 CHECK_ARGLENGTH(14);
Just4pLeisure 1:d5452e398b76 278 GET_NUMBER(&cmd_addr, 6, 8);
Just4pLeisure 1:d5452e398b76 279 return write_flash(cmd_buffer + 2, &cmd_addr);
Just4pLeisure 1:d5452e398b76 280 }
Just4pLeisure 1:d5452e398b76 281 break;
Just4pLeisure 1:d5452e398b76 282
Just4pLeisure 1:d5452e398b76 283 // memory
Just4pLeisure 1:d5452e398b76 284 case CMDGROUP_MEMORY:
Just4pLeisure 1:d5452e398b76 285 if (cmd != CMD_FILLBYTE && cmd != CMD_FILLWORD &&
Just4pLeisure 1:d5452e398b76 286 cmd != CMD_FILLLONG && cmd != CMD_DUMPBYTE && cmd != CMD_DUMPWORD &&
Just4pLeisure 1:d5452e398b76 287 cmd != CMD_DUMPLONG) {
Just4pLeisure 1:d5452e398b76 288 // get memory address
Just4pLeisure 1:d5452e398b76 289 if (cmd_length < 10 || !ascii2int(&cmd_addr, cmd_buffer + 2, 8)) {
Just4pLeisure 1:d5452e398b76 290 // broken parametre
Just4pLeisure 1:d5452e398b76 291 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 292 }
Just4pLeisure 1:d5452e398b76 293
Just4pLeisure 1:d5452e398b76 294 // get optional value
Just4pLeisure 1:d5452e398b76 295 if (cmd_length > 10 &&
Just4pLeisure 1:d5452e398b76 296 !ascii2int(&cmd_value, cmd_buffer + 10, cmd_length - 10)) {
Just4pLeisure 1:d5452e398b76 297 // broken parametre
Just4pLeisure 1:d5452e398b76 298 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 299 }
Just4pLeisure 1:d5452e398b76 300 }
Just4pLeisure 1:d5452e398b76 301
Just4pLeisure 1:d5452e398b76 302 switch (cmd) {
Just4pLeisure 1:d5452e398b76 303 // read byte
Just4pLeisure 1:d5452e398b76 304 case CMD_READBYTE:
Just4pLeisure 1:d5452e398b76 305 if (cmd_length != 10 ||
Just4pLeisure 1:d5452e398b76 306 memread_byte((uint8_t*)(&cmd_result), &cmd_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 307 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 308 }
Just4pLeisure 1:d5452e398b76 309 printf("%02x", (uint8_t)cmd_result);
Just4pLeisure 4:682d96ff6d79 310 printf("\r\n");
Just4pLeisure 1:d5452e398b76 311 return TERM_OK;
Just4pLeisure 1:d5452e398b76 312
Just4pLeisure 1:d5452e398b76 313 // read word
Just4pLeisure 1:d5452e398b76 314 case CMD_READWORD:
Just4pLeisure 1:d5452e398b76 315 if (cmd_length != 10 ||
Just4pLeisure 1:d5452e398b76 316 memread_word((uint16_t*)(&cmd_result), &cmd_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 317 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 318 }
Just4pLeisure 1:d5452e398b76 319 printf("%04X", (uint16_t)cmd_result);
Just4pLeisure 4:682d96ff6d79 320 printf("\r\n");
Just4pLeisure 1:d5452e398b76 321 return TERM_OK;
Just4pLeisure 1:d5452e398b76 322
Just4pLeisure 1:d5452e398b76 323 // read long word
Just4pLeisure 1:d5452e398b76 324 case CMD_READLONG:
Just4pLeisure 1:d5452e398b76 325 if (cmd_length != 10 ||
Just4pLeisure 1:d5452e398b76 326 memread_long(&cmd_result, &cmd_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 327 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 328 }
Just4pLeisure 1:d5452e398b76 329 printf("%08X", cmd_result);
Just4pLeisure 4:682d96ff6d79 330 printf("\r\n");
Just4pLeisure 1:d5452e398b76 331 return TERM_OK;
Just4pLeisure 1:d5452e398b76 332
Just4pLeisure 1:d5452e398b76 333 // dump byte
Just4pLeisure 1:d5452e398b76 334 case CMD_DUMPBYTE:
Just4pLeisure 1:d5452e398b76 335 if (cmd_length != 2 ||
Just4pLeisure 1:d5452e398b76 336 memdump_byte((uint8_t*)(&cmd_result)) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 337 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 338 }
Just4pLeisure 1:d5452e398b76 339 printf("%02x", (uint8_t)cmd_result);
Just4pLeisure 4:682d96ff6d79 340 printf("\r\n");
Just4pLeisure 1:d5452e398b76 341 return TERM_OK;
Just4pLeisure 1:d5452e398b76 342
Just4pLeisure 1:d5452e398b76 343 // dump word
Just4pLeisure 1:d5452e398b76 344 case CMD_DUMPWORD:
Just4pLeisure 1:d5452e398b76 345 if (cmd_length != 2 ||
Just4pLeisure 1:d5452e398b76 346 memdump_word((uint16_t*)(&cmd_result)) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 347 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 348 }
Just4pLeisure 1:d5452e398b76 349 printf("%04X", (uint16_t)cmd_result);
Just4pLeisure 4:682d96ff6d79 350 printf("\r\n");
Just4pLeisure 1:d5452e398b76 351 return TERM_OK;
Just4pLeisure 1:d5452e398b76 352
Just4pLeisure 1:d5452e398b76 353 // dump long word
Just4pLeisure 1:d5452e398b76 354 case CMD_DUMPLONG:
Just4pLeisure 1:d5452e398b76 355 if (cmd_length != 2 ||
Just4pLeisure 1:d5452e398b76 356 memdump_long(&cmd_result) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 357 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 358 }
Just4pLeisure 1:d5452e398b76 359 printf("%08X", cmd_result);
Just4pLeisure 4:682d96ff6d79 360 printf("\r\n");
Just4pLeisure 1:d5452e398b76 361 return TERM_OK;
Just4pLeisure 1:d5452e398b76 362
Just4pLeisure 1:d5452e398b76 363 // write byte
Just4pLeisure 1:d5452e398b76 364 case CMD_WRITEBYTE:
Just4pLeisure 1:d5452e398b76 365 return (cmd_length == 12 &&
Just4pLeisure 1:d5452e398b76 366 memwrite_byte(&cmd_addr, cmd_value) == TERM_OK) ?
Just4pLeisure 1:d5452e398b76 367 TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 368
Just4pLeisure 1:d5452e398b76 369 // write word
Just4pLeisure 1:d5452e398b76 370 case CMD_WRITEWORD:
Just4pLeisure 1:d5452e398b76 371 return (cmd_length == 14 &&
Just4pLeisure 1:d5452e398b76 372 memwrite_word(&cmd_addr, cmd_value) == TERM_OK) ?
Just4pLeisure 1:d5452e398b76 373 TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 374
Just4pLeisure 1:d5452e398b76 375 // write long word
Just4pLeisure 1:d5452e398b76 376 case CMD_WRITELONG:
Just4pLeisure 1:d5452e398b76 377 return (cmd_length == 18 &&
Just4pLeisure 1:d5452e398b76 378 memwrite_long(&cmd_addr, &cmd_value) == TERM_OK) ?
Just4pLeisure 1:d5452e398b76 379 TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 380
Just4pLeisure 1:d5452e398b76 381 // fill byte
Just4pLeisure 1:d5452e398b76 382 case CMD_FILLBYTE:
Just4pLeisure 1:d5452e398b76 383 if (cmd_length != 4 || !ascii2int(&cmd_value, cmd_buffer + 2, 2)) {
Just4pLeisure 1:d5452e398b76 384 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 385 }
Just4pLeisure 1:d5452e398b76 386 return (memfill_byte(cmd_value));
Just4pLeisure 1:d5452e398b76 387
Just4pLeisure 1:d5452e398b76 388 // fill word
Just4pLeisure 1:d5452e398b76 389 case CMD_FILLWORD:
Just4pLeisure 1:d5452e398b76 390 if (cmd_length != 6 || !ascii2int(&cmd_value, cmd_buffer + 2, 4)) {
Just4pLeisure 1:d5452e398b76 391 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 392 }
Just4pLeisure 1:d5452e398b76 393 return (memfill_word(cmd_value));
Just4pLeisure 1:d5452e398b76 394
Just4pLeisure 1:d5452e398b76 395 // fill long word
Just4pLeisure 1:d5452e398b76 396 case CMD_FILLLONG:
Just4pLeisure 1:d5452e398b76 397 if (cmd_length != 10 || !ascii2int(&cmd_value, cmd_buffer + 2, 8)) {
Just4pLeisure 1:d5452e398b76 398 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 399 }
Just4pLeisure 1:d5452e398b76 400 return (memfill_long(&cmd_value));
Just4pLeisure 1:d5452e398b76 401 }
Just4pLeisure 1:d5452e398b76 402 break;
Just4pLeisure 1:d5452e398b76 403
Just4pLeisure 1:d5452e398b76 404 // registers
Just4pLeisure 1:d5452e398b76 405 case CMDGROUP_REGISTER:
Just4pLeisure 1:d5452e398b76 406 // get register code
Just4pLeisure 1:d5452e398b76 407 if (cmd_length < 4 || !ascii2int(&cmd_addr, cmd_buffer + 3, 1)) {
Just4pLeisure 1:d5452e398b76 408 // broken parametre
Just4pLeisure 1:d5452e398b76 409 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 410 }
Just4pLeisure 1:d5452e398b76 411
Just4pLeisure 1:d5452e398b76 412 // get optional value
Just4pLeisure 1:d5452e398b76 413 if (cmd_length > 4 &&
Just4pLeisure 1:d5452e398b76 414 !ascii2int(&cmd_value, cmd_buffer + 4, 8)) {
Just4pLeisure 1:d5452e398b76 415 // broken parametre
Just4pLeisure 1:d5452e398b76 416 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 417 }
Just4pLeisure 1:d5452e398b76 418
Just4pLeisure 1:d5452e398b76 419 switch (cmd) {
Just4pLeisure 1:d5452e398b76 420 // read system register
Just4pLeisure 1:d5452e398b76 421 case CMD_READSYSREG:
Just4pLeisure 1:d5452e398b76 422 if (cmd_length != 4 ||
Just4pLeisure 1:d5452e398b76 423 sysreg_read(&cmd_result, (uint8_t)cmd_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 424 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 425 }
Just4pLeisure 1:d5452e398b76 426 printf("%08X", cmd_result);
Just4pLeisure 4:682d96ff6d79 427 printf("\r\n");
Just4pLeisure 1:d5452e398b76 428 return TERM_OK;
Just4pLeisure 1:d5452e398b76 429
Just4pLeisure 1:d5452e398b76 430 // write system register
Just4pLeisure 1:d5452e398b76 431 case CMD_WRITESYSREG:
Just4pLeisure 1:d5452e398b76 432 return (cmd_length == 12 &&
Just4pLeisure 1:d5452e398b76 433 sysreg_write((uint8_t)cmd_addr, &cmd_value) == TERM_OK) ?
Just4pLeisure 1:d5452e398b76 434 TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 435
Just4pLeisure 1:d5452e398b76 436 // read A/D register
Just4pLeisure 1:d5452e398b76 437 case CMD_READADREG:
Just4pLeisure 1:d5452e398b76 438 if (cmd_length != 4 ||
Just4pLeisure 1:d5452e398b76 439 adreg_read(&cmd_result, (uint8_t)cmd_addr) != TERM_OK) {
Just4pLeisure 1:d5452e398b76 440 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 441 }
Just4pLeisure 1:d5452e398b76 442 printf("%08X", cmd_result);
Just4pLeisure 4:682d96ff6d79 443 printf("\r\n");
Just4pLeisure 1:d5452e398b76 444 return TERM_OK;
Just4pLeisure 1:d5452e398b76 445
Just4pLeisure 1:d5452e398b76 446 // write A/D register
Just4pLeisure 1:d5452e398b76 447 case CMD_WRITEADREG:
Just4pLeisure 1:d5452e398b76 448 return (cmd_length == 12 &&
Just4pLeisure 1:d5452e398b76 449 adreg_write((uint8_t)cmd_addr, &cmd_value) == TERM_OK) ?
Just4pLeisure 1:d5452e398b76 450 TERM_OK : TERM_ERR;
Just4pLeisure 1:d5452e398b76 451 }
Just4pLeisure 1:d5452e398b76 452 break;
Just4pLeisure 1:d5452e398b76 453
Just4pLeisure 1:d5452e398b76 454 // Trionic dumping and flashing
Just4pLeisure 1:d5452e398b76 455 case CMDGROUP_TRIONIC:
Just4pLeisure 1:d5452e398b76 456
Just4pLeisure 1:d5452e398b76 457 switch (cmd) {
Just4pLeisure 1:d5452e398b76 458
Just4pLeisure 1:d5452e398b76 459 // dump flash contents to a bin file
Just4pLeisure 1:d5452e398b76 460 case CMD_TRIONICDUMP:
Just4pLeisure 1:d5452e398b76 461 CHECK_ARGLENGTH(0);
Just4pLeisure 1:d5452e398b76 462 return dump_trionic();
Just4pLeisure 1:d5452e398b76 463
Just4pLeisure 1:d5452e398b76 464 // write data block to flash memory
Just4pLeisure 1:d5452e398b76 465 case CMD_TRIONICWRITE:
Just4pLeisure 1:d5452e398b76 466 CHECK_ARGLENGTH(0);
Just4pLeisure 1:d5452e398b76 467 return flash_trionic();
Just4pLeisure 1:d5452e398b76 468 }
Just4pLeisure 1:d5452e398b76 469
Just4pLeisure 1:d5452e398b76 470 // show help for BDM commands
Just4pLeisure 1:d5452e398b76 471 case 'H':
Just4pLeisure 1:d5452e398b76 472 bdm_show_full_help();
Just4pLeisure 1:d5452e398b76 473 return TERM_OK;
Just4pLeisure 1:d5452e398b76 474 case 'h':
Just4pLeisure 1:d5452e398b76 475 bdm_show_help();
Just4pLeisure 1:d5452e398b76 476 return TERM_OK;
Just4pLeisure 1:d5452e398b76 477 default:
Just4pLeisure 1:d5452e398b76 478 bdm_show_help();
Just4pLeisure 1:d5452e398b76 479 }
Just4pLeisure 1:d5452e398b76 480
Just4pLeisure 1:d5452e398b76 481 // unknown command
Just4pLeisure 1:d5452e398b76 482 return TERM_ERR;
Just4pLeisure 1:d5452e398b76 483 }
Just4pLeisure 1:d5452e398b76 484
Just4pLeisure 1:d5452e398b76 485 void bdm_show_help() {
Just4pLeisure 1:d5452e398b76 486 printf("Just4Trionic BDM Command Menu\r\n");
Just4pLeisure 1:d5452e398b76 487 printf("=============================\r\n");
Just4pLeisure 1:d5452e398b76 488 printf("TD - and DUMP T5 FLASH BIN file\r\n");
Just4pLeisure 1:d5452e398b76 489 printf("TF - FLASH the update file to the T5 (and write SRAM)\r\n");
Just4pLeisure 1:d5452e398b76 490 printf("Tr - Read SRAM adaption (not done).\r\n");
Just4pLeisure 1:d5452e398b76 491 printf("Tw - Write SRAM adaptation (not done).\r\n");
Just4pLeisure 1:d5452e398b76 492 printf("\r\n");
Just4pLeisure 1:d5452e398b76 493 printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
Just4pLeisure 1:d5452e398b76 494 printf("\r\n");
Just4pLeisure 1:d5452e398b76 495 printf("h - Show this help menu\r\n");
Just4pLeisure 1:d5452e398b76 496 printf("\r\n");
Just4pLeisure 1:d5452e398b76 497 return;
Just4pLeisure 1:d5452e398b76 498 }
Just4pLeisure 1:d5452e398b76 499 void bdm_show_full_help() {
Just4pLeisure 1:d5452e398b76 500 printf("Just4Trionic BDM Command Menu\r\n");
Just4pLeisure 1:d5452e398b76 501 printf("=============================\r\n");
Just4pLeisure 1:d5452e398b76 502 printf("TD - and DUMP T5 FLASH BIN file\r\n");
Just4pLeisure 1:d5452e398b76 503 printf("TF - FLASH the update file to the T5 (and write SRAM)\r\n");
Just4pLeisure 1:d5452e398b76 504 printf("Tr - Read SRAM adaption (not done).\r\n");
Just4pLeisure 1:d5452e398b76 505 printf("Tw - Write SRAM adaptation (not done).\r\n");
Just4pLeisure 1:d5452e398b76 506 printf("\r\n");
Just4pLeisure 1:d5452e398b76 507 printf("Adapter Commands - a\r\n");
Just4pLeisure 1:d5452e398b76 508 printf("====================\r\n");
Just4pLeisure 1:d5452e398b76 509 printf("av - display firmware version\r\n");
Just4pLeisure 1:d5452e398b76 510 printf("as - display status of BDM pins\r\n");
Just4pLeisure 1:d5452e398b76 511 printf("a1 - pull BKPT low\r\n");
Just4pLeisure 1:d5452e398b76 512 printf("a2 - pull BKPT high\r\n");
Just4pLeisure 1:d5452e398b76 513 printf("a3 - pull RESET low\r\n");
Just4pLeisure 1:d5452e398b76 514 printf("a4 - pull RESET high\r\n");
Just4pLeisure 1:d5452e398b76 515 printf("\r\n");
Just4pLeisure 1:d5452e398b76 516 printf("MCU Management Commands - c\r\n");
Just4pLeisure 1:d5452e398b76 517 printf("===========================\r\n");
Just4pLeisure 1:d5452e398b76 518 printf("cS - stop MCU\r\n");
Just4pLeisure 1:d5452e398b76 519 printf("cR - reset MCU\r\n");
Just4pLeisure 1:d5452e398b76 520 printf("cr - run from given address\r\n");
Just4pLeisure 1:d5452e398b76 521 printf(" e.g. crCAFEBABE run from address 0xcafebabe\r\n");
Just4pLeisure 1:d5452e398b76 522 printf("cs - restart MCU\r\n");
Just4pLeisure 1:d5452e398b76 523 printf("cb - step MCU\r\n");
Just4pLeisure 1:d5452e398b76 524 printf("\r\n");
Just4pLeisure 1:d5452e398b76 525 printf("MCU FLASH Commands - f\r\n");
Just4pLeisure 1:d5452e398b76 526 printf("======================\r\n");
Just4pLeisure 1:d5452e398b76 527 printf("fv - gets verification status (always verify)\r\n");
Just4pLeisure 1:d5452e398b76 528 printf("fV - sets verification on/off (always on)\r\n");
Just4pLeisure 1:d5452e398b76 529 printf("fd - DUMPs memory contents\r\n");
Just4pLeisure 1:d5452e398b76 530 printf(" e.g. fdSSSSSSSSEEEEEEEE S...E... start and end addresses\r\n");
Just4pLeisure 1:d5452e398b76 531 printf(" e.g. fd0000000000020000 to DUMP T5.2\r\n");
Just4pLeisure 1:d5452e398b76 532 printf(" e.g. fd0000000000040000 to DUMP T5.5\r\n");
Just4pLeisure 1:d5452e398b76 533 printf(" e.g. fd0000000000080000 to DUMP T7\r\n");
Just4pLeisure 1:d5452e398b76 534 printf("fE - Erases entire FLASH memory\r\n");
Just4pLeisure 1:d5452e398b76 535 printf(" e.g. fETTTTTTSSSSSSSSEEEEEEEE T...S...E type, start and end addresses\r\n");
Just4pLeisure 1:d5452e398b76 536 printf(" e.g. fE28f0100000000000020000 erase 28F512 in T5.2\r\n");
Just4pLeisure 1:d5452e398b76 537 printf(" e.g. fE28f0100000000000040000 erase 28F010 in T5.5\r\n");
Just4pLeisure 1:d5452e398b76 538 printf(" e.g. fE29f0100000000000040000 erase 29F010 in T5.5 (addresses not used)\r\n");
Just4pLeisure 1:d5452e398b76 539 printf(" e.g. fE29f4000000000000080000 erase 29F400 in T7 (addresses not used)\r\n");
Just4pLeisure 1:d5452e398b76 540 printf("fw - writes to FLASH memory\r\n");
Just4pLeisure 1:d5452e398b76 541 printf(" Write a batch of long words to flash from a start address\r\n");
Just4pLeisure 1:d5452e398b76 542 printf(" followed by longwords LLLLLLLL, LLLLLLLL etc\r\n");
Just4pLeisure 1:d5452e398b76 543 printf(" Send a break character to stop when doneg");
Just4pLeisure 1:d5452e398b76 544 printf(" e.g. fwTTTTTTSSSSSSSS T...S... type and start address\r\n");
Just4pLeisure 1:d5452e398b76 545 printf(" e.g. fw28f01000004000 start at address 0x004000 T5.2/5.5\r\n");
Just4pLeisure 1:d5452e398b76 546 printf(" e.g. fw29f01000004000 start at address 0x004000 T5.5 with 29F010\r\n");
Just4pLeisure 1:d5452e398b76 547 printf(" e.g. fw29f40000004000 start at address 0x004000 T7\r\n");
Just4pLeisure 1:d5452e398b76 548 printf("\r\n");
Just4pLeisure 1:d5452e398b76 549 printf("MCU Memory Commands - m\r\n");
Just4pLeisure 1:d5452e398b76 550 printf("=======================\r\n");
Just4pLeisure 1:d5452e398b76 551 printf("mbAAAAAAAA - read byte from memory at 0xaaaaaaaa\r\n");
Just4pLeisure 1:d5452e398b76 552 printf("mwAAAAAAAA - read word (2 bytes) from memory\r\n");
Just4pLeisure 1:d5452e398b76 553 printf("mlAAAAAAAA - read long word (4 bytes) from memory\r\n");
Just4pLeisure 1:d5452e398b76 554 printf("mz - dump byte from the next memory address\r\n");
Just4pLeisure 1:d5452e398b76 555 printf("mx - dump word from the next memory address\r\n");
Just4pLeisure 1:d5452e398b76 556 printf("mc - dump long word from the next memory address\r\n");
Just4pLeisure 1:d5452e398b76 557 printf("mBAAAAAAAADD - write byte 0xdd to memory 0xaaaaaaaa\r\n");
Just4pLeisure 1:d5452e398b76 558 printf("mWAAAAAAAADDDD - write word 0xdddd to memory 0xaaaaaaaa\r\n");
Just4pLeisure 1:d5452e398b76 559 printf("mLAAAAAAAADDDDDDD - write long word 0xdddddddd to memory 0xaaaaaaaa\r\n");
Just4pLeisure 1:d5452e398b76 560 printf("mfDD - fill byte 0xdd to next memory address\r\n");
Just4pLeisure 1:d5452e398b76 561 printf("mFDDDD - fill word 0xdddd to next memory address\r\n");
Just4pLeisure 1:d5452e398b76 562 printf("mMDDDDDDDD - fill long word 0xdddddddd to next memory address\r\n");
Just4pLeisure 1:d5452e398b76 563 printf("\r\n");
Just4pLeisure 1:d5452e398b76 564 printf("MCU Register Commands - r\r\n");
Just4pLeisure 1:d5452e398b76 565 printf("=========================\r\n");
Just4pLeisure 1:d5452e398b76 566 printf("rrRR - read system register RR\r\n");
Just4pLeisure 1:d5452e398b76 567 printf(" 00 - RPC, 01 - PCC, 0B - SR, 0C - USP, 0D - SSP\r\n");
Just4pLeisure 1:d5452e398b76 568 printf(" 0e - SFC, 0f - DFC, 08 - ATEMP, 09 - FAR, 0a - VBR\r\n");
Just4pLeisure 1:d5452e398b76 569 printf("rWRRCAFEBABE - write 0xcafebabe system register RR\r\n");
Just4pLeisure 1:d5452e398b76 570 printf("raAD - read A/D register 0x00-07 D0-D7, 0x08-15 A0-A7\r\n");
Just4pLeisure 1:d5452e398b76 571 printf("rAADCAFEBABE - write 0xcafebabe to A/D register \r\n");
Just4pLeisure 1:d5452e398b76 572 printf("\r\n");
Just4pLeisure 1:d5452e398b76 573 printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
Just4pLeisure 1:d5452e398b76 574 printf("\r\n");
Just4pLeisure 1:d5452e398b76 575 printf("H - Show this help menu\r\n");
Just4pLeisure 1:d5452e398b76 576 printf("\r\n");
Just4pLeisure 1:d5452e398b76 577 return;
Just4pLeisure 1:d5452e398b76 578 }