flashing, test program
This commit is contained in:
parent
ad046185d3
commit
d4e34bb742
|
@ -1 +1,2 @@
|
||||||
build/
|
build/
|
||||||
|
dat/
|
||||||
|
|
76
src/main.c
76
src/main.c
|
@ -9,10 +9,20 @@
|
||||||
#include "tap.h"
|
#include "tap.h"
|
||||||
#include "msp430dbg.h"
|
#include "msp430dbg.h"
|
||||||
|
|
||||||
void printbuf(const uint8_t* buf, size_t size) {
|
static uint16_t DATA_text[0x24] = {
|
||||||
for (size_t i = 0; i < size; ++i)
|
0xc232,0x43c2,0x0000,0x4031,0x02fe,0x40f2,0x00ff,0x002a,0x40b2,0x5a10,0x0120,
|
||||||
printf("%02x%c", buf[i], i % 16 == 15 ? '\n' : ' ');
|
0x43d2,0x0000,0xd232,0xd032,0x0018,0x3ffd,0xc3d2,0x0002,0xd3d2,0x0000,0xe3d2,
|
||||||
}
|
0x0029,0x4130,0x1300,0x1300,0x1300,0x1300,0x1300,0x1300,0x12b0,0xf822,0x1300,
|
||||||
|
0x1300,0x1300,0x3fdc
|
||||||
|
};
|
||||||
|
static uint16_t DATA_vectors[0x10] = {
|
||||||
|
0xf830,0xf830,0xf832,0xf834,0xf836,0xf830,0xf830,0xf830,
|
||||||
|
0xf838,0xf83a,0xf83c,0xf842,0xf830,0xf830,0xf844,0xf846
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2k/8k flash, 256b RAM
|
||||||
|
static uint16_t dumpmem_ram[256>>1];
|
||||||
|
static uint16_t dumpmem_flash[8192>>1];
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
gpio_init(PINOUT_SBW_TCK);
|
gpio_init(PINOUT_SBW_TCK);
|
||||||
|
@ -83,5 +93,63 @@ int main() {
|
||||||
uint32_t initv = msp430_device_get(200e3);
|
uint32_t initv = msp430_device_get(200e3);
|
||||||
printf("init -> %08lx\n", initv);
|
printf("init -> %08lx\n", initv);
|
||||||
|
|
||||||
|
/*msp430_memory_read_block(0x0f00, 16>>1, dumpmem_ram);
|
||||||
|
printf("info dump:\n");
|
||||||
|
for (size_t i = 0; i < ( 16>>1); i += 4) {
|
||||||
|
printf("%04zx: %04x %04x %04x %04x\n",
|
||||||
|
0x0f00+(i<<1), dumpmem_ram[i+0], dumpmem_ram[i+1],
|
||||||
|
dumpmem_ram[i+2], dumpmem_ram[i+3]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
msp430_memory_read_block(0x0200, 256>>1, dumpmem_ram);
|
||||||
|
|
||||||
|
printf("RAM dump:\n");
|
||||||
|
for (size_t i = 0; i < (256>>1); i += 4) {
|
||||||
|
printf("%04zx: %04x %04x %04x %04x\n",
|
||||||
|
0x0200+(i<<1), dumpmem_ram[i+0], dumpmem_ram[i+1],
|
||||||
|
dumpmem_ram[i+2], dumpmem_ram[i+3]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
msp430_memory_read_block(0xe000, 8192>>1, dumpmem_flash);
|
||||||
|
|
||||||
|
printf("flash dump:\n");
|
||||||
|
for (size_t i = 0; i < (8192>>1); i += 4) {
|
||||||
|
printf("%04zx: %04x %04x %04x %04x\n",
|
||||||
|
0xe000+(i<<1), dumpmem_flash[i+0], dumpmem_flash[i+1],
|
||||||
|
dumpmem_flash[i+2], dumpmem_flash[i+3]
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*printf("flashing text...\n");
|
||||||
|
for (size_t i = 0; i < 0x24; ++i) {
|
||||||
|
printf("%zu : %04x\n", DATA_text[i]);
|
||||||
|
msp430_flash_write(0xf800 + (i*2), 1, &DATA_text[i]);
|
||||||
|
}
|
||||||
|
printf("flashing vectors...\n");
|
||||||
|
for (size_t i = 0; i < 0x10; ++i) {
|
||||||
|
msp430_flash_write(0xffe0 + (i*2), 1, &DATA_vectors[i]);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*printf("dumping for check...\n");
|
||||||
|
msp430_memory_read_block(0xf800, 0x0800>>1, dumpmem_flash);
|
||||||
|
|
||||||
|
printf("flash dump:\n");
|
||||||
|
for (size_t i = 0; i < (2048>>1); i += 4) {
|
||||||
|
printf("%04zx: %04x %04x %04x %04x\n",
|
||||||
|
0xf800+(i<<1), dumpmem_flash[i+0], dumpmem_flash[i+1],
|
||||||
|
dumpmem_flash[i+2], dumpmem_flash[i+3]
|
||||||
|
);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*msp430_memory_write8(0x0024, 0x00); // P2IE =0x00 (no irq)
|
||||||
|
msp430_memory_write8(0x002e, 0x00); // P2SEL=0x00 (gpio)
|
||||||
|
msp430_memory_write8(0x0042, 0x00); // P2SEL2=0 (gpio)
|
||||||
|
msp430_memory_write8(0x002a, 0xff); // P2DIR=0xff (all out)
|
||||||
|
msp430_memory_write8(0x0029, 0x01); // P2OUT=0x01 (P2.0 hi)*/
|
||||||
|
|
||||||
|
msp430_device_release(0xfffe/*0xf800*/);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
198
src/msp430dbg.c
198
src/msp430dbg.c
|
@ -274,7 +274,8 @@ uint32_t msp430_device_get(float freq) {
|
||||||
if (jtagid != MSP430_JTAG_TAP_ID) return 0<<24;
|
if (jtagid != MSP430_JTAG_TAP_ID) return 0<<24;
|
||||||
if (msp430_check_fuse_blown()) return 1<<24;
|
if (msp430_check_fuse_blown()) return 1<<24;
|
||||||
|
|
||||||
sbw_set_freq(false, freq); // TODO: store freq? for programming stuff (needs different baudrate for tclk)
|
//sbw_set_freq(false, freq); // TODO: store freq? for programming stuff (needs different baudrate for tclk)
|
||||||
|
sbw_set_freq(true, 350e3);
|
||||||
|
|
||||||
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
uint16_t dr = sbw_tap_shift_dr(0x2401); // JTAG mode, read
|
uint16_t dr = sbw_tap_shift_dr(0x2401); // JTAG mode, read
|
||||||
|
@ -301,5 +302,200 @@ uint32_t msp430_device_get(float freq) {
|
||||||
return ((uint32_t)jtagid << 24) | devid;
|
return ((uint32_t)jtagid << 24) | devid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
void msp430_flash_write(uint16_t startaddr, uint16_t num, const uint16_t* src) {
|
||||||
|
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_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x0128); // FCTL1
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa540); // enable flash write
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012a); // FCTL2
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa540); // MCLK source, DIV=1
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012c); // FCTL3
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa540); // unlock
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
|
||||||
|
//sbw_set_freq(true, 350e3);
|
||||||
|
|
||||||
|
for (uint16_t i = 0, addr = startaddr; i < num; ++i, addr += 2) {
|
||||||
|
sbw_tap_shift_dr(0x2408);
|
||||||
|
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(addr);
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(src[i]);
|
||||||
|
|
||||||
|
sbw_set_tclk();
|
||||||
|
sbw_clr_tclk();
|
||||||
|
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2409);
|
||||||
|
|
||||||
|
sbw_tclk_burst(35*4);
|
||||||
|
printf("%04x gets %04x\n", addr, src[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2408);
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x0128); // FCTL1
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa500); // disable flash write
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012c); // FCTL3
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa550); // set lock
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
msp430_cpu_release();
|
||||||
|
}
|
||||||
|
void msp430_flash_erase_seg(uint16_t startaddr, bool is_infosegA) {
|
||||||
|
(void)is_infosegA;
|
||||||
|
|
||||||
|
msp430_cpu_halt();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2408);
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x0128); // FCTL1
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa502); // enable flash erase, single segment
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012a); // FCTL2
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa540); // MCLK source, DIV=1
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012c); // FCTL3
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa500); // unlock
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(startaddr);
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0x55aa);
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2409);
|
||||||
|
|
||||||
|
sbw_tclk_burst(4820);
|
||||||
|
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2408);
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x0128); // FCTL1
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa500); // lock flash
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_addr_16bit);
|
||||||
|
sbw_tap_shift_dr(0x012c); // FCTL3
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_to_addr);
|
||||||
|
sbw_tap_shift_dr(0xa510); // set lock
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
msp430_cpu_release();
|
||||||
|
}
|
||||||
|
void msp430_flash_erase_mass(bool withinfomem) {
|
||||||
|
uint16_t addr = withinfomem ? 0x1002 : 0xfffe;
|
||||||
|
uint16_t mode = withinfomem ? 0xa506 : 0xa504;
|
||||||
|
|
||||||
|
(void)addr; (void)mode; // nah, not yet
|
||||||
|
}
|
||||||
|
|
||||||
|
// mwhahahah
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
/*uint16_t msp430_read_jmb(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void msp430_write_jmb(uint16_t v) {
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
uint16_t msp430_cpureg_read(short regid) {
|
||||||
|
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((regid & 0xf) << 8 | 0x4082);
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_capture);
|
||||||
|
sbw_set_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_16bit);
|
||||||
|
sbw_tap_shift_dr(0x00fe);
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_capture);
|
||||||
|
sbw_set_tclk();
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_set_tclk();
|
||||||
|
uint16_t reg = sbw_tap_read_dr();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2401);
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
return reg;
|
||||||
|
}
|
||||||
|
void msp430_cpureg_write(short regid, uint16_t value) {
|
||||||
|
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((regid & 0xf) | 0x4030);
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_capture);
|
||||||
|
sbw_set_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_16bit);
|
||||||
|
sbw_tap_shift_dr(value);
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_capture);
|
||||||
|
sbw_set_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_16bit);
|
||||||
|
sbw_tap_shift_dr(0x3ffd);
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_data_capture);
|
||||||
|
sbw_set_tclk();
|
||||||
|
|
||||||
|
sbw_clr_tclk();
|
||||||
|
sbw_tap_shift_ir(msp430_ir_ctrl_sig_16bit);
|
||||||
|
sbw_tap_shift_dr(0x2401);
|
||||||
|
sbw_set_tclk();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
126
src/msp430dbg.h
126
src/msp430dbg.h
|
@ -5,43 +5,103 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// also seen: 8D 91 95 99
|
||||||
#define MSP430_JTAG_TAP_ID 0x89
|
#define MSP430_JTAG_TAP_ID 0x89
|
||||||
|
|
||||||
enum msp430_ir {
|
enum msp430_ir {
|
||||||
// lsb-first transfer
|
//!all these // EMEX == EEM
|
||||||
// DR: msb-first transfer...
|
msp430_ir_emex_data_exchange = 0x09,
|
||||||
msp430_ir_addr_16bit = 0x83,
|
msp430_ir_emex_read_trigger = 0x0a, // unused? / unknown
|
||||||
msp430_ir_addr_capture = 0x84,
|
msp430_ir_emex_read_control = 0x0b,
|
||||||
|
msp430_ir_emex_write_control = 0x0c,
|
||||||
|
msp430_ir_emex_data_exchange32 = 0x0d, // 430X/Xv2-only
|
||||||
|
|
||||||
msp430_ir_data_to_addr = 0x85,
|
// overlaps with EMEX!
|
||||||
msp430_ir_data_16bit = 0x41,
|
msp430_ir_bp_cntl_16bit = 0x09, // unused? / unknown // == data_exchange
|
||||||
msp430_ir_data_quick = 0x43,
|
msp430_ir_bp_cntl_capture = 0x0a, // unused? / unknown
|
||||||
|
msp430_ir_bp1_16bit = 0x0b, // unused? / unknown
|
||||||
|
msp430_ir_bp1_capture = 0x0c, // unused? / unknown
|
||||||
|
msp430_ir_bp2_16bit = 0x0d, // unused? / unknown
|
||||||
|
msp430_ir_bp2_capture = 0x0e, // unused? / unknown
|
||||||
|
|
||||||
|
msp430_ir_ctrl_sig_high_byte = 0x11,
|
||||||
|
msp430_ir_ctrl_sig_low_byte = 0x12,
|
||||||
msp430_ir_ctrl_sig_16bit = 0x13,
|
msp430_ir_ctrl_sig_16bit = 0x13,
|
||||||
msp430_ir_ctrl_sig_capture = 0x14, // 0010 1000 <=> 0x28
|
msp430_ir_ctrl_sig_capture = 0x14,
|
||||||
msp430_ir_ctrl_sig_release = 0x15,
|
msp430_ir_ctrl_sig_release = 0x15,
|
||||||
|
msp430_ir_coreip_id = 0x17, // pointer to more data on non-0x89 JTAG IDs?
|
||||||
|
msp430_ir_jstate_id = 0x18, // JState is Xv2 stuff so eh // NOTE: 64-bit DRshift!
|
||||||
|
|
||||||
msp430_ir_data_psa = 0x44,
|
msp430_ir_flash_16bit_update = 0x19, // "disable flash test mode"?
|
||||||
msp430_ir_shift_out_psa = 0x46,
|
msp430_ir_flash_capture = 0x1a, // unused? / unknown
|
||||||
|
msp430_ir_flash_16bit_in = 0x1b, // unused? / unknown
|
||||||
|
msp430_ir_flash_update = 0x1c, // unused? / unknown
|
||||||
|
// sesel = 0x0080, tmr = 0x0800
|
||||||
|
|
||||||
|
msp430_ir_cntrl = 0x21, // unused? / unknown
|
||||||
msp430_ir_fuse_prepare_blow = 0x22,
|
msp430_ir_fuse_prepare_blow = 0x22,
|
||||||
msp430_ir_fuse_ex_blow = 0x24,
|
msp430_ir_fuse_ex_blow = 0x24,
|
||||||
|
msp430_ir_config_fuses = 0x29, // get fuse state? uses 8-bit DRshift!
|
||||||
|
|
||||||
|
msp43_ir_test_reg = 0x2a, // Xv2-only
|
||||||
|
msp43_ir_test_v3_reg = 0x2f,
|
||||||
|
// TODO: what is LPM? something with power? related to LPMx.5
|
||||||
|
|
||||||
|
// "embedded signal processing cell" control
|
||||||
|
msp430_ir_dual_8bit = 0x31,
|
||||||
|
msp430_ir_dual_capture = 0x32,
|
||||||
|
msp430_ir_select_main = 0x33,
|
||||||
|
msp430_ir_select_esp = 0x34,
|
||||||
|
|
||||||
|
msp430_ir_tclk_toggle_inst = 0x39, // unused? / unknown
|
||||||
|
msp430_ir_tclk_0_inst = 0x3a, // unused? / unknown
|
||||||
|
msp430_ir_tclk_1_inst = 0x3b, // unused? / unknown
|
||||||
|
|
||||||
|
msp430_ir_data_16bit = 0x41,
|
||||||
|
msp430_ir_data_capture = 0x42,//! // reads from data bus?
|
||||||
|
msp430_ir_data_quick = 0x43,
|
||||||
|
msp430_ir_data_psa = 0x44,
|
||||||
|
msp430_ir_data_16bit_opt = 0x45, // unused? / unknown
|
||||||
|
msp430_ir_shift_out_psa = 0x46,
|
||||||
|
msp430_ir_dta = 0x47, // unused? / unknown
|
||||||
|
|
||||||
|
msp430_ir_accept_key = 0x59, // unused? / unknown
|
||||||
|
|
||||||
msp430_ir_jmb_exchange = 0x61,
|
msp430_ir_jmb_exchange = 0x61,
|
||||||
|
|
||||||
|
msp430_ir_tdo_event = 0x64, // unused? / unknown
|
||||||
|
msp430_ir_tdo_event_ctl = 0x65, // unused? / unknown
|
||||||
|
|
||||||
|
msp430_ir_addr_high_byte = 0x81,
|
||||||
|
msp430_ir_addr_low_byte = 0x82,
|
||||||
|
msp430_ir_addr_16bit = 0x83,
|
||||||
|
msp430_ir_addr_capture = 0x84,
|
||||||
|
msp430_ir_data_to_addr = 0x85,
|
||||||
|
msp430_ir_capture_cpu_reg = 0x86, // unused? / unknown
|
||||||
|
msp430_ir_device_id = 0x87, // "device ip pointer" for non-0x89 JTAG IDs
|
||||||
|
|
||||||
|
msp430_ir_jmb_write_32bit_mode = 0x88,//!
|
||||||
|
|
||||||
msp430_ir_bypass = 0xff
|
msp430_ir_bypass = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
enum msp430_ctrl {
|
enum msp430_ctrl {
|
||||||
msp430_ctrl_RnW = 1<< 0,
|
msp430_ctrl_RnW = 1<< 0,
|
||||||
|
msp430_ctrl_cpu_halt = 1<< 1,
|
||||||
|
msp430_ctrl_intr_req = 1<< 2,
|
||||||
msp430_ctrl_halt_jtag = 1<< 3,
|
msp430_ctrl_halt_jtag = 1<< 3,
|
||||||
|
msp430_ctrl_byte = 1<< 4,
|
||||||
|
msp430_ctrl_cpu_off = 1<< 5,
|
||||||
|
msp430_ctrl_mclk_on = 1<< 6,
|
||||||
msp430_ctrl_instr_load = 1<< 7,
|
msp430_ctrl_instr_load = 1<< 7,
|
||||||
|
msp430_ctrl_tmode = 1<< 8,
|
||||||
msp430_ctrl_tce0 = 1<< 9,
|
msp430_ctrl_tce0 = 1<< 9,
|
||||||
msp430_ctrl_tce1 = 1<<10,
|
msp430_ctrl_tce1 = 1<<10,
|
||||||
msp430_ctrl_por = 1<<11,
|
msp430_ctrl_por = 1<<11,
|
||||||
msp430_release_lbyte0 = 1<<12,
|
msp430_release_lbyte0 = 1<<12,
|
||||||
msp430_tagfuncsat = 1<<13,
|
msp430_tagfuncsat = 1<<13,
|
||||||
msp430_switch = 1<<14,
|
msp430_switch = 1<<14,
|
||||||
|
msp430_ctrl_stop_sel = 1<<15,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool msp430_check_fuse_blown(void);
|
bool msp430_check_fuse_blown(void);
|
||||||
|
@ -57,18 +117,60 @@ uint16_t msp430_memory_read16(uint16_t addr);
|
||||||
uint8_t msp430_memory_read8 (uint16_t addr);
|
uint8_t msp430_memory_read8 (uint16_t addr);
|
||||||
void msp430_memory_write16(uint16_t addr, uint16_t value);
|
void msp430_memory_write16(uint16_t addr, uint16_t value);
|
||||||
void msp430_memory_write8 (uint16_t addr, uint8_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_read_block(uint16_t srcaddr, uint16_t numwords, uint16_t* dest);
|
||||||
void msp430_memory_write_block(uint16_t dstaddr, uint16_t num, const uint16_t* src);
|
void msp430_memory_write_block(uint16_t dstaddr, uint16_t numwords, const uint16_t* src);
|
||||||
bool msp430_memory_verify(uint16_t startaddr, uint16_t length, const uint16_t* copy);
|
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_read(bits, addr) (msp430_memory_read##bits (addr))
|
||||||
#define msp430_memory_write(bit, a, v) (msp430_memory_write##bit (a, v))
|
#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_write(uint16_t startaddr, uint16_t num, const uint16_t* src);//
|
||||||
|
|
||||||
|
// TODO: erase routine needs to be redone
|
||||||
void msp430_flash_erase_seg(uint16_t startaddr, bool is_infosegA);//
|
void msp430_flash_erase_seg(uint16_t startaddr, bool is_infosegA);//
|
||||||
void msp430_flash_erase_mass(bool withinfomem); // false: only main flash
|
void msp430_flash_erase_mass(bool withinfomem); // false: only main flash
|
||||||
|
|
||||||
uint32_t msp430_device_get(float freq);
|
uint32_t msp430_device_get(float freq);
|
||||||
|
|
||||||
|
// TODO: from non-slau320aj src
|
||||||
|
uint16_t msp430_read_jmb(void);
|
||||||
|
void msp430_write_jmb(uint16_t v);
|
||||||
|
|
||||||
|
uint16_t msp430_cpureg_read(short regno);
|
||||||
|
void msp430_cpureg_write(short regno, uint16_t value);
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
// 430X and Xv2 versions of the above routines
|
||||||
|
//
|
||||||
|
// EnableLpmx5
|
||||||
|
// DisableLpmx5
|
||||||
|
// what do these do? it's something about power mode, it's disabled when
|
||||||
|
// starting JTAG, and reenabled when releasing JTAG
|
||||||
|
// only MSP430Xv2, though, so we're not going to care for now. (I don't
|
||||||
|
// have such chips, only an MSP430G2212 and a G2452)
|
||||||
|
// uses test_reg and test_reg_3V
|
||||||
|
//
|
||||||
|
// jstate_read
|
||||||
|
// what is this for? (Xv2-only -> let's not care for this either now)
|
||||||
|
// uses 64-bit DRshift!
|
||||||
|
// -> PollJStateReg, HilCommand, SingleStepJState
|
||||||
|
//
|
||||||
|
// eem_write_control
|
||||||
|
// used in save & restore context stuff / jtag start & release
|
||||||
|
// eem_read_control
|
||||||
|
// used where write_control is used, but also "wait for eem" and single-step
|
||||||
|
// eem_data_exchange
|
||||||
|
// used in a lot of places: write_control places, single-step, wait for storage, "eemdataexchange", execute funclet
|
||||||
|
//
|
||||||
|
// what is EEM? what is its sub-command stuff?
|
||||||
|
//
|
||||||
|
// wait for EEM
|
||||||
|
// JTAG release with context restore
|
||||||
|
// JTAG start with context save
|
||||||
|
// single-step
|
||||||
|
// wait for storage(?)
|
||||||
|
// execute funclet
|
||||||
|
// get dco frequency // annoying
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
trace.log
|
||||||
|
*.bin
|
||||||
|
*.h
|
||||||
|
*.elf
|
||||||
|
*.map
|
||||||
|
*.o
|
|
@ -0,0 +1,20 @@
|
||||||
|
|
||||||
|
AS := msp430-gcc
|
||||||
|
CC := msp430-gcc
|
||||||
|
LD := msp430-gcc
|
||||||
|
OBJCOPY := msp430-objcopy
|
||||||
|
|
||||||
|
all: test.bin
|
||||||
|
|
||||||
|
test.S.o: test.S
|
||||||
|
$(AS) -c -o "$@" "$<"
|
||||||
|
|
||||||
|
test.elf test.elf.map: test.S.o link.ld
|
||||||
|
$(LD) -o "$@" "$<" -T link.ld -Wl,-Map="$@.map" -nostdlib -nostartfiles
|
||||||
|
|
||||||
|
test.bin: test.elf
|
||||||
|
$(OBJCOPY) -O binary "$<" "$@"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@$(RM) -v test.bin test.bin.h test.elf test.elf.map test.S.o
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os, re, sys, struct
|
||||||
|
import textwrap
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
|
||||||
|
def sanitize_name(name):
|
||||||
|
# replace special characters with underscores
|
||||||
|
name = re.sub('[^a-zA-Z0-9_]', '_', name)
|
||||||
|
# clean up
|
||||||
|
name = name.strip('_')
|
||||||
|
|
||||||
|
# not needed: 'DATA_' prefix
|
||||||
|
#if name[0] in "0123456789": name = '_' + name
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Convert data files into byte arrays in a C header")
|
||||||
|
|
||||||
|
parser.add_argument('input', nargs='*', action='append',
|
||||||
|
help="Input data file to convert to a header file. If "
|
||||||
|
+"none are specified, data is read from standard input.")
|
||||||
|
parser.add_argument('--output', type=str, default=None,
|
||||||
|
help="Output header file path, standard output if none specified")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
#print(repr(args), file=sys.stderr)
|
||||||
|
|
||||||
|
inputfiles = args.input[0]
|
||||||
|
datafiles = {}
|
||||||
|
|
||||||
|
if len(inputfiles) == 0:
|
||||||
|
# need to read from stdio
|
||||||
|
datafiles['data'] = sys.stdin.buffer.read()
|
||||||
|
else:
|
||||||
|
for path in inputfiles:
|
||||||
|
# cannot use os.access, POSIX-only
|
||||||
|
if not os.path.exists(path) or os.path.isdir(path):
|
||||||
|
print("ERROR: input path '%s' does not exist, or is not a file" % path)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# get base name of the path (no folder names, no extension)
|
||||||
|
name = os.path.splitext(os.path.split(path)[1])[0]
|
||||||
|
# make it usable for C code names
|
||||||
|
name = sanitize_name(name)
|
||||||
|
|
||||||
|
# now read the data
|
||||||
|
data = None
|
||||||
|
try:
|
||||||
|
with open(path, 'rb') as f:
|
||||||
|
data = f.read()
|
||||||
|
except IOError:
|
||||||
|
print("ERROR: input file '%s' not readable" % path)
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
data = struct.unpack('<'+('H'*(len(data)//2)), data)
|
||||||
|
|
||||||
|
# add it to the list
|
||||||
|
datafiles[name] = data
|
||||||
|
|
||||||
|
#print(repr(datafiles), file=sys.stderr)
|
||||||
|
|
||||||
|
outname = "hardcoded_data"
|
||||||
|
if args.output is not None:
|
||||||
|
outname = os.path.splitext(os.path.split(args.output)[1])[0]
|
||||||
|
outname = sanitize_name(outname)
|
||||||
|
|
||||||
|
# generate the C source code: one uint8_t array for each data file
|
||||||
|
# variable name is "DATA_<datafile>"
|
||||||
|
# (width=84 is the equivalent of 16 bytes/line)
|
||||||
|
headersrc = '\n\n'.join(
|
||||||
|
"static uint16_t DATA_%s[%d] = {\n%s\n};" % (name, len(data), \
|
||||||
|
textwrap.fill(','.join("0x%04x" % b for b in data), width=81,
|
||||||
|
initial_indent=" ", subsequent_indent=" ")
|
||||||
|
) for name, data in datafiles.items()
|
||||||
|
)
|
||||||
|
|
||||||
|
# a C header needs include guards
|
||||||
|
headersrc = """
|
||||||
|
#ifndef AUTOGEN_{0}_H_
|
||||||
|
#define AUTOGEN_{0}_H_
|
||||||
|
|
||||||
|
{1}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
""".format(outname.upper(), headersrc)
|
||||||
|
|
||||||
|
#print(headersrc, file=sys.stderr)
|
||||||
|
|
||||||
|
if args.output is None:
|
||||||
|
# no output specified -> output to stdout
|
||||||
|
sys.stdout.write(headersrc)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
with open(args.output, 'w') as f:
|
||||||
|
f.write(headersrc)
|
||||||
|
except IOError:
|
||||||
|
print("ERROR: output file '%s' not writable" % args.output)
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
OUTPUT_FORMAT("elf32-msp430","elf32-msp430","elf32-msp430")
|
||||||
|
OUTPUT_ARCH(msp:14)
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
data (rwx) : ORIGIN = 0x0200, LENGTH = 0x100
|
||||||
|
text (rx) : ORIGIN = 0xf800, LENGTH = 0x800 - 0x20
|
||||||
|
vectors (rw) : ORIGIN = 0xffe0, LENGTH = 0x20
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* Internal text space. */
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(SORT_NONE(.init))
|
||||||
|
*(SORT_NONE(.init0)) /* Start here after reset. */
|
||||||
|
*(SORT_NONE(.init1))
|
||||||
|
*(SORT_NONE(.init2)) /* Copy data loop */
|
||||||
|
*(SORT_NONE(.init3))
|
||||||
|
*(SORT_NONE(.init4)) /* Clear bss */
|
||||||
|
*(SORT_NONE(.init5))
|
||||||
|
*(SORT_NONE(.init6)) /* C++ constructors. */
|
||||||
|
*(SORT_NONE(.init7))
|
||||||
|
*(SORT_NONE(.init8))
|
||||||
|
*(SORT_NONE(.init9)) /* Call main(). */
|
||||||
|
__ctors_start = . ;
|
||||||
|
*(.ctors)
|
||||||
|
__ctors_end = . ;
|
||||||
|
__dtors_start = . ;
|
||||||
|
*(.dtors)
|
||||||
|
__dtors_end = . ;
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.lower.text.* .lower.text)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.text)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.text.*)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.text:*)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(SORT_NONE(.fini9))
|
||||||
|
*(SORT_NONE(.fini8))
|
||||||
|
*(SORT_NONE(.fini7))
|
||||||
|
*(SORT_NONE(.fini6)) /* C++ destructors. */
|
||||||
|
*(SORT_NONE(.fini5))
|
||||||
|
*(SORT_NONE(.fini4))
|
||||||
|
*(SORT_NONE(.fini3))
|
||||||
|
*(SORT_NONE(.fini2))
|
||||||
|
*(SORT_NONE(.fini1))
|
||||||
|
*(SORT_NONE(.fini0)) /* Infinite loop after program termination. */
|
||||||
|
*(SORT_NONE(.fini))
|
||||||
|
_etext = .;
|
||||||
|
} > text =0xff
|
||||||
|
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.lower.rodata.* .lower.rodata)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.plt)
|
||||||
|
*(.rodata .rodata.* .gnu.linkonce.r.* .const .const:*)
|
||||||
|
*(.rodata1)
|
||||||
|
*(.eh_frame_hdr)
|
||||||
|
KEEP (*(.eh_frame))
|
||||||
|
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
|
||||||
|
PROVIDE (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array))
|
||||||
|
PROVIDE (__preinit_array_end = .);
|
||||||
|
PROVIDE (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array))
|
||||||
|
PROVIDE (__init_array_end = .);
|
||||||
|
PROVIDE (__fini_array_start = .);
|
||||||
|
KEEP (*(.fini_array))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
PROVIDE (__fini_array_end = .);
|
||||||
|
LONG(0); /* Sentinel. */
|
||||||
|
/* gcc uses crtbegin.o to find the start of the constructors, so
|
||||||
|
we make sure it is first. Because this is a wildcard, it
|
||||||
|
doesn't matter if the user does not actually link against
|
||||||
|
crtbegin.o; the linker won't look for a file to match a
|
||||||
|
wildcard. The wildcard also means that it doesn't matter which
|
||||||
|
directory crtbegin.o is in. */
|
||||||
|
KEEP (*crtbegin*.o(.ctors))
|
||||||
|
/* We don't want to include the .ctor section from from the
|
||||||
|
crtend.o file until after the sorted ctors. The .ctor section
|
||||||
|
from the crtend file contains the end of ctors marker and it
|
||||||
|
must be last */
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
KEEP (*crtbegin*.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
} > text =0xff
|
||||||
|
|
||||||
|
.vectors :
|
||||||
|
{
|
||||||
|
PROVIDE (__vectors_start = .) ;
|
||||||
|
*(.vectors*)
|
||||||
|
_vectors_end = . ;
|
||||||
|
} > vectors =0xff
|
||||||
|
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
PROVIDE (__data_start = .) ;
|
||||||
|
PROVIDE (__datastart = .) ;
|
||||||
|
. = ALIGN(2);
|
||||||
|
KEEP (*(.jcr))
|
||||||
|
*(.data.rel.ro.local) *(.data.rel.ro*)
|
||||||
|
*(.dynamic)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.lower.data.* .lower.data)
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d*)
|
||||||
|
KEEP (*(.gnu.linkonce.d.*personality*))
|
||||||
|
*(.data1)
|
||||||
|
*(.got.plt) *(.got)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.sdata .sdata.* .gnu.linkonce.s.*)
|
||||||
|
. = ALIGN(2);
|
||||||
|
_edata = . ;
|
||||||
|
} > data AT> text
|
||||||
|
.bss SIZEOF(.data) + ADDR(.data) :
|
||||||
|
{
|
||||||
|
. = ALIGN(2);
|
||||||
|
PROVIDE (__bss_start = .) ;
|
||||||
|
*(.lower.bss.* .lower.bss)
|
||||||
|
. = ALIGN(2);
|
||||||
|
*(.bss)
|
||||||
|
*(COMMON)
|
||||||
|
PROVIDE (__bss_end = .) ;
|
||||||
|
_end = . ;
|
||||||
|
} > data
|
||||||
|
.noinit SIZEOF(.bss) + ADDR(.bss) :
|
||||||
|
{
|
||||||
|
PROVIDE (__noinit_start = .) ;
|
||||||
|
*(.noinit)
|
||||||
|
*(COMMON)
|
||||||
|
PROVIDE (__noinit_end = .) ;
|
||||||
|
_end = . ;
|
||||||
|
} > data
|
||||||
|
|
||||||
|
|
||||||
|
.fill :
|
||||||
|
{
|
||||||
|
FILL(0xffffffff);
|
||||||
|
. = ORIGIN(vectors);
|
||||||
|
} > text
|
||||||
|
|
||||||
|
.MP430.attributes 0 :
|
||||||
|
{
|
||||||
|
KEEP (*(.MSP430.attributes))
|
||||||
|
KEEP (*(.gnu.attributes))
|
||||||
|
KEEP (*(__TI_build_attributes))
|
||||||
|
}
|
||||||
|
PROVIDE (__stack = 0x2fe) ;
|
||||||
|
PROVIDE (__data_start_rom = _etext) ;
|
||||||
|
PROVIDE (__data_end_rom = _etext + SIZEOF (.data)) ;
|
||||||
|
PROVIDE (__noinit_start_rom = _etext + SIZEOF (.data)) ;
|
||||||
|
PROVIDE (__noinit_end_rom = _etext + SIZEOF (.data) + SIZEOF (.noinit)) ;
|
||||||
|
PROVIDE (__subdevice_has_heap = 0) ;
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
; vim: set ft=gas:
|
||||||
|
|
||||||
|
#define CPUOFF (1<<4)
|
||||||
|
#define GIE (1<<3)
|
||||||
|
|
||||||
|
#define IE1 0x0000
|
||||||
|
#define IFG1 0x0002
|
||||||
|
|
||||||
|
#define WDTCTL 0x0120
|
||||||
|
|
||||||
|
#define USICTL0 0x0078
|
||||||
|
#define USICTL1 0x0079
|
||||||
|
#define USICKCTL 0x007a
|
||||||
|
#define USICNT 0x007b
|
||||||
|
#define USISR 0x007c
|
||||||
|
|
||||||
|
#define BCSCTL3 0x0053
|
||||||
|
#define BCSCTL2 0x0058
|
||||||
|
#define BCSCTL1 0x0057
|
||||||
|
#define DCOCTL 0x0056
|
||||||
|
|
||||||
|
#define P2SEL2 0x0042
|
||||||
|
#define P2REN 0x002f
|
||||||
|
#define P2SEL 0x002e
|
||||||
|
#define P2IE 0x002d
|
||||||
|
#define P2IES 0x002c
|
||||||
|
#define P2IFG 0x002b
|
||||||
|
#define P2DIR 0x002a
|
||||||
|
#define P2OUT 0x0029
|
||||||
|
#define P2IN 0x0028
|
||||||
|
|
||||||
|
#define P1SEL2 0x0041
|
||||||
|
#define P1REN 0x0027
|
||||||
|
#define P1SEL 0x0026
|
||||||
|
#define P1IE 0x0024
|
||||||
|
#define P1IES 0x0024
|
||||||
|
#define P1IFG 0x0023
|
||||||
|
#define P1DIR 0x0022
|
||||||
|
#define P1OUT 0x0021
|
||||||
|
#define P1IN 0x0020
|
||||||
|
|
||||||
|
.section ".text.startup._start", "ax", %progbits
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
dint
|
||||||
|
|
||||||
|
mov.b #0, &IE1
|
||||||
|
|
||||||
|
mov.w #__stack, sp
|
||||||
|
|
||||||
|
mov.b #0, &P2IE
|
||||||
|
mov.b #0, &P2SEL
|
||||||
|
mov.b #0, &P2SEL2
|
||||||
|
mov.b #0xff, &P2DIR
|
||||||
|
|
||||||
|
; TODO: configure wdt
|
||||||
|
mov.w #((0x5a<<8)|(1<<4)), &WDTCTL
|
||||||
|
|
||||||
|
mov.b #1, &IE1
|
||||||
|
|
||||||
|
eint
|
||||||
|
|
||||||
|
lockup:
|
||||||
|
|
||||||
|
; enter LPM0 for power save stuff
|
||||||
|
bis #(GIE|CPUOFF), sr
|
||||||
|
|
||||||
|
jmp lockup
|
||||||
|
|
||||||
|
|
||||||
|
.section ".text.callback", "ax", %progbits
|
||||||
|
|
||||||
|
wdt_callback:
|
||||||
|
bic.b #1, &IFG1
|
||||||
|
bis.b #1, &IE1
|
||||||
|
|
||||||
|
xor.b #1, &P2OUT
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.section ".vectors", "ax", %progbits
|
||||||
|
|
||||||
|
_VECTORS:
|
||||||
|
|
||||||
|
.2byte ISR_unk ; ffe0
|
||||||
|
.2byte ISR_unk ; ffe2
|
||||||
|
.2byte ISR_port1 ; ffe4
|
||||||
|
.2byte ISR_port2 ; ffe6
|
||||||
|
.2byte ISR_USI ; ffe8
|
||||||
|
.2byte ISR_unk ; ffea ; (ADC10, not on this chip)
|
||||||
|
.2byte ISR_unk ; ffec
|
||||||
|
.2byte ISR_unk ; ffee
|
||||||
|
.2byte ISR_timer0 ; fff0
|
||||||
|
.2byte ISR_timer1 ; fff2
|
||||||
|
.2byte ISR_wdt ; fff4
|
||||||
|
.2byte ISR_cmpA ; fff6
|
||||||
|
.2byte ISR_unk ; fff8
|
||||||
|
.2byte ISR_unk ; fffa
|
||||||
|
.2byte ISR_NMI ; fffc
|
||||||
|
.2byte ISR_RST ; fffe
|
||||||
|
|
||||||
|
.section ".text.isr.unk", "ax", %progbits
|
||||||
|
ISR_unk:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.port1", "ax", %progbits
|
||||||
|
ISR_port1:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.port2", "ax", %progbits
|
||||||
|
ISR_port2:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.usi", "ax", %progbits
|
||||||
|
ISR_USI:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.timer0", "ax", %progbits
|
||||||
|
ISR_timer0:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.timer1", "ax", %progbits
|
||||||
|
ISR_timer1:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.wdt", "ax", %progbits
|
||||||
|
ISR_wdt:
|
||||||
|
call #wdt_callback
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.cmpA", "ax", %progbits
|
||||||
|
ISR_cmpA:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.nmi", "ax", %progbits
|
||||||
|
ISR_NMI:
|
||||||
|
reti
|
||||||
|
|
||||||
|
.section ".text.isr.rst", "ax", %progbits
|
||||||
|
ISR_RST:
|
||||||
|
jmp _start
|
||||||
|
|
Loading…
Reference in New Issue