//----------------------------------------------------------------------------- static void target_deselect(void) { dap_write_word(DHCSR, 0xa05f0000); dap_write_word(DEMCR, 0x00000000); dap_write_word(AIRCR, 0x05fa0004); target_free_options(&target_options); }
//----------------------------------------------------------------------------- static void target_select(target_options_t *options) { uint32_t chip_id, chip_exid; // Set boot mode GPNVM bit as a workaraound dap_write_word(EEFC_FCR(0), CMD_SGPB | (1 << 8)); // Stop the core dap_write_word(DHCSR, 0xa05f0003); dap_write_word(DEMCR, 0x00000001); dap_write_word(AIRCR, 0x05fa0004); chip_id = dap_read_word(CHIPID_CIDR); chip_exid = dap_read_word(CHIPID_EXID); for (device_t *device = devices; device->chip_id > 0; device++) { if (device->chip_id == chip_id && device->chip_exid == chip_exid) { uint32_t fl_id, fl_size, fl_page_size, fl_nb_palne, fl_nb_lock; verbose("Target: %s\n", device->name); for (uint32_t plane = 0; plane < device->n_planes; plane++) { dap_write_word(EEFC_FCR(plane), CMD_GETD); while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); fl_id = dap_read_word(EEFC_FRR(plane)); check(fl_id, "Cannot read flash descriptor, check Erase pin state"); fl_size = dap_read_word(EEFC_FRR(plane)); check(fl_size == device->flash_size, "Invalid reported Flash size (%d)", fl_size); fl_page_size = dap_read_word(EEFC_FRR(plane)); check(fl_page_size == device->page_size, "Invalid reported page size (%d)", fl_page_size); fl_nb_palne = dap_read_word(EEFC_FRR(plane)); for (uint32_t i = 0; i < fl_nb_palne; i++) dap_read_word(EEFC_FRR(plane)); fl_nb_lock = dap_read_word(EEFC_FRR(plane)); for (uint32_t i = 0; i < fl_nb_lock; i++) dap_read_word(EEFC_FRR(plane)); } target_device = *device; target_options = *options; target_check_options(&target_options, device->flash_size * target_device.n_planes, device->page_size * PAGES_IN_ERASE_BLOCK); return; } } error_exit("unknown target device (CHIP_ID = 0x%08x)", chip_id); }
//----------------------------------------------------------------------------- static void target_cm0p_erase(void) { verbose("Erasing... "); dap_write_word(DSU_CTRL_STATUS, 0x00001f00); // Clear flags dap_write_word(DSU_CTRL_STATUS, 0x00000010); // Chip erase usleep(100000); while (0 == (dap_read_word(0x41002100) & 0x00000100)); verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_erase(void) { for (uint32_t plane = 0; plane < target_device.n_planes; plane++) dap_write_word(EEFC_FCR(plane), CMD_EA); for (uint32_t plane = 0; plane < target_device.n_planes; plane++) while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); }
//----------------------------------------------------------------------------- static void target_cm7_select(void) { uint32_t chip_id, chip_exid; // Stop the core dap_write_word(DHCSR, 0xa05f0003); dap_write_word(DEMCR, 0x00000001); dap_write_word(AIRCR, 0x05fa0004); chip_id = dap_read_word(CHIPID_CIDR); chip_exid = dap_read_word(CHIPID_EXID); for (device = devices; device->chip_id > 0; device++) { if (device->chip_id == chip_id && device->chip_exid == chip_exid) { uint32_t fl_id, fl_size, fl_page_size, fl_nb_palne, fl_nb_lock; verbose("Target: %s\n", device->name); dap_write_word(EEFC_FCR, CMD_GETD); while (0 == (dap_read_word(EEFC_FSR) & FSR_FRDY)); fl_id = dap_read_word(EEFC_FRR); check(fl_id, "Cannot read flash descriptor, check Erase pin state"); fl_size = dap_read_word(EEFC_FRR); check(fl_size == device->flash_size, "Invalid reported Flash size (%d)", fl_size); fl_page_size = dap_read_word(EEFC_FRR); check(fl_page_size == device->page_size, "Invalid reported page size (%d)", fl_page_size); fl_nb_palne = dap_read_word(EEFC_FRR); for (uint32_t i = 0; i < fl_nb_palne; i++) dap_read_word(EEFC_FRR); fl_nb_lock = dap_read_word(EEFC_FRR); for (uint32_t i = 0; i < fl_nb_lock; i++) dap_read_word(EEFC_FRR); return; } } error_exit("unknown target device (CHIP_ID = 0x%08x)", chip_id); }
//----------------------------------------------------------------------------- static void target_cm7_program(char *name) { uint32_t addr = device->flash_start; uint32_t size, number_of_pages; uint32_t offs = 0; uint8_t *buf; buf = buf_alloc(device->flash_size); size = load_file(name, buf, device->flash_size); memset(&buf[size], 0xff, device->flash_size - size); verbose("Programming..."); number_of_pages = (size + device->page_size - 1) / device->page_size; for (uint32_t page = 0; page < number_of_pages; page += 8) { dap_write_word(EEFC_FCR, CMD_EPA | ((page | 1) << 8)); while (0 == (dap_read_word(EEFC_FSR) & FSR_FRDY)); verbose("."); } verbose(","); for (uint32_t page = 0; page < number_of_pages; page++) { for (uint32_t sector = 0; sector < device->page_size / SECTOR_SIZE; sector++) { dap_write_block(addr, &buf[offs], SECTOR_SIZE); addr += SECTOR_SIZE; offs += SECTOR_SIZE; } dap_write_word(EEFC_FCR, CMD_WP | (page << 8)); while (0 == (dap_read_word(EEFC_FSR) & FSR_FRDY)); verbose("."); } buf_free(buf); verbose(" done.\n"); }
//----------------------------------------------------------------------------- static void target_cm7_lock(void) { verbose("Locking... "); dap_write_word(EEFC_FCR, CMD_SGPB | (0 << 8)); verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_cm0p_lock(void) { verbose("Locking... "); dap_write_word(0x41004000, 0x0000a545); // Set Security Bit verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_lock(void) { verbose("Locking... "); // It is enough to lock just one plane to lock the entire device dap_write_word(EEFC_FCR(0), CMD_SGPB | (0 << 8)); verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_cm7_erase(void) { verbose("Erasing... "); dap_write_word(EEFC_FCR, CMD_EA); while (0 == (dap_read_word(EEFC_FSR) & FSR_FRDY)); verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_cm0p_program(char *name) { uint32_t addr = device->flash_start; uint32_t size; uint32_t offs = 0; uint32_t number_of_rows; uint8_t *buf; if (dap_read_word(DSU_CTRL_STATUS) & 0x00010000) error_exit("devices is locked, perform a chip erase before programming"); buf = buf_alloc(device->flash_size); size = load_file(name, buf, device->flash_size); memset(&buf[size], 0xff, device->flash_size - size); verbose("Programming..."); number_of_rows = (size + device->row_size - 1) / device->row_size; for (uint32_t row = 0; row < number_of_rows; row++) { dap_write_word(0x4100401c, addr >> 1); dap_write_word(0x41004000, 0x0000a541); // Unlock Region while (0 == (dap_read_word(0x41004014) & 1)); dap_write_word(0x41004000, 0x0000a502); // Erase Row while (0 == (dap_read_word(0x41004014) & 1)); dap_write_block(addr, &buf[offs], device->row_size); addr += device->row_size; offs += device->row_size; verbose("."); } buf_free(buf); verbose(" done.\n"); }
//----------------------------------------------------------------------------- static void target_erase(void) { verbose("Erasing... "); for (uint32_t plane = 0; plane < device->n_planes; plane++) dap_write_word(EEFC_FCR(plane), CMD_EA); for (uint32_t plane = 0; plane < device->n_planes; plane++) while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); verbose("done.\n"); }
//----------------------------------------------------------------------------- static void target_cm0p_select(void) { uint32_t dsu_did; // Stop the core dap_write_word(DHCSR, 0xa05f0003); dap_write_word(DEMCR, 0x00000001); dap_write_word(AIRCR, 0xfa050004); dsu_did = dap_read_word(DSU_DID); for (device = devices; device->dsu_did > 0; device++) { if (device->dsu_did == dsu_did) { verbose("Target: %s\n", device->name); return; } } error_exit("unknown target device (DSU_DID = 0x%08x)", dsu_did); }
//----------------------------------------------------------------------------- static void target_program(void) { uint32_t addr = target_device.flash_start + target_options.offset; uint32_t number_of_pages, plane, page_offset; uint32_t offs = 0; uint8_t *buf = target_options.file_data; uint32_t size = target_options.file_size; number_of_pages = (size + target_device.page_size - 1) / target_device.page_size; page_offset = target_options.offset / target_device.page_size; for (uint32_t page = 0; page < number_of_pages; page += PAGES_IN_ERASE_BLOCK) { plane = (page + page_offset) / (target_device.flash_size / target_device.page_size); dap_write_word(EEFC_FCR(plane), CMD_EPA | (((page + page_offset) | 1) << 8)); while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); verbose("."); } verbose(","); for (uint32_t page = 0; page < number_of_pages; page++) { dap_write_block(addr, &buf[offs], target_device.page_size); addr += target_device.page_size; offs += target_device.page_size; plane = (page + page_offset) / (target_device.flash_size / target_device.page_size); dap_write_word(EEFC_FCR(plane), CMD_WP | ((page + page_offset) << 8)); while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); verbose("."); } }
//----------------------------------------------------------------------------- static void target_program(char *name) { uint32_t addr = device->flash_start; uint32_t flash_size = device->flash_size * device->n_planes; uint32_t size, number_of_pages, plane; uint32_t offs = 0; uint8_t *buf; buf = buf_alloc(flash_size); size = load_file(name, buf, flash_size); memset(&buf[size], 0xff, flash_size - size); verbose("Programming..."); number_of_pages = (size + device->page_size - 1) / device->page_size; for (uint32_t page = 0; page < number_of_pages; page++) { dap_write_block(addr, &buf[offs], device->page_size); addr += device->page_size; offs += device->page_size; plane = page / (device->flash_size / device->page_size); dap_write_word(EEFC_FCR(plane), CMD_EWP | (page << 8)); while (0 == (dap_read_word(EEFC_FSR(plane)) & FSR_FRDY)); verbose("."); } buf_free(buf); verbose(" done.\n"); }
//----------------------------------------------------------------------------- static void target_lock(void) { // It is enough to lock just one plane to lock the entire device dap_write_word(EEFC_FCR(0), CMD_SGPB | (0 << 8)); }
//----------------------------------------------------------------------------- static void target_cm0p_deselect(void) { dap_write_word(DEMCR, 0x00000000); dap_write_word(DHCSR, 0xa05f0000); }
//----------------------------------------------------------------------------- static void target_deselect(void) { dap_write_word(ARM_DAP_DHCSR, 0xa05f0000); dap_write_word(ARM_DAP_DEMCR, 0x00000000); dap_write_word(ARM_SCB_AIRCR, 0x05fa0004); }
//----------------------------------------------------------------------------- static void target_cm7_deselect(void) { dap_write_word(DHCSR, 0xa05f0000); dap_write_word(DEMCR, 0x00000000); dap_write_word(AIRCR, 0x05fa0004); }