/* Detects stlinky in RAM, returns handler */ struct stlinky* stlinky_detect(stlink_t* sl) { static const uint32_t sram_base = 0x20000000; struct stlinky* st = malloc(sizeof(struct stlinky)); int multiple=0; st->sl = sl; printf("sram: 0x%x bytes @ 0x%zx\n", sl->sram_base, sl->sram_size); uint32_t off; for (off = 0; off < sl->sram_size; off += 4) { if (off % 1024 == 0) sig_process(); stlink_read_mem32(sl, sram_base + off, 4); if (STLINKY_MAGIC == READ_UINT32_LE(sl->q_buf)) { if (multiple > 0) printf("WARNING: another "); printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; printf("stlinky buffer size 0x%zu \n", st->bufsize); multiple++; } } if (multiple > 0) { if (multiple > 1) { printf("Using last stlinky structure detected\n"); } return st; } return NULL; }
int main(int argc, char** argv) { if(argc != 3) { fprintf(stderr, "Usage: %s <port> /dev/sgX\n", argv[0]); return 1; } struct stlink *sl = stlink_quirk_open(argv[2], 0); if (sl == NULL) return 1; if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) stlink_enter_swd_mode(sl); uint32_t chip_id; stlink_read_mem32(sl, 0xE0042000, 4); chip_id = sl->q_buf[0] | (sl->q_buf[1] << 8) | (sl->q_buf[2] << 16) | (sl->q_buf[3] << 24); printf("Chip ID is %08x.\n", chip_id); const struct chip_params* params = NULL; for(int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == (chip_id & 0xFFF)) { params = &devices[i]; break; } } if(params == NULL) { fprintf(stderr, "Cannot recognize the connected device!\n"); return 0; } printf("Device connected: %s\n", params->description); printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n", params->sram_size, params->max_flash_size, params->flash_pagesize); FLASH_PAGE = params->flash_pagesize; uint32_t flash_size; stlink_read_mem32(sl, 0x1FFFF7E0, 4); flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); printf("Flash size is %d KiB.\n", flash_size); // memory map is in 1k blocks. current_memory_map = make_memory_map(params, flash_size * 0x400); int port = atoi(argv[1]); while(serve(sl, port) == 0); stlink_close(sl); return 0; }
size_t stlinky_rx(struct stlinky *st, char* buffer) { unsigned char tx = 0; while(tx == 0) { stlink_read_mem32(st->sl, st->off+4, 4); tx = (unsigned char) st->sl->q_buf[1]; } size_t rs = tx + (4 - (tx % 4)); /* voodoo */ stlink_read_mem32(st->sl, st->off+8, rs); memcpy(buffer, st->sl->q_buf, (size_t) tx); *st->sl->q_buf=0x0; stlink_write_mem8(st->sl, st->off+5, 1); return (size_t) tx; }
/* Detects stlinky in RAM, returns handler */ struct stlinky* stlinky_detect(stlink_t* sl) { static const uint32_t sram_base = 0x20000000; struct stlinky* st = malloc(sizeof(struct stlinky)); st->sl = sl; printf("sram: 0x%x bytes @ 0x%x\n", sl->sram_base, sl->sram_size); uint32_t off; for (off = 0; off < sl->sram_size; off += 4) { stlink_read_mem32(sl, sram_base + off, 4); if ( STLINKY_MAGIC== *(uint32_t*) sl->q_buf) { printf("stlinky detected at 0x%x\n", sram_base + off); st->off = sram_base + off; stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; printf("stlinky buffer size 0x%zu \n", st->bufsize); return st; } } return NULL; }
static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr, unsigned int len) { int i = 0; uint32_t mask; // computer mask // find a free watchpoint // configure mask = -1; i = len; while(i) { i >>= 1; mask++; } if((mask != -1) && (mask < 16)) { for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { #ifdef DEBUG printf("insert watchpoint %d addr %x wf %u mask %u len %d\n", i, addr, wf, mask, len); #endif data_watches[i].fun = wf; data_watches[i].addr = addr; data_watches[i].mask = mask; // insert comparator address sl->q_buf[0] = (addr & 0xff); sl->q_buf[1] = ((addr >> 8) & 0xff); sl->q_buf[2] = ((addr >> 16) & 0xff); sl->q_buf[3] = ((addr >> 24) & 0xff); stlink_write_mem32(sl, 0xE0001020 + i * 16, 4); // insert mask memset(sl->q_buf, 0, 4); sl->q_buf[0] = mask; stlink_write_mem32(sl, 0xE0001024 + i * 16, 4); // insert function memset(sl->q_buf, 0, 4); sl->q_buf[0] = wf; stlink_write_mem32(sl, 0xE0001028 + i * 16, 4); // just to make sure the matched bit is clear ! stlink_read_mem32(sl, 0xE0001028 + i * 16, 4); return 0; } } }
size_t stlinky_tx(struct stlinky *st, char* buffer, size_t sz) { unsigned char rx = 1; while(rx != 0) { stlink_read_mem32(st->sl, st->off+4, 4); rx = (unsigned char) st->sl->q_buf[2]; } memcpy(st->sl->q_buf, buffer, sz); size_t rs = sz + (4 - (sz % 4)); /* voodoo */ stlink_write_mem32(st->sl, st->off+8+st->bufsize, rs); *st->sl->q_buf=(unsigned char) sz; stlink_write_mem8(st->sl, st->off+6, 1); return (size_t) rx; }
static void init_data_watchpoints(stlink_t *sl) { #ifdef DEBUG printf("init watchpoints\n"); #endif // set trcena in debug command to turn on dwt unit stlink_read_mem32(sl, 0xE000EDFC, 4); sl->q_buf[3] |= 1; stlink_write_mem32(sl, 0xE000EDFC, 4); // make sure all watchpoints are cleared memset(sl->q_buf, 0, 4); for(int i = 0; i < DATA_WATCH_NUM; i++) { data_watches[i].fun = WATCHDISABLED; stlink_write_mem32(sl, 0xe0001028 + i * 16, 4); } }
static void stlink_gui_populate_devmem_view (STlinkGUI *gui) { guint off; stm32_addr_t addr; g_return_if_fail (gui != NULL); g_return_if_fail (gui->sl != NULL); addr = gui->sl->flash_base; if (gui->flash_mem.memory) { g_free (gui->flash_mem.memory); } gui->flash_mem.memory = g_malloc (gui->sl->flash_size); gui->flash_mem.size = gui->sl->flash_size; gui->flash_mem.base = gui->sl->flash_base; for (off = 0; off < gui->sl->flash_size; off += MEM_READ_SIZE) { guint n_read = MEM_READ_SIZE; if (off + MEM_READ_SIZE > gui->sl->flash_size) { n_read = gui->sl->flash_size - off; /* align if needed */ if (n_read & 3) { n_read = (n_read + 4) & ~(3); } } /* reads to sl->q_buf */ stlink_read_mem32(gui->sl, addr + off, n_read); if (gui->sl->q_len < 0) { stlink_gui_set_info_error_message (gui, "Failed to read memory"); g_free (gui->flash_mem.memory); gui->flash_mem.memory = NULL; return; } memcpy (gui->flash_mem.memory + off, gui->sl->q_buf, n_read); gui->progress.fraction = (gdouble) (off + n_read) / gui->sl->flash_size; } g_idle_add ((GSourceFunc) stlink_gui_update_devmem_view, gui); }
int stlinky_canrx(struct stlinky *st) { stlink_read_mem32(st->sl, st->off+4, 4); unsigned char tx = (unsigned char) st->sl->q_buf[1]; return (int) tx; }
int main(int ac, char** av) { struct stlinky *st; sig_init(); sl = stlink_open_usb(10, 1); if (sl != NULL) { printf("ST-Linky proof-of-concept terminal :: Created by Necromant for lulz\n"); stlink_version(sl); stlink_enter_swd_mode(sl); printf("chip id: %#x\n", sl->chip_id); printf("core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; stlink_cpu_id(sl, &cpuid); printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); stlink_reset(sl); stlink_force_debug(sl); stlink_run(sl); stlink_status(sl); /* wait for device to boot */ /* TODO: Make timeout adjustable via command line */ sleep(1); if(ac == 1){ st = stlinky_detect(sl); }else if(ac == 2){ st = malloc(sizeof(struct stlinky)); st->sl = sl; st->off = (int)strtol(av[1], NULL, 16); printf("using stlinky at 0x%x\n", st->off); stlink_read_mem32(sl, st->off + 4, 4); st->bufsize = (size_t) *(unsigned char*) sl->q_buf; printf("stlinky buffer size 0x%zu \n", st->bufsize); }else{ cleanup(0); } if (st == NULL) { printf("stlinky magic not found in sram :(\n"); cleanup(0); } char* rxbuf = malloc(st->bufsize); char* txbuf = malloc(st->bufsize); size_t tmp; nonblock(1); int fd = fileno(stdin); int saved_flags = fcntl(fd, F_GETFL); fcntl(fd, F_SETFL, saved_flags & ~O_NONBLOCK); printf("Entering interactive terminal. CTRL+C to exit\n\n\n"); while(1) { sig_process(); if (stlinky_canrx(st)) { tmp = stlinky_rx(st, rxbuf); fwrite(rxbuf,tmp,1,stdout); fflush(stdout); } if (kbhit()) { tmp = read(fd, txbuf, st->bufsize); stlinky_tx(st,txbuf,tmp); } } } return 0; }
int main ( int argc, char *argv[] ) { stlink_t* sl; unsigned int ra; unsigned int rb; unsigned int flen; int ret; if(argc<2) { printf(".bin file not specified\n"); return(1); } fp=fopen(argv[1],"rb"); if(fp==NULL) { printf("Error opening file [%s]\n",argv[1]); return(1); } memset(pdata,0xFF,sizeof(pdata)); flen=fread(pdata,1,sizeof(pdata),fp); flen+=3; flen>>=2; fclose(fp); sl = stlink_open_usb(10); if(sl==NULL) { printf("stlink_open_usb failed\n"); return(1); } printf("-- version\n"); stlink_version(sl); printf("mode before doing anything: %d\n", stlink_current_mode(sl)); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { printf("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } printf("-- enter_swd_mode\n"); stlink_enter_swd_mode(sl); printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl)); printf("-- chip id: %#x\n", sl->chip_id); printf("-- core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; stlink_cpu_id(sl, &cpuid); printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); // printf("-- status\n"); //stlink_status(sl); printf("-- reset\n"); stlink_reset(sl); stlink_force_debug(sl); // printf("-- status\n"); // stlink_status(sl); #ifdef LOAD_RAM printf("-- load\n"); for(ra=0;ra<flen;ra++) { write_uint32(sl->q_buf,pdata[ra]); stlink_write_mem32(sl, 0x20000000+(ra<<2), 4); } for(ra=0;ra<8;ra++) { stlink_read_mem32(sl, 0x20000000+(ra<<2), 4); rb=read_uint32(sl->q_buf,0); printf("[0x%08X] 0x%08X 0x%08X\n",ra,rb,pdata[ra]); } printf("-- run\n"); stlink_write_reg(sl, 0x20020000, 13); /* pc register */ stlink_write_reg(sl, 0x20000000, 15); /* pc register */ stlink_run(sl); ret =0; #endif //LOAD_RAM #ifdef LOAD_FLASH ra=0; rb=0; ret=stlink_write_flash(sl,0x08000000,(unsigned char *)pdata,0x4000); if(ret) { printf("stlink_write_flasin error\n"); } #endif //LOAD_FLASH printf("-- exit_debug_mode\n"); stlink_exit_debug_mode(sl); stlink_close(sl); return 0; }
int main(int argc, char *argv[]) { // set scpi lib debug level: 0 for no debug info, 10 for lots const int scsi_verbose = 2; char *dev_name; switch (argc) { case 1: fputs( "\nUsage: stlink-access-test /dev/sg0, sg1, ...\n" "\n*** Notice: The stlink firmware violates the USB standard.\n" "*** If you plug-in the discovery's stlink, wait a several\n" "*** minutes to let the kernel driver swallow the broken device.\n" "*** Watch:\ntail -f /var/log/messages\n" "*** This command sequence can shorten the waiting time and fix some issues.\n" "*** Unplug the stlink and execute once as root:\n" "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:lrwsro\n\n", stderr); return EXIT_FAILURE; case 2: dev_name = argv[1]; break; default: return EXIT_FAILURE; } fputs("*** stlink access test ***\n", stderr); fprintf(stderr, "Using sg_lib %s : scsi_pt %s\n", sg_lib_version(), scsi_pt_version()); stlink_t *sl = stlink_quirk_open(dev_name, scsi_verbose); if (sl == NULL) return EXIT_FAILURE; // we are in mass mode, go to swd stlink_enter_swd_mode(sl); stlink_current_mode(sl); stlink_core_id(sl); //---------------------------------------------------------------------- stlink_status(sl); //stlink_force_debug(sl); stlink_reset(sl); stlink_status(sl); #if 0 // core system control block stlink_read_mem32(sl, 0xe000ed00, 4); DD(sl, "cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231", read_uint32(sl->q_buf, 0)); // no MPU stlink_read_mem32(sl, 0xe000ed90, 4); DD(sl, "mpu type register: MPU_TYPER = got 0x%08x expect 0x0", read_uint32(sl->q_buf, 0)); stlink_read_mem32(sl, 0xe000edf0, 4); DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif #if 0 // happy new year 2011: let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" #define GPIOC 0x40011000 // port C #define GPIOC_CRH (GPIOC + 0x04) // port configuration register high #define GPIOC_ODR (GPIOC + 0x0c) // port output data register #define LED_BLUE (1<<8) // pin 8 #define LED_GREEN (1<<9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); DD(sl, "GPIOC_CRH = 0x%08x", io_conf); // set: general purpose output push-pull, output mode, max speed 10 MHz. write_uint32(sl->q_buf, 0x44444411); stlink_write_mem32(sl, GPIOC_CRH, 4); clear_buf(sl); for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); /* stlink_read_mem32(sl, 0x4001100c, 4); */ /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ delay(100); clear_buf(sl); stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo delay(100); } write_uint32(sl->q_buf, io_conf); // set old state #endif #if 0 // TODO rtfm: stlink doesn't have flash write routines // writing to the flash area confuses the fw for the next read access //stlink_read_mem32(sl, 0, 1024*6); // flash 0x08000000 128kB fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB clear_buf(sl); stlink_read_mem32(sl, 0x08000c00, 5); stlink_read_mem32(sl, 0x08000c00, 4); mark_buf(sl); stlink_write_mem32(sl, 0x08000c00, 4); stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif #if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); clear_buf(sl); stlink_write_mem8(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 1); stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif #if 0 // a not aligned mem32 access doesn't work indeed fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); clear_buf(sl); stlink_write_mem8(sl, 0x20000000, 32); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 1); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x20000001, 1); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif #if 0 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 64); stlink_read_mem32(sl, 0x20000000, 64); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif #if 0 stlink_read_all_regs(sl); stlink_step(sl); fputs("++++++++++ write r0 = 0x12345678\n", stderr); stlink_write_reg(sl, 0x12345678, 0); stlink_read_reg(sl, 0); stlink_read_all_regs(sl); #endif #if 0 stlink_run(sl); stlink_status(sl); stlink_force_debug(sl); stlink_status(sl); #endif #if 1 /* read the system bootloader */ fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif #if 0 /* read the flash memory */ fputs("\n+++++++ read flash memory\n\n", stderr); /* mark_buf(sl); */ stlink_read_mem32(sl, 0x08000000, 4); #endif #if 0 /* flash programming */ fputs("\n+++++++ program flash memory\n\n", stderr); stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif #if 0 /* check file contents */ fputs("\n+++++++ check flash memory\n\n", stderr); { const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); printf("_____ stlink_fcheck_flash() == %d\n", res); } #endif #if 0 fputs("\n+++++++ sram write and execute\n\n", stderr); stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); stlink_run_at(sl, sl->sram_base); #endif stlink_run(sl); stlink_status(sl); //---------------------------------------------------------------------- // back to mass mode, just in case ... stlink_exit_debug_mode(sl); stlink_current_mode(sl); stlink_close(sl); //fflush(stderr); fflush(stdout); return EXIT_SUCCESS; }
int main(int argc, char** argv) { stlink_t *sl = NULL; st_state_t state; memset(&state, 0, sizeof(state)); // set defaults... state.stlink_version = 2; state.logging_level = DEFAULT_LOGGING_LEVEL; state.listen_port = DEFAULT_GDB_LISTEN_PORT; parse_options(argc, argv, &state); switch (state.stlink_version) { case 2: sl = stlink_open_usb(state.logging_level); if(sl == NULL) return 1; break; case 1: sl = stlink_v1_open(state.logging_level); if(sl == NULL) return 1; break; } if (stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE) { if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { stlink_exit_dfu_mode(sl); } stlink_enter_swd_mode(sl); } uint32_t chip_id = stlink_chip_id(sl); uint32_t core_id = stlink_core_id(sl); /* Fix chip_id for F4 */ if (((chip_id & 0xFFF) == 0x411) && (core_id == CORE_M4_R0)) { printf("Fixing wrong chip_id for STM32F4 Rev A errata\n"); chip_id = 0x413; } printf("Chip ID is %08x, Core ID is %08x.\n", chip_id, core_id); const struct chip_params* params = NULL; for(int i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) { if(devices[i].chip_id == (chip_id & 0xFFF)) { params = &devices[i]; break; } } if(params == NULL) { fprintf(stderr, "Cannot recognize the connected device!\n"); return 0; } printf("Device connected: %s\n", params->description); printf("Device parameters: SRAM: 0x%x bytes, Flash: up to 0x%x bytes in pages of 0x%x bytes\n", params->sram_size, params->max_flash_size, params->flash_pagesize); FLASH_PAGE = params->flash_pagesize; uint32_t flash_size; stlink_read_mem32(sl, params->flash_size_reg, 4); flash_size = sl->q_buf[0] | (sl->q_buf[1] << 8); printf("Flash size is %d KiB.\n", flash_size); // memory map is in 1k blocks. current_memory_map = make_memory_map(params, flash_size * 0x400); while(serve(sl, state.listen_port) == 0); /* Switch back to mass storage mode before closing. */ stlink_run(sl); stlink_exit_debug_mode(sl); stlink_close(sl); return 0; }
int main(int argc, char *argv[]) { /* Avoid unused parameter warning */ (void)argv; // set scpi lib debug level: 0 for no debug info, 10 for lots switch (argc) { case 1: fputs( "\nUsage: stlink-access-test [anything at all] ...\n" "\n*** Notice: The stlink firmware violates the USB standard.\n" "*** Because we just use libusb, we can just tell the kernel's\n" "*** driver to simply ignore the device...\n" "*** Unplug the stlink and execute once as root:\n" "modprobe -r usb-storage && modprobe usb-storage quirks=483:3744:i\n\n", stderr); return EXIT_FAILURE; default: break; } stlink_t *sl = stlink_v1_open(99, 1); if (sl == NULL) return EXIT_FAILURE; // we are in mass mode, go to swd stlink_enter_swd_mode(sl); stlink_current_mode(sl); stlink_core_id(sl); //---------------------------------------------------------------------- stlink_status(sl); //stlink_force_debug(sl); stlink_reset(sl); stlink_status(sl); // core system control block stlink_read_mem32(sl, 0xe000ed00, 4); DLOG("cpu id base register: SCB_CPUID = got 0x%08x expect 0x411fc231\n", read_uint32(sl->q_buf, 0)); // no MPU stlink_read_mem32(sl, 0xe000ed90, 4); DLOG("mpu type register: MPU_TYPER = got 0x%08x expect 0x0\n", read_uint32(sl->q_buf, 0)); #if 0 stlink_read_mem32(sl, 0xe000edf0, 4); DD(sl, "DHCSR = 0x%08x", read_uint32(sl->q_buf, 0)); stlink_read_mem32(sl, 0x4001100c, 4); DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); #endif #if 0 // happy new year 2011: let blink all the leds // see "RM0041 Reference manual - STM32F100xx advanced ARM-based 32-bit MCUs" #define GPIOC 0x40011000 // port C #define GPIOC_CRH (GPIOC + 0x04) // port configuration register high #define GPIOC_ODR (GPIOC + 0x0c) // port output data register #define LED_BLUE (1<<8) // pin 8 #define LED_GREEN (1<<9) // pin 9 stlink_read_mem32(sl, GPIOC_CRH, 4); uint32_t io_conf = read_uint32(sl->q_buf, 0); DLOG("GPIOC_CRH = 0x%08x\n", io_conf); // set: general purpose output push-pull, output mode, max speed 10 MHz. write_uint32(sl->q_buf, 0x44444411); stlink_write_mem32(sl, GPIOC_CRH, 4); memset(sl->q_buf, 0, sizeof(sl->q_buf)); for (int i = 0; i < 100; i++) { write_uint32(sl->q_buf, LED_BLUE | LED_GREEN); stlink_write_mem32(sl, GPIOC_ODR, 4); /* stlink_read_mem32(sl, 0x4001100c, 4); */ /* DD(sl, "GPIOC_ODR = 0x%08x", read_uint32(sl->q_buf, 0)); */ usleep(100 * 1000); memset(sl->q_buf, 0, sizeof(sl->q_buf)); stlink_write_mem32(sl, GPIOC_ODR, 4); // PC lo usleep(100 * 1000); } write_uint32(sl->q_buf, io_conf); // set old state #endif #if 0 // TODO rtfm: stlink doesn't have flash write routines // writing to the flash area confuses the fw for the next read access //stlink_read_mem32(sl, 0, 1024*6); // flash 0x08000000 128kB fputs("++++++++++ read a flash at 0x0800 0000\n", stderr); stlink_read_mem32(sl, 0x08000000, 1024 * 6); //max 6kB clear_buf(sl); stlink_read_mem32(sl, 0x08000c00, 5); stlink_read_mem32(sl, 0x08000c00, 4); mark_buf(sl); stlink_write_mem32(sl, 0x08000c00, 4); stlink_read_mem32(sl, 0x08000c00, 256); stlink_read_mem32(sl, 0x08000c00, 256); #endif #if 0 // sram 0x20000000 8kB fputs("\n++++++++++ read/write 8bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); //stlink_write_mem8(sl, 0x20000000, 16); //stlink_write_mem8(sl, 0x20000000, 1); //stlink_write_mem8(sl, 0x20000001, 1); stlink_write_mem8(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); #endif #if 0 // a not aligned mem32 access doesn't work indeed fputs("\n++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++++++\n\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 1); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x20000001, 1); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x2000000b, 3); stlink_read_mem32(sl, 0x20000000, 16); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 17); stlink_read_mem32(sl, 0x20000000, 32); #endif #if 0 // sram 0x20000000 8kB fputs("++++++++++ read/write 32bit, sram at 0x2000 0000 ++++++++++++\n", stderr); memset(sl->q_buf, 0, sizeof(sl->q_buf)); mark_buf(sl); stlink_write_mem8(sl, 0x20000000, 64); stlink_read_mem32(sl, 0x20000000, 64); mark_buf(sl); stlink_write_mem32(sl, 0x20000000, 1024 * 8); //8kB stlink_read_mem32(sl, 0x20000000, 1024 * 6); stlink_read_mem32(sl, 0x20000000 + 1024 * 6, 1024 * 2); #endif #if 1 reg regs; stlink_read_all_regs(sl, ®s); stlink_step(sl); fputs("++++++++++ write r0 = 0x12345678\n", stderr); stlink_write_reg(sl, 0x12345678, 0); stlink_read_reg(sl, 0, ®s); stlink_read_all_regs(sl, ®s); #endif #if 0 stlink_run(sl); stlink_status(sl); stlink_force_debug(sl); stlink_status(sl); #endif #if 0 /* read the system bootloader */ fputs("\n++++++++++ reading bootloader ++++++++++++++++\n\n", stderr); stlink_fread(sl, "/tmp/barfoo", sl->sys_base, sl->sys_size); #endif #if 0 /* read the flash memory */ fputs("\n+++++++ read flash memory\n\n", stderr); /* mark_buf(sl); */ stlink_read_mem32(sl, 0x08000000, 4); #endif #if 0 /* flash programming */ fputs("\n+++++++ program flash memory\n\n", stderr); stlink_fwrite_flash(sl, "/tmp/foobar", 0x08000000); #endif #if 0 /* check file contents */ fputs("\n+++++++ check flash memory\n\n", stderr); { const int res = stlink_fcheck_flash(sl, "/tmp/foobar", 0x08000000); printf("_____ stlink_fcheck_flash() == %d\n", res); } #endif #if 0 fputs("\n+++++++ sram write and execute\n\n", stderr); stlink_fwrite_sram(sl, "/tmp/foobar", sl->sram_base); stlink_run_at(sl, sl->sram_base); #endif #if 0 stlink_run(sl); stlink_status(sl); //---------------------------------------------------------------------- // back to mass mode, just in case ... stlink_exit_debug_mode(sl); stlink_current_mode(sl); stlink_close(sl); #endif //fflush(stderr); fflush(stdout); return EXIT_SUCCESS; }
int main(int ac, char** av) { (void)ac; (void)av; stlink_t* sl; reg regs; sl = stlink_open_usb(10, 1, NULL); if (sl != NULL) { printf("-- version\n"); stlink_version(sl); printf("mode before doing anything: %d\n", stlink_current_mode(sl)); if (stlink_current_mode(sl) == STLINK_DEV_DFU_MODE) { printf("-- exit_dfu_mode\n"); stlink_exit_dfu_mode(sl); } printf("-- enter_swd_mode\n"); stlink_enter_swd_mode(sl); printf("-- mode after entering swd mode: %d\n", stlink_current_mode(sl)); printf("-- chip id: %#x\n", sl->chip_id); printf("-- core_id: %#x\n", sl->core_id); cortex_m3_cpuid_t cpuid; stlink_cpu_id(sl, &cpuid); printf("cpuid:impl_id = %0#x, variant = %#x\n", cpuid.implementer_id, cpuid.variant); printf("cpuid:part = %#x, rev = %#x\n", cpuid.part, cpuid.revision); printf("-- read_sram\n"); static const uint32_t sram_base = STM32_SRAM_BASE; uint32_t off; for (off = 0; off < 16; off += 4) stlink_read_mem32(sl, sram_base + off, 4); printf("FP_CTRL\n"); stlink_read_mem32(sl, STLINK_REG_CM3_FP_CTRL, 4); // no idea what reg this is.. */ // stlink_read_mem32(sl, 0xe000ed90, 4); // no idea what register this is... // stlink_read_mem32(sl, 0xe000edf0, 4); // offset 0xC into TIM11 register? TIMx_DIER? // stlink_read_mem32(sl, 0x4001100c, 4); */ /* Test 32 bit Write */ write_uint32(sl->q_buf,0x01234567); stlink_write_mem32(sl,0x200000a8,4); write_uint32(sl->q_buf,0x89abcdef); stlink_write_mem32(sl,0x200000ac, 4); stlink_read_mem32(sl, 0x200000a8, 4); stlink_read_mem32(sl, 0x200000ac, 4); /* Test 8 bit write */ write_uint32(sl->q_buf,0x01234567); stlink_write_mem8(sl,0x200001a8,3); write_uint32(sl->q_buf,0x89abcdef); stlink_write_mem8(sl, 0x200001ac, 3); stlink_read_mem32(sl, 0x200001a8, 4); stlink_read_mem32(sl, 0x200001ac, 4); printf("-- status\n"); stlink_status(sl); printf("-- reset\n"); stlink_reset(sl); stlink_force_debug(sl); /* Test reg write*/ stlink_write_reg(sl, 0x01234567, 3); stlink_write_reg(sl, 0x89abcdef, 4); stlink_write_reg(sl, 0x12345678, 15); for (off = 0; off < 21; off += 1) stlink_read_reg(sl, off, ®s); stlink_read_all_regs(sl, ®s); printf("-- status\n"); stlink_status(sl); printf("-- step\n"); stlink_step(sl); printf("-- run\n"); stlink_run(sl); printf("-- exit_debug_mode\n"); stlink_exit_debug_mode(sl); stlink_close(sl); } return 0; }