* 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 <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
struct nrf51_info {
uint32_t code_page_size;
- uint32_t code_memory_size;
struct {
bool probed;
struct nrf51_device_spec {
uint16_t hwid;
+ const char *part;
const char *variant;
const char *build_code;
unsigned int flash_size_kb;
};
+#define NRF51_DEVICE_DEF(id, pt, var, bcode, fsize) \
+{ \
+.hwid = (id), \
+.part = pt, \
+.variant = var, \
+.build_code = bcode, \
+.flash_size_kb = (fsize), \
+}
+
/* 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:
*/
static const struct nrf51_device_spec nrf51_known_devices_table[] = {
/* nRF51822 Devices (IC rev 1). */
- {
- .hwid = 0x001D,
- .variant = "QFAA",
- .build_code = "CA/C0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0026,
- .variant = "QFAB",
- .build_code = "AA",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0027,
- .variant = "QFAB",
- .build_code = "A0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0020,
- .variant = "CEAA",
- .build_code = "BA",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x002F,
- .variant = "CEAA",
- .build_code = "B0",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x001D, "51822", "QFAA", "CA/C0", 256),
+ NRF51_DEVICE_DEF(0x0026, "51822", "QFAB", "AA", 128),
+ NRF51_DEVICE_DEF(0x0027, "51822", "QFAB", "A0", 128),
+ NRF51_DEVICE_DEF(0x0020, "51822", "CEAA", "BA", 256),
+ NRF51_DEVICE_DEF(0x002F, "51822", "CEAA", "B0", 256),
/* nRF51822 Devices (IC rev 2). */
- {
- .hwid = 0x002A,
- .variant = "QFAA",
- .build_code = "FA0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0044,
- .variant = "QFAA",
- .build_code = "GC0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x003C,
- .variant = "QFAA",
- .build_code = "G0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x004C,
- .variant = "QFAB",
- .build_code = "B0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0040,
- .variant = "CEAA",
- .build_code = "CA0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0047,
- .variant = "CEAA",
- .build_code = "DA0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x004D,
- .variant = "CEAA",
- .build_code = "D00",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x002A, "51822", "QFAA", "FA0", 256),
+ NRF51_DEVICE_DEF(0x0044, "51822", "QFAA", "GC0", 256),
+ NRF51_DEVICE_DEF(0x003C, "51822", "QFAA", "G0", 256),
+ NRF51_DEVICE_DEF(0x0057, "51822", "QFAA", "G2", 256),
+ NRF51_DEVICE_DEF(0x0058, "51822", "QFAA", "G3", 256),
+ NRF51_DEVICE_DEF(0x004C, "51822", "QFAB", "B0", 128),
+ NRF51_DEVICE_DEF(0x0040, "51822", "CEAA", "CA0", 256),
+ NRF51_DEVICE_DEF(0x0047, "51822", "CEAA", "DA0", 256),
+ NRF51_DEVICE_DEF(0x004D, "51822", "CEAA", "D00", 256),
/* nRF51822 Devices (IC rev 3). */
- {
- .hwid = 0x0072,
- .variant = "QFAA",
- .build_code = "H0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x007B,
- .variant = "QFAB",
- .build_code = "C0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0083,
- .variant = "QFAC",
- .build_code = "A0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x007D,
- .variant = "CDAB",
- .build_code = "A0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0079,
- .variant = "CEAA",
- .build_code = "E0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0087,
- .variant = "CFAC",
- .build_code = "A0",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x0072, "51822", "QFAA", "H0", 256),
+ NRF51_DEVICE_DEF(0x007B, "51822", "QFAB", "C0", 128),
+ NRF51_DEVICE_DEF(0x0083, "51822", "QFAC", "A0", 256),
+ NRF51_DEVICE_DEF(0x0084, "51822", "QFAC", "A1", 256),
+ NRF51_DEVICE_DEF(0x007D, "51822", "CDAB", "A0", 128),
+ NRF51_DEVICE_DEF(0x0079, "51822", "CEAA", "E0", 256),
+ NRF51_DEVICE_DEF(0x0087, "51822", "CFAC", "A0", 256),
/* nRF51422 Devices (IC rev 1). */
- {
- .hwid = 0x001E,
- .variant = "QFAA",
- .build_code = "CA",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0024,
- .variant = "QFAA",
- .build_code = "C0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0031,
- .variant = "CEAA",
- .build_code = "A0A",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x001E, "51422", "QFAA", "CA", 256),
+ NRF51_DEVICE_DEF(0x0024, "51422", "QFAA", "C0", 256),
+ NRF51_DEVICE_DEF(0x0031, "51422", "CEAA", "A0A", 256),
/* nRF51422 Devices (IC rev 2). */
- {
- .hwid = 0x002D,
- .variant = "QFAA",
- .build_code = "DAA",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x002E,
- .variant = "QFAA",
- .build_code = "E0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0061,
- .variant = "QFAB",
- .build_code = "A00",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0050,
- .variant = "CEAA",
- .build_code = "B0",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x002D, "51422", "QFAA", "DAA", 256),
+ NRF51_DEVICE_DEF(0x002E, "51422", "QFAA", "E0", 256),
+ NRF51_DEVICE_DEF(0x0061, "51422", "QFAB", "A00", 128),
+ NRF51_DEVICE_DEF(0x0050, "51422", "CEAA", "B0", 256),
/* nRF51422 Devices (IC rev 3). */
- {
- .hwid = 0x0073,
- .variant = "QFAA",
- .build_code = "F0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x007C,
- .variant = "QFAB",
- .build_code = "B0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x0085,
- .variant = "QFAC",
- .build_code = "A0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0086,
- .variant = "QFAC",
- .build_code = "A1",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x007E,
- .variant = "CDAB",
- .build_code = "A0",
- .flash_size_kb = 128,
- },
- {
- .hwid = 0x007A,
- .variant = "CEAA",
- .build_code = "C0",
- .flash_size_kb = 256,
- },
- {
- .hwid = 0x0088,
- .variant = "CFAC",
- .build_code = "A0",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x0073, "51422", "QFAA", "F0", 256),
+ NRF51_DEVICE_DEF(0x007C, "51422", "QFAB", "B0", 128),
+ NRF51_DEVICE_DEF(0x0085, "51422", "QFAC", "A0", 256),
+ NRF51_DEVICE_DEF(0x0086, "51422", "QFAC", "A1", 256),
+ NRF51_DEVICE_DEF(0x007E, "51422", "CDAB", "A0", 128),
+ NRF51_DEVICE_DEF(0x007A, "51422", "CEAA", "C0", 256),
+ NRF51_DEVICE_DEF(0x0088, "51422", "CFAC", "A0", 256),
/* Some early nRF51-DK (PCA10028) & nRF51-Dongle (PCA10031) boards
with built-in jlink seem to use engineering samples not listed
in the nRF51 Series Compatibility Matrix V1.0. */
- {
- .hwid = 0x0071,
- .variant = "QFAC",
- .build_code = "AB",
- .flash_size_kb = 256,
- },
+ NRF51_DEVICE_DEF(0x0071, "51822", "QFAC", "AB", 256),
};
static int nrf51_bank_is_probed(struct flash_bank *bank)
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);
* 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)
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,
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) {
"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,