X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fnrf51.c;h=7b7acf479205f47e6c4b6e09e2fa06428db7dd69;hp=351a86e49cc0543b1c72ecd905c343132bffea56;hb=7829f31a6dd61297e97d8e94fe98a1658eac833e;hpb=5387d616a3d1b4550f9acecda26ead380d37dedf diff --git a/src/flash/nor/nrf51.c b/src/flash/nor/nrf51.c index 351a86e49c..7b7acf4792 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; @@ -123,39 +120,57 @@ struct nrf51_info { struct nrf51_device_spec { uint16_t hwid; + const char *part; const char *variant; const char *build_code; 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). */ { .hwid = 0x001D, + .part = "51822", .variant = "QFAA", .build_code = "CA/C0", .flash_size_kb = 256, }, { .hwid = 0x0026, + .part = "51822", .variant = "QFAB", .build_code = "AA", .flash_size_kb = 128, }, { .hwid = 0x0027, + .part = "51822", .variant = "QFAB", .build_code = "A0", .flash_size_kb = 128, }, { .hwid = 0x0020, + .part = "51822", .variant = "CEAA", .build_code = "BA", .flash_size_kb = 256, }, { .hwid = 0x002F, + .part = "51822", .variant = "CEAA", .build_code = "B0", .flash_size_kb = 256, @@ -164,42 +179,63 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { /* nRF51822 Devices (IC rev 2). */ { .hwid = 0x002A, + .part = "51822", .variant = "QFAA", .build_code = "FA0", .flash_size_kb = 256, }, { .hwid = 0x0044, + .part = "51822", .variant = "QFAA", .build_code = "GC0", .flash_size_kb = 256, }, { .hwid = 0x003C, + .part = "51822", .variant = "QFAA", - .build_code = "Gx0", + .build_code = "G0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0057, + .part = "51822", + .variant = "QFAA", + .build_code = "G2", + .flash_size_kb = 256, + }, + { + .hwid = 0x0058, + .part = "51822", + .variant = "QFAA", + .build_code = "G3", .flash_size_kb = 256, }, { .hwid = 0x004C, + .part = "51822", .variant = "QFAB", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 128, }, { .hwid = 0x0040, + .part = "51822", .variant = "CEAA", .build_code = "CA0", .flash_size_kb = 256, }, { .hwid = 0x0047, + .part = "51822", .variant = "CEAA", .build_code = "DA0", .flash_size_kb = 256, }, { .hwid = 0x004D, + .part = "51822", .variant = "CEAA", .build_code = "D00", .flash_size_kb = 256, @@ -208,56 +244,79 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { /* nRF51822 Devices (IC rev 3). */ { .hwid = 0x0072, + .part = "51822", .variant = "QFAA", - .build_code = "Hx0", + .build_code = "H0", .flash_size_kb = 256, }, { .hwid = 0x007B, + .part = "51822", .variant = "QFAB", - .build_code = "Cx0", + .build_code = "C0", .flash_size_kb = 128, }, { .hwid = 0x0083, + .part = "51822", .variant = "QFAC", - .build_code = "Ax0", + .build_code = "A0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0084, + .part = "51822", + .variant = "QFAC", + .build_code = "A1", .flash_size_kb = 256, }, { .hwid = 0x007D, + .part = "51822", .variant = "CDAB", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 128, }, { .hwid = 0x0079, + .part = "51822", .variant = "CEAA", - .build_code = "Ex0", + .build_code = "E0", .flash_size_kb = 256, }, { .hwid = 0x0087, + .part = "51822", .variant = "CFAC", - .build_code = "Ax0", + .build_code = "A0", + .flash_size_kb = 256, + }, + { + .hwid = 0x008F, + .part = "51822", + .variant = "QFAA", + .build_code = "H1", .flash_size_kb = 256, }, /* nRF51422 Devices (IC rev 1). */ { .hwid = 0x001E, + .part = "51422", .variant = "QFAA", .build_code = "CA", .flash_size_kb = 256, }, { .hwid = 0x0024, + .part = "51422", .variant = "QFAA", .build_code = "C0", .flash_size_kb = 256, }, { .hwid = 0x0031, + .part = "51422", .variant = "CEAA", .build_code = "A0A", .flash_size_kb = 256, @@ -266,64 +325,81 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { /* nRF51422 Devices (IC rev 2). */ { .hwid = 0x002D, + .part = "51422", .variant = "QFAA", .build_code = "DAA", .flash_size_kb = 256, }, { .hwid = 0x002E, + .part = "51422", .variant = "QFAA", - .build_code = "Ex0", + .build_code = "E0", .flash_size_kb = 256, }, { .hwid = 0x0061, + .part = "51422", .variant = "QFAB", .build_code = "A00", .flash_size_kb = 128, }, { .hwid = 0x0050, + .part = "51422", .variant = "CEAA", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 256, }, /* nRF51422 Devices (IC rev 3). */ { .hwid = 0x0073, + .part = "51422", .variant = "QFAA", - .build_code = "Fx0", + .build_code = "F0", .flash_size_kb = 256, }, { .hwid = 0x007C, + .part = "51422", .variant = "QFAB", - .build_code = "Bx0", + .build_code = "B0", .flash_size_kb = 128, }, { .hwid = 0x0085, + .part = "51422", + .variant = "QFAC", + .build_code = "A0", + .flash_size_kb = 256, + }, + { + .hwid = 0x0086, + .part = "51422", .variant = "QFAC", - .build_code = "Ax0", + .build_code = "A1", .flash_size_kb = 256, }, { .hwid = 0x007E, + .part = "51422", .variant = "CDAB", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 128, }, { .hwid = 0x007A, + .part = "51422", .variant = "CEAA", - .build_code = "Cx0", + .build_code = "C0", .flash_size_kb = 256, }, { .hwid = 0x0088, + .part = "51422", .variant = "CFAC", - .build_code = "Ax0", + .build_code = "A0", .flash_size_kb = 256, }, @@ -332,6 +408,7 @@ static const struct nrf51_device_spec nrf51_known_devices_table[] = { in the nRF51 Series Compatibility Matrix V1.0. */ { .hwid = 0x0071, + .part = "51822", .variant = "QFAC", .build_code = "AB", .flash_size_kb = 256, @@ -551,7 +628,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); @@ -593,43 +670,46 @@ static int nrf51_probe(struct flash_bank *bank) * bytes of the CONFIGID register */ const struct nrf51_device_spec *spec = NULL; - for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++) + for (size_t i = 0; i < ARRAY_SIZE(nrf51_known_devices_table); i++) { if (hwid == nrf51_known_devices_table[i].hwid) { spec = &nrf51_known_devices_table[i]; break; } + } if (!chip->bank[0].probed && !chip->bank[1].probed) { if (spec) - LOG_INFO("nRF51822-%s(build code: %s) %ukB Flash", - spec->variant, spec->build_code, spec->flash_size_kb); + LOG_INFO("nRF%s-%s(build code: %s) %ukB Flash", + spec->part, spec->variant, spec->build_code, + spec->flash_size_kb); else 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; } - res = target_read_u32(chip->target, NRF51_FICR_CODESIZE, - &chip->code_memory_size); + /* Note the register name is misleading, + * NRF51_FICR_CODESIZE is the number of pages in flash memory, not the number of bytes! */ + uint32_t num_sectors; + res = target_read_u32(chip->target, NRF51_FICR_CODESIZE, &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->num_sectors = num_sectors; + bank->size = 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) @@ -731,7 +811,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 +1192,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 +1318,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,