From 0bf7778759c8f23e60011e403343d977e51f58a9 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 17 Mar 2015 10:31:48 -0700 Subject: samd: Remove low level ADIv5 calls an favour of target_mem_write. --- src/samd.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/samd.c b/src/samd.c index 68f5bc4..6ab8140 100644 --- a/src/samd.c +++ b/src/samd.c @@ -508,7 +508,6 @@ static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len) static int samd_flash_write(struct target_s *target, uint32_t dest, const uint8_t *src, size_t len) { - ADIv5_AP_t *ap = adiv5_target_ap(target); /* Find the size of our 32-bit data buffer */ uint32_t offset = dest % 4; uint32_t words = (offset + len + 3) / 4; @@ -534,42 +533,26 @@ static int samd_flash_write(struct target_s *target, uint32_t dest, end_of_this_page = page + (SAMD_PAGE_SIZE - 4); if (addr > page || (page == last_page && end < end_of_this_page)) { - /* Setup write */ - adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw | - ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE); - adiv5_ap_write(ap, ADIV5_AP_TAR, addr); - adiv5_dp_write(ap->dp, ADIV5_DP_SELECT, - ((uint32_t)ap->apsel << 24)|(ADIV5_AP_DRW & 0xF0)); - /* Partial, manual page write */ - for (; addr <= MINIMUM(end, end_of_this_page); addr += 4, i++) { - adiv5_dp_write(ap->dp, ADIV5_AP_DRW, data[i]); - } + target_mem_write(target, addr, &data[i], + MINIMUM(end, end_of_this_page)); /* Unlock */ samd_unlock_current_address(target); /* Issue the write page command */ target_mem_write32(target, SAMD_NVMC_CTRLA, - SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); + SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); } else { /* Write first word to set address */ - target_mem_write32(target, addr, data[i]); addr += 4; i++; + target_mem_write32(target, addr, data[i]); + addr += 4; i++; /* Unlock */ samd_unlock_current_address(target); - /* Set up write */ - adiv5_ap_write(ap, ADIV5_AP_CSW, ap->csw | - ADIV5_AP_CSW_SIZE_WORD | ADIV5_AP_CSW_ADDRINC_SINGLE); - adiv5_ap_write(ap, ADIV5_AP_TAR, addr); - adiv5_dp_write(ap->dp, ADIV5_DP_SELECT, - ((uint32_t)ap->apsel << 24)|(ADIV5_AP_DRW & 0xF0)); - - /* Full, automatic page write */ - for (; addr < page + SAMD_PAGE_SIZE; addr += 4, i++) { - adiv5_dp_write(ap->dp, ADIV5_AP_DRW, data[i]); - } + target_mem_write(target, addr, &data[i], + MINIMUM(end, end_of_this_page)); } /* Poll for NVM Ready */ -- cgit v1.2.3 From 1366c32f89b419d8002fc79a90915bde70bf495c Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Tue, 17 Mar 2015 22:49:01 +0000 Subject: samd: Simplified samd_flash_write further by always using manual writes. Tested on all three devices as listed at the top of samd.c --- src/samd.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/samd.c b/src/samd.c index 6ab8140..a37a739 100644 --- a/src/samd.c +++ b/src/samd.c @@ -526,34 +526,26 @@ static int samd_flash_write(struct target_s *target, uint32_t dest, uint32_t first_page = dest & ~(SAMD_PAGE_SIZE - 1); /* The start address of the last page involved in the write */ uint32_t last_page = (dest + len - 1) & ~(SAMD_PAGE_SIZE - 1); - uint32_t end_of_this_page; - + uint32_t next_page; + uint32_t length; for (uint32_t page = first_page; page <= last_page; page += SAMD_PAGE_SIZE) { - end_of_this_page = page + (SAMD_PAGE_SIZE - 4); - - if (addr > page || (page == last_page && end < end_of_this_page)) { - /* Partial, manual page write */ - target_mem_write(target, addr, &data[i], - MINIMUM(end, end_of_this_page)); + next_page = page + SAMD_PAGE_SIZE; + length = MINIMUM(end + 4, next_page) - addr; - /* Unlock */ - samd_unlock_current_address(target); + /* Write within a single page. This may be part or all of the page */ + target_mem_write(target, addr, &data[i], length); + addr += length; i += (length >> 2); - /* Issue the write page command */ - target_mem_write32(target, SAMD_NVMC_CTRLA, - SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); - } else { - /* Write first word to set address */ - target_mem_write32(target, addr, data[i]); - addr += 4; i++; + /* If MANW=0 (default) we may have triggered an automatic + * write. Ignore this */ - /* Unlock */ - samd_unlock_current_address(target); + /* Unlock */ + samd_unlock_current_address(target); - target_mem_write(target, addr, &data[i], - MINIMUM(end, end_of_this_page)); - } + /* Issue the write page command */ + target_mem_write32(target, SAMD_NVMC_CTRLA, + SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); /* Poll for NVM Ready */ while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) @@ -572,7 +564,7 @@ static int samd_flash_write(struct target_s *target, uint32_t dest, */ static bool samd_cmd_erase_all(target *t) { - /* Clear the DSU status bits */ + /* Clear the DSU status bits */ target_mem_write32(t, SAMD_DSU_CTRLSTAT, (SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)); -- cgit v1.2.3 From 5c337c9aa7274f64b78849e350ef0d6c859437c5 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 17 Mar 2015 20:54:41 -0700 Subject: Whitespace. --- src/samd.c | 70 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/src/samd.c b/src/samd.c index a37a739..c257fe2 100644 --- a/src/samd.c +++ b/src/samd.c @@ -59,7 +59,7 @@ const struct command_s samd_cmd_list[] = { {"user_row", (cmd_handler)samd_cmd_read_userrow, "Prints user row from flash"}, {"serial", (cmd_handler)samd_cmd_serial, "Prints serial number"}, {"mbist", (cmd_handler)samd_cmd_mbist, "Runs the built-in memory test"}, - {"set_security_bit", (cmd_handler)samd_cmd_ssb, "Sets the Security Bit"}, + {"set_security_bit", (cmd_handler)samd_cmd_ssb, "Sets the Security Bit"}, {NULL, NULL, NULL} }; @@ -222,14 +222,14 @@ samd_reset(struct target_s *target) * or SYSRESETREQ: 0x05FA0004 (system reset) */ target_mem_write32(target, CORTEXM_AIRCR, - CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ); + CORTEXM_AIRCR_VECTKEY | CORTEXM_AIRCR_SYSRESETREQ); /* Exit extended reset */ if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) & SAMD_STATUSA_CRSTEXT) { /* Write bit to clear from extended reset */ target_mem_write32(target, SAMD_DSU_CTRLSTAT, - SAMD_STATUSA_CRSTEXT); + SAMD_STATUSA_CRSTEXT); } /* Poll for release from reset */ @@ -301,10 +301,10 @@ samd_protected_attach(struct target_s *target) * regain access to the chip. */ - /* Patch back in the normal cortexm attach for next time */ - target->attach = cortexm_attach; + /* Patch back in the normal cortexm attach for next time */ + target->attach = cortexm_attach; - /* Allow attach this time */ + /* Allow attach this time */ return true; } @@ -387,11 +387,11 @@ bool samd_probe(struct target_s *target) SAMD_DSU_CTRLSTAT); struct samd_descr samd = samd_parse_device_id(did); - /* Protected? */ - int protected = (ctrlstat & SAMD_STATUSB_PROT); + /* Protected? */ + int protected = (ctrlstat & SAMD_STATUSB_PROT); /* Part String */ - if (protected) { + if (protected) { sprintf(variant_string, "Atmel SAMD%d%c%dA%s (rev %c) (PROT=1)", samd.series, samd.pin, samd.mem, @@ -401,7 +401,7 @@ bool samd_probe(struct target_s *target) "Atmel SAMD%d%c%dA%s (rev %c)", samd.series, samd.pin, samd.mem, samd.package, samd.revision); - } + } /* Setup Target */ target->driver = variant_string; @@ -489,7 +489,7 @@ static int samd_flash_erase(struct target_s *target, uint32_t addr, size_t len) SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_ERASEROW); /* Poll for NVM Ready */ while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) - if(target_check_error(target)) + if (target_check_error(target)) return -1; /* Lock */ @@ -534,22 +534,22 @@ static int samd_flash_write(struct target_s *target, uint32_t dest, length = MINIMUM(end + 4, next_page) - addr; /* Write within a single page. This may be part or all of the page */ - target_mem_write(target, addr, &data[i], length); - addr += length; i += (length >> 2); + target_mem_write(target, addr, &data[i], length); + addr += length; i += (length >> 2); - /* If MANW=0 (default) we may have triggered an automatic - * write. Ignore this */ + /* If MANW=0 (default) we may have triggered an automatic + * write. Ignore this */ - /* Unlock */ - samd_unlock_current_address(target); + /* Unlock */ + samd_unlock_current_address(target); - /* Issue the write page command */ - target_mem_write32(target, SAMD_NVMC_CTRLA, - SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); + /* Issue the write page command */ + target_mem_write32(target, SAMD_NVMC_CTRLA, + SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEPAGE); /* Poll for NVM Ready */ while ((target_mem_read32(target, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) - if(target_check_error(target)) + if (target_check_error(target)) return -1; /* Lock */ @@ -564,9 +564,10 @@ static int samd_flash_write(struct target_s *target, uint32_t dest, */ static bool samd_cmd_erase_all(target *t) { - /* Clear the DSU status bits */ + /* Clear the DSU status bits */ target_mem_write32(t, SAMD_DSU_CTRLSTAT, - (SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)); + SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | + SAMD_STATUSA_FAIL); /* Erase all */ target_mem_write32(t, SAMD_DSU_CTRLSTAT, SAMD_CTRL_CHIP_ERASE); @@ -575,7 +576,7 @@ static bool samd_cmd_erase_all(target *t) uint32_t status; while (((status = target_mem_read32(t, SAMD_DSU_CTRLSTAT)) & (SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)) == 0) - if(target_check_error(t)) + if (target_check_error(t)) return false; /* Test the protection error bit in Status A */ @@ -617,7 +618,7 @@ static bool samd_set_flashlock(target *t, uint16_t value) /* Poll for NVM Ready */ while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) - if(target_check_error(t)) + if (target_check_error(t)) return -1; /* Modify the high byte of the user row */ @@ -631,16 +632,19 @@ static bool samd_set_flashlock(target *t, uint16_t value) target_mem_write32(t, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_WRITEAUXPAGE); - return true; + return true; } + static bool samd_cmd_lock_flash(target *t) { return samd_set_flashlock(t, 0x0000); } + static bool samd_cmd_unlock_flash(target *t) { return samd_set_flashlock(t, 0xFFFF); } + static bool samd_cmd_read_userrow(target *t) { gdb_outf("User Row: 0x%08x%08x\n", @@ -649,6 +653,7 @@ static bool samd_cmd_read_userrow(target *t) return true; } + /** * Reads the 128-bit serial number from the NVM */ @@ -664,6 +669,7 @@ static bool samd_cmd_serial(target *t) return true; } + /** * Returns the size (in bytes) of the current SAM D20's flash memory. */ @@ -678,6 +684,7 @@ static uint32_t samd_flash_size(target *t) /* Shift the maximum flash size (256KB) down as appropriate */ return (0x40000 >> (devsel % 5)); } + /** * Runs the Memory Built In Self Test (MBIST) */ @@ -697,7 +704,7 @@ static bool samd_cmd_mbist(target *t) uint32_t status; while (((status = target_mem_read32(t, SAMD_DSU_CTRLSTAT)) & (SAMD_STATUSA_DONE | SAMD_STATUSA_PERR | SAMD_STATUSA_FAIL)) == 0) - if(target_check_error(t)) + if (target_check_error(t)) return false; /* Test the protection error bit in Status A */ @@ -709,7 +716,7 @@ static bool samd_cmd_mbist(target *t) /* Test the fail bit in Status A */ if (status & SAMD_STATUSA_FAIL) { gdb_outf("MBIST Fail @ 0x%08x\n", - target_mem_read32(t, SAMD_DSU_ADDRESS)); + target_mem_read32(t, SAMD_DSU_ADDRESS)); } else { gdb_outf("MBIST Passed!\n"); } @@ -725,9 +732,9 @@ static bool samd_cmd_ssb(target *t) target_mem_write32(t, SAMD_NVMC_CTRLA, SAMD_CTRLA_CMD_KEY | SAMD_CTRLA_CMD_SSB); - /* Poll for NVM Ready */ - while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) - if(target_check_error(t)) + /* Poll for NVM Ready */ + while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0) + if (target_check_error(t)) return -1; gdb_outf("Set the security bit! " @@ -735,3 +742,4 @@ static bool samd_cmd_ssb(target *t) return true; } + -- cgit v1.2.3 From 1de685198c2dc7792bb5808989afb268203d1ded Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Tue, 17 Mar 2015 20:56:21 -0700 Subject: Flatten samd_probe. --- src/samd.c | 144 ++++++++++++++++++++++++++++++------------------------------- 1 file changed, 71 insertions(+), 73 deletions(-) diff --git a/src/samd.c b/src/samd.c index c257fe2..e12bcc9 100644 --- a/src/samd.c +++ b/src/samd.c @@ -374,82 +374,80 @@ bool samd_probe(struct target_s *target) uint32_t pid = samd_read_pid(target); /* Check the ARM Coresight Component and Perhiperal IDs */ - if (cid == SAMD_CID_VALUE && - (pid & SAMD_PID_MASK) == SAMD_PID_CONST_VALUE) { - - /* Read the Device ID */ - uint32_t did = target_mem_read32(target, SAMD_DSU_DID); - - /* If the Device ID matches */ - if ((did & SAMD_DID_MASK) == SAMD_DID_CONST_VALUE) { - - uint32_t ctrlstat = target_mem_read32(target, - SAMD_DSU_CTRLSTAT); - struct samd_descr samd = samd_parse_device_id(did); - - /* Protected? */ - int protected = (ctrlstat & SAMD_STATUSB_PROT); - - /* Part String */ - if (protected) { - sprintf(variant_string, - "Atmel SAMD%d%c%dA%s (rev %c) (PROT=1)", - samd.series, samd.pin, samd.mem, - samd.package, samd.revision); - } else { - sprintf(variant_string, - "Atmel SAMD%d%c%dA%s (rev %c)", - samd.series, samd.pin, samd.mem, - samd.package, samd.revision); - } - - /* Setup Target */ - target->driver = variant_string; - target->reset = samd_reset; - - if (samd.series == 20 && samd.revision == 'B') { - /** - * These functions check for and - * extended reset. Appears to be - * related to Errata 35.4.1 ref 12015 - */ - target->detach = samd20_revB_detach; - target->halt_resume = samd20_revB_halt_resume; - } - if (protected) { - /** - * Overload the default cortexm attach - * for when the samd is protected. - * This function allows users to - * attach on a temporary basis so they - * can rescue the device. - */ - target->attach = samd_protected_attach; - } - - target->xml_mem_map = samd_xml_memory_map; - target->flash_erase = samd_flash_erase; - target->flash_write = samd_flash_write; - target_add_commands(target, samd_cmd_list, "SAMD"); - - /* If we're not in reset here */ - if (!connect_assert_srst) { - /* We'll have to release the target from - * extended reset to make attach possible */ - if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) & - SAMD_STATUSA_CRSTEXT) { - - /* Write bit to clear from extended reset */ - target_mem_write32(target, SAMD_DSU_CTRLSTAT, - SAMD_STATUSA_CRSTEXT); - } - } - - return true; + if ((cid != SAMD_CID_VALUE) || + ((pid & SAMD_PID_MASK) != SAMD_PID_CONST_VALUE)) + return false; + + /* Read the Device ID */ + uint32_t did = target_mem_read32(target, SAMD_DSU_DID); + + /* If the Device ID matches */ + if ((did & SAMD_DID_MASK) != SAMD_DID_CONST_VALUE) + return false; + + uint32_t ctrlstat = target_mem_read32(target, + SAMD_DSU_CTRLSTAT); + struct samd_descr samd = samd_parse_device_id(did); + + /* Protected? */ + bool protected = (ctrlstat & SAMD_STATUSB_PROT); + + /* Part String */ + if (protected) { + sprintf(variant_string, + "Atmel SAMD%d%c%dA%s (rev %c) (PROT=1)", + samd.series, samd.pin, samd.mem, + samd.package, samd.revision); + } else { + sprintf(variant_string, + "Atmel SAMD%d%c%dA%s (rev %c)", + samd.series, samd.pin, samd.mem, + samd.package, samd.revision); + } + + /* Setup Target */ + target->driver = variant_string; + target->reset = samd_reset; + + if (samd.series == 20 && samd.revision == 'B') { + /** + * These functions check for and + * extended reset. Appears to be + * related to Errata 35.4.1 ref 12015 + */ + target->detach = samd20_revB_detach; + target->halt_resume = samd20_revB_halt_resume; + } + if (protected) { + /** + * Overload the default cortexm attach + * for when the samd is protected. + * This function allows users to + * attach on a temporary basis so they + * can rescue the device. + */ + target->attach = samd_protected_attach; + } + + target->xml_mem_map = samd_xml_memory_map; + target->flash_erase = samd_flash_erase; + target->flash_write = samd_flash_write; + target_add_commands(target, samd_cmd_list, "SAMD"); + + /* If we're not in reset here */ + if (!connect_assert_srst) { + /* We'll have to release the target from + * extended reset to make attach possible */ + if (target_mem_read32(target, SAMD_DSU_CTRLSTAT) & + SAMD_STATUSA_CRSTEXT) { + + /* Write bit to clear from extended reset */ + target_mem_write32(target, SAMD_DSU_CTRLSTAT, + SAMD_STATUSA_CRSTEXT); } } - return false; + return true; } /** -- cgit v1.2.3