Merge pull request #378 from markrages/nordic_unlock
Add extra port for mass erasing / unprotecting nRF52 with APPROTECT set.
This commit is contained in:
commit
c5c0783337
|
@ -448,6 +448,9 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
|
|||
extern void kinetis_mdm_probe(ADIv5_AP_t *);
|
||||
kinetis_mdm_probe(ap);
|
||||
|
||||
extern void nrf51_mdm_probe(ADIv5_AP_t *);
|
||||
nrf51_mdm_probe(ap);
|
||||
|
||||
if (ap->base == 0xffffffff) {
|
||||
/* No debug entries... useless AP */
|
||||
adiv5_ap_unref(ap);
|
||||
|
|
|
@ -341,7 +341,7 @@ const struct command_s kinetis_mdm_cmd_list[] = {
|
|||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
bool nop_function(void)
|
||||
static bool nop_function(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -336,3 +336,81 @@ static bool nrf51_cmd_read(target *t, int argc, const char *argv[])
|
|||
|
||||
return nrf51_cmd_read_help(t);
|
||||
}
|
||||
|
||||
#include "adiv5.h"
|
||||
#define NRF52_MDM_IDR 0x02880000
|
||||
|
||||
static bool nrf51_mdm_cmd_erase_mass(target *t);
|
||||
|
||||
const struct command_s nrf51_mdm_cmd_list[] = {
|
||||
{"erase_mass", (cmd_handler)nrf51_mdm_cmd_erase_mass, "Erase entire flash memory"},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static bool nop_function(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void nrf51_mdm_probe(ADIv5_AP_t *ap)
|
||||
{
|
||||
switch(ap->idr) {
|
||||
case NRF52_MDM_IDR:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
target *t = target_new();
|
||||
adiv5_ap_ref(ap);
|
||||
t->priv = ap;
|
||||
t->priv_free = (void*)adiv5_ap_unref;
|
||||
|
||||
t->driver = "Nordic nRF52 Access Port";
|
||||
t->attach = (void*)nop_function;
|
||||
t->detach = (void*)nop_function;
|
||||
t->check_error = (void*)nop_function;
|
||||
t->mem_read = (void*)nop_function;
|
||||
t->mem_write = (void*)nop_function;
|
||||
t->regs_size = 4;
|
||||
t->regs_read = (void*)nop_function;
|
||||
t->regs_write = (void*)nop_function;
|
||||
t->reset = (void*)nop_function;
|
||||
t->halt_request = (void*)nop_function;
|
||||
//t->halt_poll = mdm_halt_poll;
|
||||
t->halt_resume = (void*)nop_function;
|
||||
|
||||
target_add_commands(t, nrf51_mdm_cmd_list, t->driver);
|
||||
}
|
||||
|
||||
#define MDM_POWER_EN ADIV5_DP_REG(0x01)
|
||||
#define MDM_SELECT_AP ADIV5_DP_REG(0x02)
|
||||
#define MDM_STATUS ADIV5_AP_REG(0x08)
|
||||
#define MDM_CONTROL ADIV5_AP_REG(0x04)
|
||||
#define MDM_PROT_EN ADIV5_AP_REG(0x0C)
|
||||
|
||||
|
||||
static bool nrf51_mdm_cmd_erase_mass(target *t)
|
||||
{
|
||||
ADIv5_AP_t *ap = t->priv;
|
||||
|
||||
uint32_t status = adiv5_ap_read(ap, MDM_STATUS);
|
||||
|
||||
adiv5_dp_write(ap->dp, MDM_POWER_EN, 0x50000000);
|
||||
|
||||
adiv5_dp_write(ap->dp, MDM_SELECT_AP, 0x01000000);
|
||||
|
||||
adiv5_ap_write(ap, MDM_CONTROL, 0x00000001);
|
||||
|
||||
// Read until 0, probably should have a timeout here...
|
||||
do {
|
||||
status = adiv5_ap_read(ap, MDM_STATUS);
|
||||
} while (status);
|
||||
|
||||
// The second read will provide true prot status
|
||||
status = adiv5_ap_read(ap, MDM_PROT_EN);
|
||||
status = adiv5_ap_read(ap, MDM_PROT_EN);
|
||||
|
||||
// should we return the prot status here?
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue