target/sam: flash read write return bool
This commit is contained in:
parent
44f7984c58
commit
67c9f3f6e2
|
@ -28,9 +28,9 @@
|
||||||
#include "target.h"
|
#include "target.h"
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
|
|
||||||
static int sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
static bool sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
||||||
static int sam3_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
static bool sam3_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
||||||
static int sam_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
static bool sam_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
||||||
|
|
||||||
static int sam_gpnvm_get(target *t, uint32_t base, uint32_t *gpnvm);
|
static int sam_gpnvm_get(target *t, uint32_t base, uint32_t *gpnvm);
|
||||||
|
|
||||||
|
@ -498,24 +498,20 @@ bool sam3x_probe(target *t)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static bool sam_flash_cmd(target *t, uint32_t base, uint8_t cmd, uint16_t arg)
|
||||||
sam_flash_cmd(target *t, uint32_t base, uint8_t cmd, uint16_t arg)
|
|
||||||
{
|
{
|
||||||
DEBUG_INFO("%s: base = 0x%08"PRIx32" cmd = 0x%02X, arg = 0x%06X\n",
|
DEBUG_INFO("%s: base = 0x%08" PRIx32 " cmd = 0x%02X, arg = 0x%06X\n", __func__, base, cmd, arg);
|
||||||
__func__, base, cmd, arg);
|
|
||||||
|
|
||||||
if(base == 0)
|
if (base == 0)
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
target_mem_write32(t, EEFC_FCR(base),
|
target_mem_write32(t, EEFC_FCR(base), EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));
|
||||||
EEFC_FCR_FKEY | cmd | ((uint32_t)arg << 8));
|
|
||||||
|
|
||||||
while (!(target_mem_read32(t, EEFC_FSR(base)) & EEFC_FSR_FRDY))
|
while (!(target_mem_read32(t, EEFC_FSR(base)) & EEFC_FSR_FRDY))
|
||||||
if(target_check_error(t))
|
if (target_check_error(t))
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
uint32_t sr = target_mem_read32(t, EEFC_FSR(base));
|
return !(target_mem_read32(t, EEFC_FSR(base)) & EEFC_FSR_ERROR);
|
||||||
return sr & EEFC_FSR_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum sam_driver sam_driver(target *t)
|
static enum sam_driver sam_driver(target *t)
|
||||||
|
@ -535,7 +531,7 @@ static enum sam_driver sam_driver(target *t)
|
||||||
return DRIVER_SAMX7X;
|
return DRIVER_SAMX7X;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
static bool sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
uint32_t base = ((struct sam_flash *)f)->eefc_base;
|
uint32_t base = ((struct sam_flash *)f)->eefc_base;
|
||||||
|
@ -549,8 +545,8 @@ static int sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
int16_t arg = chunk | 0x1;
|
int16_t arg = chunk | 0x1;
|
||||||
if(sam_flash_cmd(t, base, EEFC_FCR_FCMD_EPA, arg))
|
if(!sam_flash_cmd(t, base, EEFC_FCR_FCMD_EPA, arg))
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
if (len > f->blocksize)
|
if (len > f->blocksize)
|
||||||
len -= f->blocksize;
|
len -= f->blocksize;
|
||||||
|
@ -558,19 +554,22 @@ static int sam_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
len = 0;
|
len = 0;
|
||||||
chunk += 8;
|
chunk += 8;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sam3_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
static bool sam3_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
/* The SAM3X/SAM3N don't really have a page erase function.
|
/* The SAM3X/SAM3N don't really have a page erase function.
|
||||||
* We do nothing here and use Erase/Write page in flash_write.
|
* We do nothing here and use Erase/Write page in flash_write.
|
||||||
*/
|
*/
|
||||||
(void)f; (void)addr; (void)len;
|
(void)f;
|
||||||
return 0;
|
(void)addr;
|
||||||
|
(void)len;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sam_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
|
static bool sam_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
struct sam_flash *sf = (struct sam_flash *)f;
|
struct sam_flash *sf = (struct sam_flash *)f;
|
||||||
|
@ -578,15 +577,13 @@ static int sam_flash_write(target_flash_s *f, target_addr_t dest, const void *sr
|
||||||
unsigned chunk = (dest - f->start) / f->writesize;
|
unsigned chunk = (dest - f->start) / f->writesize;
|
||||||
|
|
||||||
target_mem_write(t, dest, src, len);
|
target_mem_write(t, dest, src, len);
|
||||||
if(sam_flash_cmd(t, base, sf->write_cmd, chunk))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
return sam_flash_cmd(t, base, sf->write_cmd, chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sam_gpnvm_get(target *t, uint32_t base, uint32_t *gpnvm)
|
static int sam_gpnvm_get(target *t, uint32_t base, uint32_t *gpnvm)
|
||||||
{
|
{
|
||||||
if(!gpnvm || sam_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0))
|
if(!gpnvm || !sam_flash_cmd(t, base, EEFC_FCR_FCMD_GGPB, 0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*gpnvm = target_mem_read32(t, EEFC_FRR(base));
|
*gpnvm = target_mem_read32(t, EEFC_FRR(base));
|
||||||
|
@ -652,7 +649,7 @@ static bool sam_cmd_gpnvm(target *t, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
if (work_mask & 1) {
|
if (work_mask & 1) {
|
||||||
uint8_t cmd = (work_values & 1) ? EEFC_FCR_FCMD_SGPB : EEFC_FCR_FCMD_CGPB;
|
uint8_t cmd = (work_values & 1) ? EEFC_FCR_FCMD_SGPB : EEFC_FCR_FCMD_CGPB;
|
||||||
if(sam_flash_cmd(t, base, cmd, bit))
|
if(!sam_flash_cmd(t, base, cmd, bit))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
work_mask >>= 1;
|
work_mask >>= 1;
|
||||||
|
|
|
@ -103,8 +103,8 @@
|
||||||
#define FLASHCALW_FGPFRLO (FLASHCALW_BASE + 0x18)
|
#define FLASHCALW_FGPFRLO (FLASHCALW_BASE + 0x18)
|
||||||
|
|
||||||
static void sam4l_extended_reset(target *t);
|
static void sam4l_extended_reset(target *t);
|
||||||
static int sam4l_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
static bool sam4l_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
||||||
static int sam4l_flash_write_buf(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
static bool sam4l_flash_write_buf(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
||||||
|
|
||||||
/* why Atmel couldn't make it sequential ... */
|
/* why Atmel couldn't make it sequential ... */
|
||||||
static const size_t __ram_size[16] = {
|
static const size_t __ram_size[16] = {
|
||||||
|
@ -159,7 +159,7 @@ static const size_t __nvp_size[16] = {
|
||||||
|
|
||||||
|
|
||||||
/* Arbitrary time to wait for FLASH controller to be ready */
|
/* Arbitrary time to wait for FLASH controller to be ready */
|
||||||
#define FLASH_TIMEOUT 10000
|
#define FLASH_TIMEOUT 1000 /* ms */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Populate a target_flash struct with the necessary function pointers
|
* Populate a target_flash struct with the necessary function pointers
|
||||||
|
@ -292,63 +292,55 @@ sam4l_extended_reset(target *t)
|
||||||
* Need the target struct to call the mem_read32 and mem_write32 function
|
* Need the target struct to call the mem_read32 and mem_write32 function
|
||||||
* pointers.
|
* pointers.
|
||||||
*/
|
*/
|
||||||
static int
|
static bool sam4l_flash_command(target *t, uint32_t page, uint32_t cmd)
|
||||||
sam4l_flash_command(target *t, uint32_t page, uint32_t cmd)
|
|
||||||
{
|
{
|
||||||
uint32_t cmd_reg;
|
DEBUG_INFO(
|
||||||
uint32_t status;
|
"\nSAM4L: sam4l_flash_command: FSR: 0x%08" PRIx32 ", page = %lu, command = %lu\n", FLASHCALW_FSR, page, cmd);
|
||||||
int timeout;
|
|
||||||
DEBUG_INFO("\nSAM4L: sam4l_flash_command: FSR: 0x%08x, page = %d, "
|
|
||||||
"command = %d\n", (unsigned int)(FLASHCALW_FSR),
|
|
||||||
(int) page, (int) cmd);
|
|
||||||
/* wait for Flash controller ready */
|
/* wait for Flash controller ready */
|
||||||
for (timeout = 0; timeout < FLASH_TIMEOUT; timeout++) {
|
platform_timeout timeout;
|
||||||
status = target_mem_read32(t, FLASHCALW_FSR);
|
platform_timeout_set(&timeout, FLASH_TIMEOUT);
|
||||||
if (status & FLASHCALW_FSR_FRDY) {
|
while (!(target_mem_read32(t, FLASHCALW_FSR) & FLASHCALW_FSR_FRDY)) {
|
||||||
break;
|
if (platform_timeout_is_expired(&timeout)) {
|
||||||
|
DEBUG_WARN("\nSAM4L: sam4l_flash_command: Not ready!\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timeout == FLASH_TIMEOUT) {
|
|
||||||
DEBUG_WARN("\nSAM4L: sam4l_flash_command: Not ready! "
|
|
||||||
"Status = 0x%08x\n", (unsigned int) status);
|
|
||||||
return -1; /* Failed */
|
|
||||||
}
|
|
||||||
/* load up the new command */
|
/* load up the new command */
|
||||||
cmd_reg = (cmd & FLASHCALW_FCMD_CMD_MASK) |
|
const uint32_t cmd_reg = (cmd & FLASHCALW_FCMD_CMD_MASK) |
|
||||||
((page & FLASHCALW_FCMD_PAGEN_MASK) << FLASHCALW_FCMD_PAGEN_SHIFT) |
|
((page & FLASHCALW_FCMD_PAGEN_MASK) << FLASHCALW_FCMD_PAGEN_SHIFT) |
|
||||||
(0xA5 << FLASHCALW_FCMD_KEY_SHIFT);
|
(0xA5U << FLASHCALW_FCMD_KEY_SHIFT);
|
||||||
DEBUG_INFO("\nSAM4L: sam4l_flash_command: Wrting command word 0x%08x\n",
|
|
||||||
(unsigned int) cmd_reg);
|
DEBUG_INFO("\nSAM4L: sam4l_flash_command: Wrting command word 0x%08" PRIx32 "\n", cmd_reg);
|
||||||
|
|
||||||
/* and kick it off */
|
/* and kick it off */
|
||||||
target_mem_write32(t, FLASHCALW_FCMD, cmd_reg);
|
target_mem_write32(t, FLASHCALW_FCMD, cmd_reg);
|
||||||
|
|
||||||
/* don't actually wait for it to finish, the next command will stall if it is not done */
|
/* don't actually wait for it to finish, the next command will stall if it is not done */
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write data from 'src' into flash using the algorithim provided by
|
* Write data from 'src' into flash using the algorithim provided by
|
||||||
* Atmel in their data sheet.
|
* Atmel in their data sheet.
|
||||||
*/
|
*/
|
||||||
static int sam4l_flash_write_buf(target_flash_s *f, target_addr_t addr, const void *src, size_t len)
|
static bool sam4l_flash_write_buf(target_flash_s *f, target_addr_t addr, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
uint32_t *src_data = (uint32_t *)src;
|
uint32_t *src_data = (uint32_t *)src;
|
||||||
uint32_t ndx;
|
|
||||||
uint16_t page;
|
|
||||||
|
|
||||||
DEBUG_INFO("\nSAM4L: sam4l_flash_write_buf: addr = 0x%08lx, len %d\n",
|
DEBUG_INFO("\nSAM4L: sam4l_flash_write_buf: addr = 0x%08" PRIx32 ", len %d\n", addr, len);
|
||||||
(long unsigned int) addr, (int) len);
|
|
||||||
/* This will fail with unaligned writes, the write_buf version */
|
/* This will fail with unaligned writes, the write_buf version */
|
||||||
page = addr / SAM4L_PAGE_SIZE;
|
const uint16_t page = addr / SAM4L_PAGE_SIZE;
|
||||||
|
|
||||||
if (len != SAM4L_PAGE_SIZE) {
|
if (len != SAM4L_PAGE_SIZE)
|
||||||
return -1;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* clear the page buffer */
|
/* clear the page buffer */
|
||||||
if (sam4l_flash_command(t, 0, FLASH_CMD_CPB)) {
|
if (!sam4l_flash_command(t, 0, FLASH_CMD_CPB))
|
||||||
return -1;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
/* Now fill page buffer with our 512 bytes of data */
|
/* Now fill page buffer with our 512 bytes of data */
|
||||||
|
|
||||||
|
@ -356,7 +348,7 @@ static int sam4l_flash_write_buf(target_flash_s *f, target_addr_t addr, const vo
|
||||||
* last 64 bits (8 bytes) to be incorrect on even pages (0, 2, 4, ...)
|
* last 64 bits (8 bytes) to be incorrect on even pages (0, 2, 4, ...)
|
||||||
* since it works this way I've not investigated further.
|
* since it works this way I've not investigated further.
|
||||||
*/
|
*/
|
||||||
for (ndx = 0; ndx < SAM4L_PAGE_SIZE; ndx += 4) {
|
for (size_t ndx = 0; ndx < SAM4L_PAGE_SIZE; ndx += 4) {
|
||||||
/*
|
/*
|
||||||
* the page buffer overlaps flash, its only 512 bytes long
|
* the page buffer overlaps flash, its only 512 bytes long
|
||||||
* and no matter where you write it from it goes to the page
|
* and no matter where you write it from it goes to the page
|
||||||
|
@ -364,26 +356,23 @@ static int sam4l_flash_write_buf(target_flash_s *f, target_addr_t addr, const vo
|
||||||
* instead we just write 0 - pagelen (512) and that fills our
|
* instead we just write 0 - pagelen (512) and that fills our
|
||||||
* buffer correctly.
|
* buffer correctly.
|
||||||
*/
|
*/
|
||||||
target_mem_write32(t, addr+ndx, *src_data);
|
target_mem_write32(t, addr + ndx, *src_data);
|
||||||
src_data++;
|
src_data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write the page */
|
/* write the page */
|
||||||
if (sam4l_flash_command(t, page, FLASH_CMD_WP)) {
|
return sam4l_flash_command(t, page, FLASH_CMD_WP);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Erase flash across the addresses specified by addr and len
|
* Erase flash across the addresses specified by addr and len
|
||||||
*/
|
*/
|
||||||
static int sam4l_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
static bool sam4l_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
uint16_t page;
|
uint16_t page;
|
||||||
|
|
||||||
DEBUG_INFO("SAM4L: flash erase address 0x%08x for %d bytes\n",
|
DEBUG_INFO("SAM4L: flash erase address 0x%08" PRIx32 " for %d bytes\n", addr, len);
|
||||||
(unsigned int) addr, (unsigned int) len);
|
|
||||||
/*
|
/*
|
||||||
* NB: if addr isn't aligned to a page boundary, or length
|
* NB: if addr isn't aligned to a page boundary, or length
|
||||||
* is not an even multiple of page sizes, we may end up
|
* is not an even multiple of page sizes, we may end up
|
||||||
|
@ -392,14 +381,15 @@ static int sam4l_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
page = addr / SAM4L_PAGE_SIZE;
|
page = addr / SAM4L_PAGE_SIZE;
|
||||||
if (sam4l_flash_command(t, page, FLASH_CMD_EP)) {
|
if (!sam4l_flash_command(t, page, FLASH_CMD_EP))
|
||||||
return -1;
|
return false;
|
||||||
}
|
|
||||||
if (len > SAM4L_PAGE_SIZE)
|
if (len > SAM4L_PAGE_SIZE)
|
||||||
len -= SAM4L_PAGE_SIZE;
|
len -= SAM4L_PAGE_SIZE;
|
||||||
else
|
else
|
||||||
len = 0;
|
len = 0;
|
||||||
|
|
||||||
addr += SAM4L_PAGE_SIZE;
|
addr += SAM4L_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,8 +39,8 @@
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
#include "cortexm.h"
|
#include "cortexm.h"
|
||||||
|
|
||||||
static int samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
static bool samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
||||||
static int samd_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
static bool samd_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
||||||
bool samd_mass_erase(target *t);
|
bool samd_mass_erase(target *t);
|
||||||
|
|
||||||
static bool samd_cmd_lock_flash(target *t, int argc, const char **argv);
|
static bool samd_cmd_lock_flash(target *t, int argc, const char **argv);
|
||||||
|
@ -579,7 +579,7 @@ static void samd_unlock_current_address(target *t)
|
||||||
/*
|
/*
|
||||||
* Erase flash row by row
|
* Erase flash row by row
|
||||||
*/
|
*/
|
||||||
static int samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
static bool samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
while (len) {
|
while (len) {
|
||||||
|
@ -596,7 +596,7 @@ static int samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
/* Poll for NVM Ready */
|
/* Poll for NVM Ready */
|
||||||
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||||
if (target_check_error(t))
|
if (target_check_error(t))
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
samd_lock_current_address(t);
|
samd_lock_current_address(t);
|
||||||
|
@ -608,14 +608,13 @@ static int samd_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write flash page by page
|
* Write flash page by page
|
||||||
*/
|
*/
|
||||||
static int samd_flash_write(target_flash_s *f,
|
static bool samd_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
|
||||||
target_addr_t dest, const void *src, size_t len)
|
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
|
|
||||||
|
@ -632,12 +631,12 @@ static int samd_flash_write(target_flash_s *f,
|
||||||
/* Poll for NVM Ready */
|
/* Poll for NVM Ready */
|
||||||
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
while ((target_mem_read32(t, SAMD_NVMC_INTFLAG) & SAMD_NVMC_READY) == 0)
|
||||||
if (target_check_error(t))
|
if (target_check_error(t))
|
||||||
return -1;
|
return false;
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
samd_lock_current_address(t);
|
samd_lock_current_address(t);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -38,8 +38,8 @@
|
||||||
#include "target_internal.h"
|
#include "target_internal.h"
|
||||||
#include "cortexm.h"
|
#include "cortexm.h"
|
||||||
|
|
||||||
static int samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
static bool samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len);
|
||||||
static int samx5x_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
static bool samx5x_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len);
|
||||||
static bool samx5x_cmd_lock_flash(target *t, int argc, const char **argv);
|
static bool samx5x_cmd_lock_flash(target *t, int argc, const char **argv);
|
||||||
static bool samx5x_cmd_unlock_flash(target *t, int argc, const char **argv);
|
static bool samx5x_cmd_unlock_flash(target *t, int argc, const char **argv);
|
||||||
static bool samx5x_cmd_unlock_bootprot(target *t, int argc, const char **argv);
|
static bool samx5x_cmd_unlock_bootprot(target *t, int argc, const char **argv);
|
||||||
|
@ -496,7 +496,7 @@ static int samx5x_check_nvm_error(target *t)
|
||||||
/**
|
/**
|
||||||
* Erase flash block by block
|
* Erase flash block by block
|
||||||
*/
|
*/
|
||||||
static int samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
static bool samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
uint16_t errs = samx5x_read_nvm_error(t);
|
uint16_t errs = samx5x_read_nvm_error(t);
|
||||||
|
@ -517,12 +517,12 @@ static int samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
|
|
||||||
if (addr < (15 - bootprot) * 8192) {
|
if (addr < (15 - bootprot) * 8192) {
|
||||||
DEBUG_WARN("Bootprot\n");
|
DEBUG_WARN("Bootprot\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (~runlock & (1 << addr / lock_region_size)) {
|
if (~runlock & (1 << addr / lock_region_size)) {
|
||||||
DEBUG_WARN("runlock\n");
|
DEBUG_WARN("runlock\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
|
@ -541,12 +541,12 @@ static int samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
SAMX5X_STATUS_READY) == 0)
|
SAMX5X_STATUS_READY) == 0)
|
||||||
if (target_check_error(t) || samx5x_check_nvm_error(t)) {
|
if (target_check_error(t) || samx5x_check_nvm_error(t)) {
|
||||||
DEBUG_WARN("NVM Ready\n");
|
DEBUG_WARN("NVM Ready\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target_check_error(t) || samx5x_check_nvm_error(t)) {
|
if (target_check_error(t) || samx5x_check_nvm_error(t)) {
|
||||||
DEBUG_WARN("Error\n");
|
DEBUG_WARN("Error\n");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
|
@ -556,13 +556,13 @@ static int samx5x_flash_erase(target_flash_s *f, target_addr_t addr, size_t len)
|
||||||
len -= f->blocksize;
|
len -= f->blocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write flash page by page
|
* Write flash page by page
|
||||||
*/
|
*/
|
||||||
static int samx5x_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
|
static bool samx5x_flash_write(target_flash_s *f, target_addr_t dest, const void *src, size_t len)
|
||||||
{
|
{
|
||||||
target *t = f->t;
|
target *t = f->t;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
|
@ -595,13 +595,13 @@ static int samx5x_flash_write(target_flash_s *f, target_addr_t dest, const void
|
||||||
if (error || target_check_error(t) || samx5x_check_nvm_error(t)) {
|
if (error || target_check_error(t) || samx5x_check_nvm_error(t)) {
|
||||||
DEBUG_WARN("Error writing flash page at 0x%08"PRIx32
|
DEBUG_WARN("Error writing flash page at 0x%08"PRIx32
|
||||||
" (len 0x%08zx)\n", dest, len);
|
" (len 0x%08zx)\n", dest, len);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lock */
|
/* Lock */
|
||||||
samx5x_lock_current_address(t);
|
samx5x_lock_current_address(t);
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue