+static bool nrf5_info_variant_to_str(uint32_t variant, char *bf)
+{
+ h_u32_to_be((uint8_t *)bf, variant);
+ bf[4] = '\0';
+ if (isalnum(bf[0]) && isalnum(bf[1]) && isalnum(bf[2]) && isalnum(bf[3]))
+ return true;
+
+ strcpy(bf, "xxxx");
+ return false;
+}
+
+static const char *nrf5_decode_info_package(uint32_t package)
+{
+ for (size_t i = 0; i < ARRAY_SIZE(nrf5_packages_table); i++) {
+ if (nrf5_packages_table[i].package == package)
+ return nrf5_packages_table[i].code;
+ }
+ return "xx";
+}
+
+static int nrf5_info(struct flash_bank *bank, char *buf, int buf_size)
+{
+ struct nrf5_bank *nbank = bank->driver_priv;
+ struct nrf5_info *chip = nbank->chip;
+
+ if (chip->spec) {
+ snprintf(buf, buf_size,
+ "nRF%s-%s(build code: %s) %ukB Flash",
+ chip->spec->part, chip->spec->variant, chip->spec->build_code,
+ chip->flash_size_kb);
+
+ } else if (chip->ficr_info_valid) {
+ char variant[5];
+ nrf5_info_variant_to_str(chip->ficr_info.variant, variant);
+ snprintf(buf, buf_size,
+ "nRF%" PRIx32 "-%s%.2s(build code: %s) %" PRIu32
+ "kB Flash, %" PRIu32 "kB RAM",
+ chip->ficr_info.part,
+ nrf5_decode_info_package(chip->ficr_info.package),
+ variant, &variant[2],
+ chip->flash_size_kb,
+ chip->ficr_info.ram);
+
+ } else {
+ snprintf(buf, buf_size, "nRF51xxx (HWID 0x%04" PRIx16 ") %ukB Flash",
+ chip->hwid, chip->flash_size_kb);
+ }
+ return ERROR_OK;
+}
+
+static int nrf5_read_ficr_info(struct nrf5_info *chip)
+{
+ int res;
+ struct target *target = chip->target;
+
+ chip->ficr_info_valid = false;
+
+ res = target_read_u32(target, NRF5_FICR_INFO_PART, &chip->ficr_info.part);
+ if (res != ERROR_OK) {
+ LOG_DEBUG("Couldn't read FICR INFO.PART register");
+ return res;
+ }
+
+ uint32_t series = chip->ficr_info.part & 0xfffff000;
+ if (!(series == 0x51000 || series == 0x52000)) {
+ LOG_DEBUG("FICR INFO likely not implemented. Invalid PART value 0x%08"
+ PRIx32, chip->ficr_info.part);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ /* Now we know the device has FICR INFO filled by something relevant:
+ * Although it is not documented, the tested nRF51 rev 3 devices
+ * have FICR INFO.PART, RAM and FLASH of the same format as nRF52.
+ * VARIANT and PACKAGE coding is unknown for a nRF51 device.
+ * nRF52 devices have FICR INFO documented and always filled. */
+
+ res = target_read_u32(target, NRF5_FICR_INFO_VARIANT, &chip->ficr_info.variant);
+ if (res != ERROR_OK)
+ return res;
+
+ res = target_read_u32(target, NRF5_FICR_INFO_PACKAGE, &chip->ficr_info.package);
+ if (res != ERROR_OK)
+ return res;
+
+ res = target_read_u32(target, NRF5_FICR_INFO_RAM, &chip->ficr_info.ram);
+ if (res != ERROR_OK)
+ return res;
+
+ res = target_read_u32(target, NRF5_FICR_INFO_FLASH, &chip->ficr_info.flash);
+ if (res != ERROR_OK)
+ return res;
+
+ chip->ficr_info_valid = true;
+ return ERROR_OK;
+}
+