Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ SRC = \
msp432e4.c \
msp432p4.c \
nrf51.c \
nrf91.c \
nxpke04.c \
remote.c \
rp.c \
Expand Down
1 change: 1 addition & 0 deletions src/target/cortexm.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ bool cortexm_probe(adiv5_access_port_s *ap)
break;
case JEP106_MANUFACTURER_NORDIC:
PROBE(nrf51_probe);
PROBE(nrf91_probe);
break;
case JEP106_MANUFACTURER_ATMEL:
PROBE(samx7x_probe);
Expand Down
105 changes: 105 additions & 0 deletions src/target/nrf91.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include "general.h"
#include "target.h"
#include "target_internal.h"
#include "cortexm.h"
#include "adiv5.h"

/* Non-Volatile Memory Controller (NVMC) Registers */
#define NRF91_NVMC 0x50039000U
#define NRF91_NVMC_READY (NRF91_NVMC + 0x400U)
#define NRF91_NVMC_CONFIG (NRF91_NVMC + 0x504U)
#define NRF91_NVMC_ERASEALL (NRF91_NVMC + 0x50cU)

#define NRF91_NVMC_CONFIG_REN 0x0U // Read only access
#define NRF91_NVMC_CONFIG_WEN 0x1U // Write enable
#define NRF91_NVMC_CONFIG_EEN 0x2U // Erase enable
#define NRF91_NVMC_CONFIG_PEEN 0x3U // Partial erase enable

static bool nrf91_wait_ready(target_s *const target, platform_timeout_s *const timeout)
{
/* Poll for NVMC_READY */
while (target_mem_read32(target, NRF91_NVMC_READY) == 0) {
if (target_check_error(target))
return false;
if (timeout)
target_print_progress(timeout);
}
return true;
}

static bool nrf91_flash_erase(target_flash_s *flash, target_addr_t addr, size_t len)
{
target_s *target = flash->t;

/* Enable erase */
target_mem_write32(target, NRF91_NVMC_CONFIG, NRF91_NVMC_CONFIG_EEN);
if (!nrf91_wait_ready(target, NULL))
return false;

for (size_t offset = 0; offset < len; offset += flash->blocksize) {
/* Write all ones to first word in page to erase it */
target_mem_write32(target, addr + offset, 0xffffffffU);

if (!nrf91_wait_ready(target, NULL))
return false;
}

/* Return to read-only */
target_mem_write32(target, NRF91_NVMC_CONFIG, NRF91_NVMC_CONFIG_REN);
return nrf91_wait_ready(target, NULL);
}

static bool nrf91_flash_write(target_flash_s *flash, target_addr_t dest, const void *src, size_t len)
{
target_s *target = flash->t;

/* Enable write */
target_mem_write32(target, NRF91_NVMC_CONFIG, NRF91_NVMC_CONFIG_WEN);
if (!nrf91_wait_ready(target, NULL))
return false;
/* Write the data */
target_mem_write(target, dest, src, len);
if (!nrf91_wait_ready(target, NULL))
return false;
/* Return to read-only */
target_mem_write32(target, NRF91_NVMC_CONFIG, NRF91_NVMC_CONFIG_REN);
return true;
}

static void nrf91_add_flash(target_s *target, uint32_t addr, size_t length, size_t erasesize)
{
target_flash_s *flash = calloc(1, sizeof(*flash));
if (!flash) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return;
}

flash->start = addr;
flash->length = length;
flash->blocksize = erasesize;
flash->erase = nrf91_flash_erase;
flash->write = nrf91_flash_write;
flash->erased = 0xff;
target_add_flash(target, flash);
}

bool nrf91_probe(target_s *target)
{
adiv5_access_port_s *ap = cortex_ap(target);

if (ap->dp->version < 2U)
return false;

switch (ap->dp->target_partno) {
case 0x90:
target->driver = "Nordic nRF9160";
target->target_options |= CORTEXM_TOPT_INHIBIT_NRST;
target_add_ram(target, 0x20000000, 256U * 1024U);
nrf91_add_flash(target, 0, 4096U * 256U, 4096U);
break;
default:
return false;
}

return true;
}
1 change: 1 addition & 0 deletions src/target/target_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ TARGET_PROBE_WEAK_NOP(samx7x_probe)
TARGET_PROBE_WEAK_NOP(sam3x_probe)
TARGET_PROBE_WEAK_NOP(sam4l_probe)
TARGET_PROBE_WEAK_NOP(nrf51_probe)
TARGET_PROBE_WEAK_NOP(nrf91_probe)
TARGET_PROBE_WEAK_NOP(samd_probe)
TARGET_PROBE_WEAK_NOP(samx5x_probe)
TARGET_PROBE_WEAK_NOP(kinetis_probe)
Expand Down
1 change: 1 addition & 0 deletions src/target/target_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ bool samx7x_probe(target_s *target);
bool sam3x_probe(target_s *target);
bool sam4l_probe(target_s *target);
bool nrf51_probe(target_s *target);
bool nrf91_probe(target_s *target);
bool samd_probe(target_s *target);
bool samx5x_probe(target_s *target);
bool kinetis_probe(target_s *target);
Expand Down