Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: bdm.cpp
- Revision:
- 1:d5452e398b76
- Child:
- 2:bf3a2b29259a
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bdm.cpp Tue Sep 14 21:02:04 2010 +0000
@@ -0,0 +1,567 @@
+/*******************************************************************************
+
+bdm.cpp
+(c) 2010 by Sophie Dexter
+
+BDM functions for Just4Trionic by Just4pLeisure
+
+A derivative work based on:
+//-----------------------------------------------------------------------------
+// Firmware for USB BDM v2.0
+// (C) johnc, 2009
+// $id$
+//-----------------------------------------------------------------------------
+
+********************************************************************************
+
+WARNING: Use at your own risk, sadly this software comes with no guarantees.
+This software is provided 'free' and in good faith, but the author does not
+accept liability for any damage arising from its use.
+
+*******************************************************************************/
+
+#include "bdm.h"
+
+// constants
+#define CMD_BUF_LENGTH 32 ///< command buffer size
+
+// LED constants and macros
+#define LED_ONTIME 5 ///< LED 'on' time, ms
+#define LED_TCNT (255 - (unsigned char)((unsigned long)(LED_ONTIME * 1000L) \
+ / (1000000L / (float)((unsigned long)XTAL_CPU / 1024L))))
+
+// command characters
+#define CMDGROUP_ADAPTER 'a' ///< adapter commands
+#define CMD_VERSION 'v' ///< firmware version
+#define CMD_PINSTATUS 's' ///< momentary status of BDM pins
+#define CMD_BKPTLOW '1' ///< pull BKPT low
+#define CMD_BKPTHIGH '2' ///< pull BKPT high
+#define CMD_RESETLOW '3' ///< pull RESET low
+#define CMD_RESETHIGH '4' ///< pull RESET high
+
+#define CMDGROUP_MCU 'c' ///< target MCU management commands
+#define CMD_STOPCHIP 'S' ///< stop
+#define CMD_RESETCHIP 'R' ///< reset
+#define CMD_RUNCHIP 'r' ///< run from given address
+#define CMD_RESTART 's' ///< restart
+#define CMD_STEP 'b' ///< step
+
+#define CMDGROUP_FLASH 'f'
+#define CMD_GETVERIFY 'v' ///< gets verification status
+#define CMD_SETVERIFY 'V' ///< sets verification on/off
+#define CMD_DUMP 'd' ///< dumps memory contents
+#define CMD_ERASE 'E' ///< erase entire flash memory
+#define CMD_WRITE 'w' ///< writes to flash memory
+
+#define CMDGROUP_MEMORY 'm' ///< target MCU memory commands
+#define CMD_READBYTE 'b' ///< read byte from memory
+#define CMD_READWORD 'w' ///< read word (2 bytes) from memory
+#define CMD_READLONG 'l' ///< read long word (4 bytes) from memory
+#define CMD_DUMPBYTE 'z' ///< dump byte from memory
+#define CMD_DUMPWORD 'x' ///< dump word from memory
+#define CMD_DUMPLONG 'c' ///< dump long word from memory
+#define CMD_WRITEBYTE 'B' ///< write byte to memory
+#define CMD_WRITEWORD 'W' ///< write word to memory
+#define CMD_WRITELONG 'L' ///< write long word to memory
+#define CMD_FILLBYTE 'f' ///< fill byte in memory
+#define CMD_FILLWORD 'F' ///< fill word in memory
+#define CMD_FILLLONG 'M' ///< fill long word in memory
+
+#define CMDGROUP_REGISTER 'r' ///< register commands
+#define CMD_READSYSREG 'r' ///< read system register
+#define CMD_WRITESYSREG 'W' ///< write system register
+#define CMD_READADREG 'a' ///< read A/D register
+#define CMD_WRITEADREG 'A' ///< write A/D register
+
+#define CMDGROUP_TRIONIC 'T'
+#define CMD_TRIONICDUMP 'D' ///< dumps memory contents
+#define CMD_TRIONICWRITE 'F' ///< writes to flash memory
+
+// static variables
+static char cmd_buffer[CMD_BUF_LENGTH]; ///< command string buffer
+static uint32_t cmd_addr; ///< address (optional)
+static uint32_t cmd_value; ///< value (optional)
+static uint32_t cmd_result; ///< result
+
+// private functions
+uint8_t execute_bdm_cmd();
+
+void bdm_show_help();
+void bdm_show_full_help();
+
+// command argument macros
+#define CHECK_ARGLENGTH(len) \
+ if (cmd_length != len + 2) \
+ return TERM_ERR
+
+#define GET_NUMBER(target, offset, len) \
+ if (!ascii2int(target, cmd_buffer + 2 + offset, len)) \
+ return TERM_ERR
+
+
+void bdm() {
+
+ bdm_show_help();
+ // set up LED pins
+// SETBIT(LED_DIR, _BV(LED_ERR) | _BV(LED_ACT));
+ // set up USB_RD and USB_WR pins
+// SETBIT(USB_RXTX_DIR, _BV(USB_RD) | _BV(USB_WR));
+
+ // enable interrupts
+// sei();
+
+ // load configuration from EEPROM
+// verify_flash = eeprom_read_byte(&ee_verify);
+
+// Set some initial values to help with checking if the BDM connector is plugged in
+ PIN_PWR.mode(PullDown);
+ PIN_NC.mode(PullUp);
+ PIN_DS.mode(PullUp);
+ PIN_FREEZE.mode(PullUp);
+ PIN_DSO.mode(PullUp);
+
+ verify_flash = true;
+
+ // main loop
+ *cmd_buffer = '\0';
+ char ret;
+ char rx_char;
+ while (true) {
+ // read chars from USB
+ if (pc.readable()) {
+ // turn Error LED off for next command
+ led4 = 0;
+ rx_char = pc.getc();
+ switch (rx_char) {
+ // 'ESC' key to go back to mbed Just4Trionic 'home' menu
+ case '\e':
+ reset_chip();
+ return;
+ // end-of-command reached
+ case TERM_OK :
+ // execute command and return flag via USB
+ ret = execute_bdm_cmd();
+ pc.putc(ret);
+ // reset command buffer
+ *cmd_buffer = '\0';
+ // light up LED
+// ret == TERM_OK ? led_on(LED_ACT) : led_on(LED_ERR);
+ ret == TERM_OK ? led3 = 1 : led4 = 1;
+ break;
+ // another command char
+ default:
+ // store in buffer if space permits
+ if (StrLen(cmd_buffer) < CMD_BUF_LENGTH - 1) {
+ StrAddc(cmd_buffer, rx_char);
+ }
+ break;
+ }
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+/**
+ Executes a command and returns result flag (does not transmit the flag
+ itself).
+
+ @return command flag (success / failure)
+*/
+uint8_t execute_bdm_cmd() {
+ uint8_t cmd_length = strlen(cmd_buffer);
+ char cmd = *(cmd_buffer + 1);
+
+ // command groups
+ switch (*cmd_buffer) {
+ // adapter commands
+ case CMDGROUP_ADAPTER:
+ CHECK_ARGLENGTH(0);
+ switch (cmd) {
+ // get firmware version
+ case CMD_VERSION:
+ printf("%02x", FW_VERSION_MAJOR);
+ printf("%02x", FW_VERSION_MINOR);
+ return TERM_OK;
+
+ // get momentary status of BDM pins 0...5 (for debugging)
+ case CMD_PINSTATUS:
+// printf("%02x", (BDM_PIN & 0x3f));
+ printf("PWR %d, ", PIN_PWR.read());
+ printf("NC %d, ", PIN_NC.read());
+ printf("DS %d, ", PIN_DS.read());
+ printf("FREEZE %d, ", PIN_FREEZE.read());
+ printf("DSO %d, ", PIN_DSO.read());
+ return TERM_OK;
+
+ // pull BKPT low
+ case CMD_BKPTLOW:
+ return bkpt_low();
+
+ // pull BKPT high
+ case CMD_BKPTHIGH:
+ return bkpt_high();
+
+ // pull RESET low
+ case CMD_RESETLOW:
+ return reset_low();
+
+ // pull RESET high
+ case CMD_RESETHIGH:
+ return reset_high();
+ }
+ break;
+
+ // MCU management
+ case CMDGROUP_MCU:
+ switch (cmd) {
+ // stop target MCU
+ case CMD_STOPCHIP:
+ return stop_chip();
+
+ // reset target MCU
+ case CMD_RESETCHIP:
+ return reset_chip();
+
+ // run target MCU from given address
+ case CMD_RUNCHIP:
+ CHECK_ARGLENGTH(8);
+ GET_NUMBER(&cmd_addr, 0, 8);
+ return run_chip(&cmd_addr);
+
+ // restart
+ case CMD_RESTART:
+ return restart_chip();
+
+ // step
+ case CMD_STEP:
+ return step_chip();
+ }
+ break;
+
+ // Trionic dumping and flashing
+ case CMDGROUP_FLASH:
+ switch (cmd) {
+ // get verification flag
+ case CMD_GETVERIFY:
+ CHECK_ARGLENGTH(0);
+ printf("%02x", (uint8_t)verify_flash);
+ return TERM_OK;
+
+ // set verification flag
+ case CMD_SETVERIFY:
+ CHECK_ARGLENGTH(2);
+ GET_NUMBER(&cmd_addr, 0, 2);
+ verify_flash = (bool)cmd_addr;
+// eeprom_write_byte(&ee_verify, verify_flash);
+ return TERM_OK;
+
+ // dump flash contents as block
+ case CMD_DUMP:
+ CHECK_ARGLENGTH(16);
+ GET_NUMBER(&cmd_addr, 0, 8);
+ GET_NUMBER(&cmd_value, 8, 8);
+ return dump_flash(&cmd_addr, &cmd_value);
+
+ // erase entire flash memory
+ case CMD_ERASE:
+ CHECK_ARGLENGTH(22);
+ GET_NUMBER(&cmd_addr, 6, 8);
+ GET_NUMBER(&cmd_value, 14, 8);
+ return erase_flash(cmd_buffer + 2, &cmd_addr, &cmd_value);
+
+ // write data block to flash memory
+ case CMD_WRITE:
+ CHECK_ARGLENGTH(14);
+ GET_NUMBER(&cmd_addr, 6, 8);
+ return write_flash(cmd_buffer + 2, &cmd_addr);
+ }
+ break;
+
+ // memory
+ case CMDGROUP_MEMORY:
+ if (cmd != CMD_FILLBYTE && cmd != CMD_FILLWORD &&
+ cmd != CMD_FILLLONG && cmd != CMD_DUMPBYTE && cmd != CMD_DUMPWORD &&
+ cmd != CMD_DUMPLONG) {
+ // get memory address
+ if (cmd_length < 10 || !ascii2int(&cmd_addr, cmd_buffer + 2, 8)) {
+ // broken parametre
+ return TERM_ERR;
+ }
+
+ // get optional value
+ if (cmd_length > 10 &&
+ !ascii2int(&cmd_value, cmd_buffer + 10, cmd_length - 10)) {
+ // broken parametre
+ return TERM_ERR;
+ }
+ }
+
+ switch (cmd) {
+ // read byte
+ case CMD_READBYTE:
+ if (cmd_length != 10 ||
+ memread_byte((uint8_t*)(&cmd_result), &cmd_addr) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%02x", (uint8_t)cmd_result);
+ return TERM_OK;
+
+ // read word
+ case CMD_READWORD:
+ if (cmd_length != 10 ||
+ memread_word((uint16_t*)(&cmd_result), &cmd_addr) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%04X", (uint16_t)cmd_result);
+ return TERM_OK;
+
+ // read long word
+ case CMD_READLONG:
+ if (cmd_length != 10 ||
+ memread_long(&cmd_result, &cmd_addr) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%08X", cmd_result);
+ return TERM_OK;
+
+ // dump byte
+ case CMD_DUMPBYTE:
+ if (cmd_length != 2 ||
+ memdump_byte((uint8_t*)(&cmd_result)) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%02x", (uint8_t)cmd_result);
+ return TERM_OK;
+
+ // dump word
+ case CMD_DUMPWORD:
+ if (cmd_length != 2 ||
+ memdump_word((uint16_t*)(&cmd_result)) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%04X", (uint16_t)cmd_result);
+ return TERM_OK;
+
+ // dump long word
+ case CMD_DUMPLONG:
+ if (cmd_length != 2 ||
+ memdump_long(&cmd_result) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%08X", cmd_result);
+ return TERM_OK;
+
+ // write byte
+ case CMD_WRITEBYTE:
+ return (cmd_length == 12 &&
+ memwrite_byte(&cmd_addr, cmd_value) == TERM_OK) ?
+ TERM_OK : TERM_ERR;
+
+ // write word
+ case CMD_WRITEWORD:
+ return (cmd_length == 14 &&
+ memwrite_word(&cmd_addr, cmd_value) == TERM_OK) ?
+ TERM_OK : TERM_ERR;
+
+ // write long word
+ case CMD_WRITELONG:
+ return (cmd_length == 18 &&
+ memwrite_long(&cmd_addr, &cmd_value) == TERM_OK) ?
+ TERM_OK : TERM_ERR;
+
+ // fill byte
+ case CMD_FILLBYTE:
+ if (cmd_length != 4 || !ascii2int(&cmd_value, cmd_buffer + 2, 2)) {
+ return TERM_ERR;
+ }
+ return (memfill_byte(cmd_value));
+
+ // fill word
+ case CMD_FILLWORD:
+ if (cmd_length != 6 || !ascii2int(&cmd_value, cmd_buffer + 2, 4)) {
+ return TERM_ERR;
+ }
+ return (memfill_word(cmd_value));
+
+ // fill long word
+ case CMD_FILLLONG:
+ if (cmd_length != 10 || !ascii2int(&cmd_value, cmd_buffer + 2, 8)) {
+ return TERM_ERR;
+ }
+ return (memfill_long(&cmd_value));
+ }
+ break;
+
+ // registers
+ case CMDGROUP_REGISTER:
+ // get register code
+ if (cmd_length < 4 || !ascii2int(&cmd_addr, cmd_buffer + 3, 1)) {
+ // broken parametre
+ return TERM_ERR;
+ }
+
+ // get optional value
+ if (cmd_length > 4 &&
+ !ascii2int(&cmd_value, cmd_buffer + 4, 8)) {
+ // broken parametre
+ return TERM_ERR;
+ }
+
+ switch (cmd) {
+ // read system register
+ case CMD_READSYSREG:
+ if (cmd_length != 4 ||
+ sysreg_read(&cmd_result, (uint8_t)cmd_addr) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%08X", cmd_result);
+ return TERM_OK;
+
+ // write system register
+ case CMD_WRITESYSREG:
+ return (cmd_length == 12 &&
+ sysreg_write((uint8_t)cmd_addr, &cmd_value) == TERM_OK) ?
+ TERM_OK : TERM_ERR;
+
+ // read A/D register
+ case CMD_READADREG:
+ if (cmd_length != 4 ||
+ adreg_read(&cmd_result, (uint8_t)cmd_addr) != TERM_OK) {
+ return TERM_ERR;
+ }
+ printf("%08X", cmd_result);
+ return TERM_OK;
+
+ // write A/D register
+ case CMD_WRITEADREG:
+ return (cmd_length == 12 &&
+ adreg_write((uint8_t)cmd_addr, &cmd_value) == TERM_OK) ?
+ TERM_OK : TERM_ERR;
+ }
+ break;
+
+ // Trionic dumping and flashing
+ case CMDGROUP_TRIONIC:
+
+ switch (cmd) {
+
+ // dump flash contents to a bin file
+ case CMD_TRIONICDUMP:
+ CHECK_ARGLENGTH(0);
+ return dump_trionic();
+
+ // write data block to flash memory
+ case CMD_TRIONICWRITE:
+ CHECK_ARGLENGTH(0);
+ return flash_trionic();
+ }
+
+ // show help for BDM commands
+ case 'H':
+ bdm_show_full_help();
+ return TERM_OK;
+ case 'h':
+ bdm_show_help();
+ return TERM_OK;
+ default:
+ bdm_show_help();
+ }
+
+ // unknown command
+ return TERM_ERR;
+}
+
+void bdm_show_help() {
+ printf("Just4Trionic BDM Command Menu\r\n");
+ printf("=============================\r\n");
+ printf("TD - and DUMP T5 FLASH BIN file\r\n");
+ printf("TF - FLASH the update file to the T5 (and write SRAM)\r\n");
+ printf("Tr - Read SRAM adaption (not done).\r\n");
+ printf("Tw - Write SRAM adaptation (not done).\r\n");
+ printf("\r\n");
+ printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
+ printf("\r\n");
+ printf("h - Show this help menu\r\n");
+ printf("\r\n");
+ return;
+}
+void bdm_show_full_help() {
+ printf("Just4Trionic BDM Command Menu\r\n");
+ printf("=============================\r\n");
+ printf("TD - and DUMP T5 FLASH BIN file\r\n");
+ printf("TF - FLASH the update file to the T5 (and write SRAM)\r\n");
+ printf("Tr - Read SRAM adaption (not done).\r\n");
+ printf("Tw - Write SRAM adaptation (not done).\r\n");
+ printf("\r\n");
+ printf("Adapter Commands - a\r\n");
+ printf("====================\r\n");
+ printf("av - display firmware version\r\n");
+ printf("as - display status of BDM pins\r\n");
+ printf("a1 - pull BKPT low\r\n");
+ printf("a2 - pull BKPT high\r\n");
+ printf("a3 - pull RESET low\r\n");
+ printf("a4 - pull RESET high\r\n");
+ printf("\r\n");
+ printf("MCU Management Commands - c\r\n");
+ printf("===========================\r\n");
+ printf("cS - stop MCU\r\n");
+ printf("cR - reset MCU\r\n");
+ printf("cr - run from given address\r\n");
+ printf(" e.g. crCAFEBABE run from address 0xcafebabe\r\n");
+ printf("cs - restart MCU\r\n");
+ printf("cb - step MCU\r\n");
+ printf("\r\n");
+ printf("MCU FLASH Commands - f\r\n");
+ printf("======================\r\n");
+ printf("fv - gets verification status (always verify)\r\n");
+ printf("fV - sets verification on/off (always on)\r\n");
+ printf("fd - DUMPs memory contents\r\n");
+ printf(" e.g. fdSSSSSSSSEEEEEEEE S...E... start and end addresses\r\n");
+ printf(" e.g. fd0000000000020000 to DUMP T5.2\r\n");
+ printf(" e.g. fd0000000000040000 to DUMP T5.5\r\n");
+ printf(" e.g. fd0000000000080000 to DUMP T7\r\n");
+ printf("fE - Erases entire FLASH memory\r\n");
+ printf(" e.g. fETTTTTTSSSSSSSSEEEEEEEE T...S...E type, start and end addresses\r\n");
+ printf(" e.g. fE28f0100000000000020000 erase 28F512 in T5.2\r\n");
+ printf(" e.g. fE28f0100000000000040000 erase 28F010 in T5.5\r\n");
+ printf(" e.g. fE29f0100000000000040000 erase 29F010 in T5.5 (addresses not used)\r\n");
+ printf(" e.g. fE29f4000000000000080000 erase 29F400 in T7 (addresses not used)\r\n");
+ printf("fw - writes to FLASH memory\r\n");
+ printf(" Write a batch of long words to flash from a start address\r\n");
+ printf(" followed by longwords LLLLLLLL, LLLLLLLL etc\r\n");
+ printf(" Send a break character to stop when doneg");
+ printf(" e.g. fwTTTTTTSSSSSSSS T...S... type and start address\r\n");
+ printf(" e.g. fw28f01000004000 start at address 0x004000 T5.2/5.5\r\n");
+ printf(" e.g. fw29f01000004000 start at address 0x004000 T5.5 with 29F010\r\n");
+ printf(" e.g. fw29f40000004000 start at address 0x004000 T7\r\n");
+ printf("\r\n");
+ printf("MCU Memory Commands - m\r\n");
+ printf("=======================\r\n");
+ printf("mbAAAAAAAA - read byte from memory at 0xaaaaaaaa\r\n");
+ printf("mwAAAAAAAA - read word (2 bytes) from memory\r\n");
+ printf("mlAAAAAAAA - read long word (4 bytes) from memory\r\n");
+ printf("mz - dump byte from the next memory address\r\n");
+ printf("mx - dump word from the next memory address\r\n");
+ printf("mc - dump long word from the next memory address\r\n");
+ printf("mBAAAAAAAADD - write byte 0xdd to memory 0xaaaaaaaa\r\n");
+ printf("mWAAAAAAAADDDD - write word 0xdddd to memory 0xaaaaaaaa\r\n");
+ printf("mLAAAAAAAADDDDDDD - write long word 0xdddddddd to memory 0xaaaaaaaa\r\n");
+ printf("mfDD - fill byte 0xdd to next memory address\r\n");
+ printf("mFDDDD - fill word 0xdddd to next memory address\r\n");
+ printf("mMDDDDDDDD - fill long word 0xdddddddd to next memory address\r\n");
+ printf("\r\n");
+ printf("MCU Register Commands - r\r\n");
+ printf("=========================\r\n");
+ printf("rrRR - read system register RR\r\n");
+ printf(" 00 - RPC, 01 - PCC, 0B - SR, 0C - USP, 0D - SSP\r\n");
+ printf(" 0e - SFC, 0f - DFC, 08 - ATEMP, 09 - FAR, 0a - VBR\r\n");
+ printf("rWRRCAFEBABE - write 0xcafebabe system register RR\r\n");
+ printf("raAD - read A/D register 0x00-07 D0-D7, 0x08-15 A0-A7\r\n");
+ printf("rAADCAFEBABE - write 0xcafebabe to A/D register \r\n");
+ printf("\r\n");
+ printf("'ESC' - Return to Just4Trionic Main Menu\r\n");
+ printf("\r\n");
+ printf("H - Show this help menu\r\n");
+ printf("\r\n");
+ return;
+}