X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fnrf51.c;h=60f6d3c6bb21e0a58a9eec8a0a2615bf231725f6;hp=34297efbd80f5591dae4e7994169ce27ea2d8f5e;hb=b9ee6dd4655310c0553f4eef853213b11c1df28f;hpb=db8029bc266187c54a35a37a80256c343bf4bf92 diff --git a/src/flash/nor/nrf51.c b/src/flash/nor/nrf51.c index 34297efbd8..60f6d3c6bb 100644 --- a/src/flash/nor/nrf51.c +++ b/src/flash/nor/nrf51.c @@ -15,9 +15,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -110,7 +108,6 @@ enum nrf51_nvmc_config_bits { struct nrf51_info { uint32_t code_page_size; - uint32_t code_memory_size; struct { bool probed; @@ -128,6 +125,18 @@ struct nrf51_device_spec { unsigned int flash_size_kb; }; +/* The known devices table below is derived from the "nRF51 Series + * Compatibility Matrix" document, which can be found by searching for + * ATTN-51 on the Nordic Semi website: + * + * http://www.nordicsemi.com/eng/content/search?SearchText=ATTN-51 + * + * Up to date with Matrix v2.0, plus some additional HWIDs. + * + * The additional HWIDs apply where the build code in the matrix is + * shown as Gx0, Bx0, etc. In these cases the HWID in the matrix is + * for x==0, x!=0 means different (unspecified) HWIDs. + */ static const struct nrf51_device_spec nrf51_known_devices_table[] = { /* nRF51822 Devices (IC rev 1). */ { @@ -177,13 +186,25 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { { .hwid = 0x003C, .variant = "QFAA", - .build_code = "Gx0", + .build_code = "G0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0057, + .variant = "QFAA", + .build_code = "G2", + .flash_size_kb = 256, + }, + { + .hwid = 0x0058, + .variant = "QFAA", + .build_code = "G3", .flash_size_kb = 256, }, { .hwid = 0x004C, .variant = "QFAB", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 128, }, { @@ -209,37 +230,43 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { { .hwid = 0x0072, .variant = "QFAA", - .build_code = "Hx0", + .build_code = "H0", .flash_size_kb = 256, }, { .hwid = 0x007B, .variant = "QFAB", - .build_code = "Cx0", + .build_code = "C0", .flash_size_kb = 128, }, { .hwid = 0x0083, .variant = "QFAC", - .build_code = "Ax0", + .build_code = "A0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0084, + .variant = "QFAC", + .build_code = "A1", .flash_size_kb = 256, }, { .hwid = 0x007D, .variant = "CDAB", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 128, }, { .hwid = 0x0079, .variant = "CEAA", - .build_code = "Ex0", + .build_code = "E0", .flash_size_kb = 256, }, { .hwid = 0x0087, .variant = "CFAC", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 256, }, @@ -273,7 +300,7 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { { .hwid = 0x002E, .variant = "QFAA", - .build_code = "Ex0", + .build_code = "E0", .flash_size_kb = 256, }, { @@ -285,7 +312,7 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { { .hwid = 0x0050, .variant = "CEAA", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 256, }, @@ -293,37 +320,43 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { { .hwid = 0x0073, .variant = "QFAA", - .build_code = "Fx0", + .build_code = "F0", .flash_size_kb = 256, }, { .hwid = 0x007C, .variant = "QFAB", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 128, }, { .hwid = 0x0085, .variant = "QFAC", - .build_code = "Ax0", + .build_code = "A0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0086, + .variant = "QFAC", + .build_code = "A1", .flash_size_kb = 256, }, { .hwid = 0x007E, .variant = "CDAB", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 128, }, { .hwid = 0x007A, .variant = "CEAA", - .build_code = "Cx0", + .build_code = "C0", .flash_size_kb = 256, }, { .hwid = 0x0088, .variant = "CFAC", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 256, }, @@ -551,7 +584,7 @@ static int nrf51_protect(struct flash_bank *bank, int set, int first, int last) if ((ppfc & 0xFF) == 0x00) { LOG_ERROR("Code region 0 size was pre-programmed at the factory, can't change flash protection settings"); return ERROR_FAIL; - }; + } res = target_read_u32(chip->target, NRF51_UICR_CLENR0, &clenr0); @@ -607,29 +640,29 @@ static int nrf51_probe(struct flash_bank *bank) LOG_WARNING("Unknown device (HWID 0x%08" PRIx32 ")", hwid); } - if (bank->base == NRF51_FLASH_BASE) { + /* The value stored in NRF51_FICR_CODEPAGESIZE is the number of bytes in one page of FLASH. */ res = target_read_u32(chip->target, NRF51_FICR_CODEPAGESIZE, - &chip->code_page_size); + &chip->code_page_size); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code page size"); return res; } + /* Note the register name is misleading, + * NRF51_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */ res = target_read_u32(chip->target, NRF51_FICR_CODESIZE, - &chip->code_memory_size); + (uint32_t *) &bank->num_sectors); if (res != ERROR_OK) { LOG_ERROR("Couldn't read code memory size"); return res; } - if (spec && chip->code_memory_size != spec->flash_size_kb) { - LOG_ERROR("Chip's reported Flash capacity does not match expected one"); - return ERROR_FAIL; - } + bank->size = bank->num_sectors * chip->code_page_size; + + if (spec && bank->size / 1024 != spec->flash_size_kb) + LOG_WARNING("Chip's reported Flash capacity does not match expected one"); - bank->size = chip->code_memory_size * 1024; - bank->num_sectors = bank->size / chip->code_page_size; bank->sectors = calloc(bank->num_sectors, sizeof((bank->sectors)[0])); if (!bank->sectors) @@ -709,7 +742,7 @@ static int nrf51_erase_page(struct flash_bank *bank, LOG_DEBUG("Erasing page at 0x%"PRIx32, sector->offset); if (sector->is_protected) { - LOG_ERROR("Cannot erase protected sector at 0x%x", sector->offset); + LOG_ERROR("Cannot erase protected sector at 0x%" PRIx32, sector->offset); return ERROR_FAIL; } @@ -731,7 +764,7 @@ static int nrf51_erase_page(struct flash_bank *bank, LOG_ERROR("The chip was not pre-programmed with SoftDevice stack and UICR cannot be erased separately. Please issue mass erase before trying to write to this region"); return ERROR_FAIL; - }; + } res = nrf51_nvmc_generic_erase(chip, NRF51_NVMC_ERASEUICR, @@ -1112,7 +1145,7 @@ COMMAND_HANDLER(nrf51_handle_mass_erase_command) LOG_ERROR("Code region 0 size was pre-programmed at the factory, " "mass erase command won't work."); return ERROR_FAIL; - }; + } res = nrf51_erase_all(chip); if (res != ERROR_OK) { @@ -1238,7 +1271,7 @@ static int nrf51_info(struct flash_bank *bank, char *buf, int buf_size) "reset value for XTALFREQ: %"PRIx32"\n" "firmware id: 0x%04"PRIx32, ficr[0].value, - ficr[1].value, + (ficr[1].value * ficr[0].value) / 1024, (ficr[2].value == 0xFFFFFFFF) ? 0 : ficr[2].value / 1024, ((ficr[3].value & 0xFF) == 0x00) ? "present" : "not present", ficr[4].value,