From ad046185d39aadcc8fc280ab8713a10e4ef6d8d4 Mon Sep 17 00:00:00 2001 From: sys64738 Date: Thu, 30 Sep 2021 14:16:05 +0200 Subject: [PATCH] read/write/verify memory block fns --- src/msp430dbg.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++- src/msp430dbg.h | 13 +++--- 2 files changed, 127 insertions(+), 7 deletions(-) diff --git a/src/msp430dbg.c b/src/msp430dbg.c index 24cd713..74950ec 100644 --- a/src/msp430dbg.c +++ b/src/msp430dbg.c @@ -68,6 +68,36 @@ bool msp430_cpu_reset(void) { return jtagid == MSP430_JTAG_TAP_ID; } +void msp430_pc_set(uint16_t pc) { + if (!msp430_insn_fetch()) ;//printf("aaa no fetch\n"); + + sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); + sbw_tap_shift_dr(0x3401); + sbw_tap_shift_ir(msp430_ir_data_16bit); + sbw_tap_shift_dr(0x4030); // "load pc" + sbw_clr_tclk(); + sbw_set_tclk(); + sbw_tap_shift_dr(pc); + sbw_clr_tclk(); + sbw_set_tclk(); + sbw_tap_shift_ir(msp430_ir_addr_capture); + sbw_clr_tclk(); + sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); + sbw_tap_shift_dr(0x2401); +} + +void msp430_device_release(uint16_t addr) { + if (addr == 0xfffe) { // reset vector + sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); + sbw_tap_shift_dr(0x2c01); + sbw_tap_shift_dr(0x2401); + } else { + msp430_pc_set(addr); + } + + sbw_tap_shift_ir(msp430_ir_ctrl_sig_release); +} + uint16_t msp430_memory_read16(uint16_t addr) { msp430_cpu_halt(); @@ -135,6 +165,93 @@ void msp430_memory_write8 (uint16_t addr, uint8_t value) { msp430_cpu_release(); } +void msp430_memory_read_block(uint16_t srcaddr, uint16_t num, uint16_t* dest) { + msp430_pc_set(srcaddr - 4); + msp430_cpu_halt(); + + sbw_clr_tclk(); + sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); + sbw_tap_shift_dr(0x2409); + sbw_tap_shift_ir(msp430_ir_data_quick); + + for (size_t i = 0; i < num; ++i) { + sbw_set_tclk(); + dest[i] = sbw_tap_read_dr(); + sbw_clr_tclk(); + } + + msp430_cpu_release(); +} +void msp430_memory_write_block(uint16_t dstaddr, uint16_t num, const uint16_t* src) { + msp430_pc_set(dstaddr - 4); + msp430_cpu_halt(); + + sbw_clr_tclk(); + sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); + sbw_tap_shift_dr(0x2408); + sbw_tap_shift_ir(msp430_ir_data_quick); + + for (size_t i = 0; i < num; ++i) { + sbw_tap_shift_dr(src[i]); + sbw_set_tclk(); + sbw_clr_tclk(); + } + + msp430_cpu_release(); +} +bool msp430_memory_verify(uint16_t startaddr, uint16_t length, const uint16_t* copy) { + const uint16_t poly = 0x0805; + + msp430_cpu_reset(); + + if (false/*device has enhanced verify*/) { + msp430_pc_set(startaddr - 4); + msp430_cpu_halt(); + sbw_clr_tclk(); + sbw_tap_shift_ir(msp430_ir_data_16bit); + sbw_tap_shift_dr(startaddr - 2); + } else { + msp430_pc_set(startaddr - 2); + sbw_set_tclk(); + sbw_clr_tclk(); + } + + sbw_tap_shift_ir(msp430_ir_data_psa); + + for (size_t i = 0; i < length; ++i) { + sbw_set_tclk(); + + const uint8_t tms_seq = 0x19; // 100110 + // go through drscan/capturedr/shiftdr/updatedr without actually shifting data + sbw_tms_sequence(6, true, &tms_seq); + + sbw_clr_tclk(); + } + + sbw_tap_shift_ir(msp430_ir_shift_out_psa); + uint16_t psa_out = sbw_tap_read_dr(); + sbw_set_tclk(); + + if (false/*device has enhanced verify*/) { + msp430_cpu_release(); + } + msp430_cpu_reset(); + + uint16_t psa_crc = startaddr - 2; + for (size_t i = 0; i < length; ++i) { + if (psa_crc & 0x8000) { + psa_crc ^= poly; + psa_crc <<= 1; + psa_crc |= 1; + } else psa_crc <<= 1; + + if (copy) psa_crc ^= copy[i]; + else psa_crc ^= 0xffff; + } + + return psa_out == psa_crc; +} + uint32_t msp430_device_get(float freq) { uint8_t jtagid = 0; for (size_t i = 0; i < 7; ++i) { @@ -157,7 +274,7 @@ uint32_t msp430_device_get(float freq) { if (jtagid != MSP430_JTAG_TAP_ID) return 0<<24; if (msp430_check_fuse_blown()) return 1<<24; - // TODO: set frequency here + sbw_set_freq(false, freq); // TODO: store freq? for programming stuff (needs different baudrate for tclk) sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit); uint16_t dr = sbw_tap_shift_dr(0x2401); // JTAG mode, read @@ -184,3 +301,5 @@ uint32_t msp430_device_get(float freq) { return ((uint32_t)jtagid << 24) | devid; } + + diff --git a/src/msp430dbg.h b/src/msp430dbg.h index 3d28e8c..3231084 100644 --- a/src/msp430dbg.h +++ b/src/msp430dbg.h @@ -45,27 +45,28 @@ enum msp430_ctrl { }; bool msp430_check_fuse_blown(void); -void msp430_jtag_ctrl(void); -bool msp430_insn_fetch(void);// +bool msp430_insn_fetch(void); void msp430_pc_set(uint16_t pc); void msp430_cpu_halt(void); void msp430_cpu_release(void); bool msp430_cpu_reset(void); // POR -void msp430_device_release(void); +static inline bool msp430_device_control(void) { return msp430_check_fuse_blown(); } +void msp430_device_release(uint16_t addr); + uint16_t msp430_memory_read16(uint16_t addr); uint8_t msp430_memory_read8 (uint16_t addr); void msp430_memory_write16(uint16_t addr, uint16_t value); void msp430_memory_write8 (uint16_t addr, uint8_t value); void msp430_memory_read_block(uint16_t srcaddr, uint16_t num, uint16_t* dest); void msp430_memory_write_block(uint16_t dstaddr, uint16_t num, const uint16_t* src); +bool msp430_memory_verify(uint16_t startaddr, uint16_t length, const uint16_t* copy); #define msp430_memory_read(bits, addr) (msp430_memory_read##bits (addr)) #define msp430_memory_write(bit, a, v) (msp430_memory_write##bit (a, v)) -void msp430_flash_write(uint16_t startaddr, uint16_t num, const uint16_t* src); -void msp430_flash_erase_seg(uint16_t startaddr, bool is_infosegA); +void msp430_flash_write(uint16_t startaddr, uint16_t num, const uint16_t* src);// +void msp430_flash_erase_seg(uint16_t startaddr, bool is_infosegA);// void msp430_flash_erase_mass(bool withinfomem); // false: only main flash -bool msp430_flash_verify(uint16_t startaddr, uint16_t length, const uint16_t* copy); uint32_t msp430_device_get(float freq);