aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorluca vinci <luca.vinci@st.com>2020-01-08 10:15:40 +0100
committerTomas Vanek <vanekt@fbl.cz>2020-03-07 15:31:09 +0000
commite9932ef23d4af8466e724b7603549778fb93c294 (patch)
tree8a6515bc13db7e6d7e67d549f6cf1707a997f578 /src
parent6bc0a77a6e1a1146c44785812595250857fc7307 (diff)
bluenrg-x: simplyfied the driver
Adopted only fast algorithm for flash programming: - write_word and write_byte methods have been removed. - start and end write alignments have been defined. Moved flash controller registers offsets in a common file shared with the flash algorithm. - the flash base address is passed to the flash algorithm as a parameter. Removed unused functions Change-Id: I80aeab3994e477044bbcf02e66d9525dae0cb491 Signed-off-by: luca vinci <luca.vinci@st.com> Reviewed-on: http://openocd.zylin.com/5393 Tested-by: jenkins Reviewed-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-by: Michele Sardo <msmttchr@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/Makefile.am1
-rw-r--r--src/flash/nor/bluenrg-x.c478
-rw-r--r--src/flash/nor/bluenrg-x.h45
3 files changed, 185 insertions, 339 deletions
diff --git a/src/flash/nor/Makefile.am b/src/flash/nor/Makefile.am
index 18b3b859..64c4a907 100644
--- a/src/flash/nor/Makefile.am
+++ b/src/flash/nor/Makefile.am
@@ -76,6 +76,7 @@ NOR_DRIVERS = \
NORHEADERS = \
%D%/core.h \
%D%/cc3220sf.h \
+ %D%/bluenrg-x.h \
%D%/cc26xx.h \
%D%/cfi.h \
%D%/driver.h \
diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c
index 79821168..f7f5e637 100644
--- a/src/flash/nor/bluenrg-x.c
+++ b/src/flash/nor/bluenrg-x.c
@@ -24,119 +24,63 @@
#include <target/armv7m.h>
#include <target/cortex_m.h>
#include "imp.h"
+#include "bluenrg-x.h"
-#define BLUENRG2_IDCODE (0x0200A041)
-#define BLUENRGLP_IDCODE (0x0201E041)
#define BLUENRG2_JTAG_REG (flash_priv_data_2.jtag_idcode_reg)
#define BLUENRGLP_JTAG_REG (flash_priv_data_lp.jtag_idcode_reg)
-#define FLASH_SIZE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_size_reg)
#define DIE_ID_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->die_id_reg)
#define JTAG_IDCODE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->jtag_idcode_reg)
-#define FLASH_BASE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_base)
#define FLASH_PAGE_SIZE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_page_size)
-#define FLASH_REG_COMMAND(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_command)
-#define FLASH_REG_IRQRAW(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_irqraw)
-#define FLASH_REG_ADDRESS(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_address)
-#define FLASH_REG_DATA(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_data)
-#define FLASH_CMD_ERASE_PAGE 0x11
-#define FLASH_CMD_MASSERASE 0x22
-#define FLASH_CMD_WRITE 0x33
-#define FLASH_CMD_BURSTWRITE 0xCC
-#define FLASH_INT_CMDDONE 0x01
-#define FLASH_WORD_LEN 4
-
-/* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and
- * hints how to generate the data!
- */
-static const uint8_t bluenrgx_flash_write_code_2[] = {
-#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc"
- };
-
-static const uint8_t bluenrgx_flash_write_code_lp[] = {
-#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc"
- };
struct flash_ctrl_priv_data {
- uint32_t flash_size_reg;
uint32_t die_id_reg;
uint32_t jtag_idcode_reg;
uint32_t flash_base;
+ uint32_t flash_regs_base;
uint32_t flash_page_size;
- uint32_t flash_reg_command;
- uint32_t flash_reg_irqraw;
- uint32_t flash_reg_address;
- uint32_t flash_reg_data;
uint32_t jtag_idcode;
char *part_name;
- const uint8_t *flash_write_code;
- uint32_t flash_write_code_size;
};
const struct flash_ctrl_priv_data flash_priv_data_1 = {
- .flash_size_reg = 0x40100014,
.die_id_reg = 0x4090001C,
.jtag_idcode_reg = 0x40900028,
.flash_base = 0x10040000,
+ .flash_regs_base = 0x40100000,
.flash_page_size = 2048,
- .flash_reg_command = 0x40100000,
- .flash_reg_irqraw = 0x40100010,
- .flash_reg_address = 0x40100018,
- .flash_reg_data = 0x40100040,
.jtag_idcode = 0x00000000,
.part_name = "BLUENRG-1",
- .flash_write_code = bluenrgx_flash_write_code_2,
- .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
};
const struct flash_ctrl_priv_data flash_priv_data_2 = {
- .flash_size_reg = 0x40100014,
.die_id_reg = 0x4090001C,
.jtag_idcode_reg = 0x40900028,
.flash_base = 0x10040000,
+ .flash_regs_base = 0x40100000,
.flash_page_size = 2048,
- .flash_reg_command = 0x40100000,
- .flash_reg_irqraw = 0x40100010,
- .flash_reg_address = 0x40100018,
- .flash_reg_data = 0x40100040,
- .jtag_idcode = BLUENRG2_IDCODE,
+ .jtag_idcode = 0x0200A041,
.part_name = "BLUENRG-2",
- .flash_write_code = bluenrgx_flash_write_code_2,
- .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
};
const struct flash_ctrl_priv_data flash_priv_data_lp = {
- .flash_size_reg = 0x40001014,
.die_id_reg = 0x40000000,
.jtag_idcode_reg = 0x40000004,
.flash_base = 0x10040000,
+ .flash_regs_base = 0x40001000,
.flash_page_size = 2048,
- .flash_reg_command = 0x40001000,
- .flash_reg_irqraw = 0x40001010,
- .flash_reg_address = 0x40001018,
- .flash_reg_data = 0x40001040,
- .jtag_idcode = BLUENRGLP_IDCODE,
+ .jtag_idcode = 0x0201E041,
.part_name = "BLUENRG-LP",
- .flash_write_code = bluenrgx_flash_write_code_lp,
- .flash_write_code_size = sizeof(bluenrgx_flash_write_code_lp),
};
struct bluenrgx_flash_bank {
int probed;
uint32_t die_id;
const struct flash_ctrl_priv_data *flash_ptr;
- const uint8_t *flash_write_code;
- uint32_t flash_write_code_size;
};
const struct flash_ctrl_priv_data *flash_ctrl[] = {&flash_priv_data_1, &flash_priv_data_2, &flash_priv_data_lp};
-static int bluenrgx_protect_check(struct flash_bank *bank)
-{
- /* Nothing to do. Protection is only handled in SW. */
- return ERROR_OK;
-}
-
/* flash_bank bluenrg-x 0 0 0 0 <target#> */
FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)
{
@@ -150,6 +94,9 @@ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)
return ERROR_FAIL;
}
+ bank->write_start_alignment = 16;
+ bank->write_end_alignment = 16;
+
bank->driver_priv = bluenrgx_info;
bluenrgx_info->probed = 0;
@@ -160,6 +107,22 @@ FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)
return ERROR_OK;
}
+static inline uint32_t bluenrgx_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset)
+{
+ struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
+ return bluenrgx_info->flash_ptr->flash_regs_base + reg_offset;
+}
+
+static inline int bluenrgx_read_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t *value)
+{
+ return target_read_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value);
+}
+
+static inline int bluenrgx_write_flash_reg(struct flash_bank *bank, uint32_t reg_offset, uint32_t value)
+{
+ return target_write_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value);
+}
+
static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
{
int retval = ERROR_OK;
@@ -186,25 +149,25 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
if (mass_erase) {
command = FLASH_CMD_MASSERASE;
address = bank->base;
- if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
- if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
- (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS,
+ (address - bank->base) >> 2) != ERROR_OK) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
- if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
for (int i = 0; i < 100; i++) {
uint32_t value;
- if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
+ if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
@@ -222,25 +185,25 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
address = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info);
LOG_DEBUG("address = %08x, index = %d", address, i);
- if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
- if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
- (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS,
+ (address - bank->base) >> 2) != ERROR_OK) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
- if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
+ if (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, command) != ERROR_OK) {
LOG_ERROR("Failed");
return ERROR_FAIL;
}
for (int j = 0; j < 100; j++) {
uint32_t value;
- if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
+ if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) {
LOG_ERROR("Register write failed");
return ERROR_FAIL;
}
@@ -258,143 +221,6 @@ static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
}
-static int bluenrgx_protect(struct flash_bank *bank, int set, int first, int last)
-{
- /* Protection is only handled in software: no hardware write protection
- available in BlueNRG-x devices */
- int sector;
-
- for (sector = first; sector <= last; sector++)
- bank->sectors[sector].is_protected = set;
- return ERROR_OK;
-}
-
-static int bluenrgx_write_word(struct flash_bank *bank, uint32_t address_base, uint8_t *values, uint32_t count)
-{
- int retval = ERROR_OK;
- struct target *target = bank->target;
- struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
-
- retval = target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f);
- if (retval != ERROR_OK) {
- LOG_ERROR("Register write failed, error code: %d", retval);
- return retval;
- }
-
- for (uint32_t i = 0; i < count; i++) {
- uint32_t address = address_base + i * FLASH_WORD_LEN;
-
- retval = target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
- (address - FLASH_BASE(bluenrgx_info)) >> 2);
- if (retval != ERROR_OK) {
- LOG_ERROR("Register write failed, error code: %d", retval);
- return retval;
- }
-
- retval = target_write_buffer(target, FLASH_REG_DATA(bluenrgx_info),
- FLASH_WORD_LEN, values + i * FLASH_WORD_LEN);
- if (retval != ERROR_OK) {
- LOG_ERROR("Register write failed, error code: %d", retval);
- return retval;
- }
-
- retval = target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), FLASH_CMD_WRITE);
- if (retval != ERROR_OK) {
- LOG_ERROR("Register write failed, error code: %d", retval);
- return retval;
- }
-
- for (int j = 0; j < 100; j++) {
- uint32_t reg_value;
- retval = target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &reg_value);
-
- if (retval != ERROR_OK) {
- LOG_ERROR("Register read failed, error code: %d", retval);
- return retval;
- }
-
- if (reg_value & FLASH_INT_CMDDONE)
- break;
-
- if (j == 99) {
- LOG_ERROR("Write command failed (timeout)");
- return ERROR_FAIL;
- }
- }
- }
- return retval;
-}
-
-static int bluenrgx_write_bytes(struct flash_bank *bank, uint32_t address_base, uint8_t *buffer, uint32_t count)
-{
- int retval = ERROR_OK;
- struct target *target = bank->target;
- uint8_t *new_buffer = NULL;
- uint32_t pre_bytes = 0, post_bytes = 0, pre_word, post_word, pre_address, post_address;
-
- if (count == 0) {
- /* Just return if there are no bytes to write */
- return retval;
- }
-
- if (address_base & 3) {
- pre_bytes = address_base & 3;
- pre_address = address_base - pre_bytes;
- }
-
- if ((count + pre_bytes) & 3) {
- post_bytes = ((count + pre_bytes + 3) & ~3) - (count + pre_bytes);
- post_address = (address_base + count) & ~3;
- }
-
- if (pre_bytes || post_bytes) {
- uint32_t old_count = count;
-
- count = old_count + pre_bytes + post_bytes;
-
- new_buffer = malloc(count);
-
- if (new_buffer == NULL) {
- LOG_ERROR("odd number of bytes to write and no memory "
- "for padding buffer");
- return ERROR_FAIL;
- }
-
- LOG_INFO("Requested number of bytes to write and/or address not word aligned (%" PRIu32 "), extending to %"
- PRIu32 " ", old_count, count);
-
- if (pre_bytes) {
- if (target_read_u32(target, pre_address, &pre_word)) {
- LOG_ERROR("Memory read failed");
- free(new_buffer);
- return ERROR_FAIL;
- }
-
- }
-
- if (post_bytes) {
- if (target_read_u32(target, post_address, &post_word)) {
- LOG_ERROR("Memory read failed");
- free(new_buffer);
- return ERROR_FAIL;
- }
-
- }
-
- memcpy(new_buffer, &pre_word, pre_bytes);
- memcpy((new_buffer+((pre_bytes+old_count) & ~3)), &post_word, 4);
- memcpy(new_buffer+pre_bytes, buffer, old_count);
- buffer = new_buffer;
- }
-
- retval = bluenrgx_write_word(bank, address_base - pre_bytes, buffer, count/4);
-
- if (new_buffer)
- free(new_buffer);
-
- return retval;
-}
-
static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
uint32_t offset, uint32_t count)
{
@@ -406,10 +232,16 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
struct working_area *source;
uint32_t address = bank->base + offset;
struct reg_param reg_params[5];
+ struct mem_param mem_params[1];
struct armv7m_algorithm armv7m_info;
int retval = ERROR_OK;
- uint32_t pre_size = 0, fast_size = 0, post_size = 0;
- uint32_t pre_offset = 0, fast_offset = 0, post_offset = 0;
+
+ /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and
+ * hints how to generate the data!
+ */
+ static const uint8_t bluenrgx_flash_write_code[] = {
+#include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc"
+ };
/* check preconditions */
if (bluenrgx_info->probed == 0)
@@ -427,133 +259,105 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
return ERROR_TARGET_NOT_HALTED;
}
- /* We are good here and we need to compute pre_size, fast_size, post_size */
- pre_size = MIN(count, ((offset+0xF) & ~0xF) - offset);
- pre_offset = offset;
- fast_size = 16*((count - pre_size) / 16);
- fast_offset = offset + pre_size;
- post_size = (count-pre_size-fast_size) % 16;
- post_offset = fast_offset + fast_size;
-
- LOG_DEBUG("pre_size = %08x, pre_offset=%08x", pre_size, pre_offset);
- LOG_DEBUG("fast_size = %08x, fast_offset=%08x", fast_size, fast_offset);
- LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size, post_offset);
-
- /* Program initial chunk not 16 bytes aligned */
- retval = bluenrgx_write_bytes(bank, bank->base+pre_offset, (uint8_t *) buffer, pre_size);
- if (retval) {
- LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
- return ERROR_FAIL;
+ if (target_alloc_working_area(target, sizeof(bluenrgx_flash_write_code),
+ &write_algorithm) != ERROR_OK) {
+ LOG_WARNING("no working area available, can't do block memory writes");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- /* Program chunk 16 bytes aligned in fast mode */
- if (fast_size) {
-
- if (target_alloc_working_area(target, bluenrgx_info->flash_write_code_size,
- &write_algorithm) != ERROR_OK) {
- LOG_WARNING("no working area available, can't do block memory writes");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
-
- retval = target_write_buffer(target, write_algorithm->address,
- bluenrgx_info->flash_write_code_size,
- bluenrgx_info->flash_write_code);
- if (retval != ERROR_OK)
- return retval;
+ retval = target_write_buffer(target, write_algorithm->address,
+ sizeof(bluenrgx_flash_write_code),
+ bluenrgx_flash_write_code);
+ if (retval != ERROR_OK)
+ return retval;
- /* memory buffer */
- if (target_alloc_working_area(target, buffer_size, &source)) {
- LOG_WARNING("no large enough working area available");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
+ /* memory buffer */
+ if (target_alloc_working_area(target, buffer_size, &source)) {
+ LOG_WARNING("no large enough working area available");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
- /* Stack pointer area */
- if (target_alloc_working_area(target, 64,
- &write_algorithm_sp) != ERROR_OK) {
- LOG_DEBUG("no working area for write code stack pointer");
- return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
- }
+ /* Stack pointer area */
+ if (target_alloc_working_area(target, 128,
+ &write_algorithm_sp) != ERROR_OK) {
+ LOG_DEBUG("no working area for write code stack pointer");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
- armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
- armv7m_info.core_mode = ARM_MODE_THREAD;
-
- init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
- init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
- init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
- init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
- init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);
-
- /* FIFO start address (first two words used for write and read pointers) */
- buf_set_u32(reg_params[0].value, 0, 32, source->address);
- /* FIFO end address (first two words used for write and read pointers) */
- buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
- /* Flash memory address */
- buf_set_u32(reg_params[2].value, 0, 32, address+pre_size);
- /* Number of bytes */
- buf_set_u32(reg_params[3].value, 0, 32, fast_size);
- /* Stack pointer for program working area */
- buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address);
-
- LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address);
- LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size);
- LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address);
- LOG_DEBUG("address = %08x", address+pre_size);
- LOG_DEBUG("count = %08x", count);
-
- retval = target_run_flash_async_algorithm(target,
- buffer+pre_size,
- fast_size/16,
- 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */
- 0,
- NULL,
- 5,
- reg_params,
- source->address,
- source->size,
- write_algorithm->address,
- 0,
- &armv7m_info);
-
- if (retval == ERROR_FLASH_OPERATION_FAILED) {
- LOG_ERROR("error executing bluenrg-x flash write algorithm");
-
- uint32_t error = buf_get_u32(reg_params[0].value, 0, 32);
-
- if (error != 0)
- LOG_ERROR("flash write failed = %08" PRIx32, error);
- }
+ armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+ armv7m_info.core_mode = ARM_MODE_THREAD;
+
+ init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
+ init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
+ init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
+ init_reg_param(&reg_params[4], "sp", 32, PARAM_OUT);
+ /* Put the parameter at the first available stack location */
+ init_mem_param(&mem_params[0], write_algorithm_sp->address + 80, 32, PARAM_OUT);
+
+ /* FIFO start address (first two words used for write and read pointers) */
+ buf_set_u32(reg_params[0].value, 0, 32, source->address);
+ /* FIFO end address (first two words used for write and read pointers) */
+ buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
+ /* Flash memory address */
+ buf_set_u32(reg_params[2].value, 0, 32, address);
+ /* Number of bytes */
+ buf_set_u32(reg_params[3].value, 0, 32, count);
+ /* Stack pointer for program working area */
+ buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address);
+ /* Flash register base address */
+ buf_set_u32(mem_params[0].value, 0, 32, bluenrgx_info->flash_ptr->flash_regs_base);
+
+ LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address);
+ LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size);
+ LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address);
+ LOG_DEBUG("address = %08x", address);
+ LOG_DEBUG("count = %08x", count);
+
+ retval = target_run_flash_async_algorithm(target,
+ buffer,
+ count/16,
+ 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */
+ 1,
+ mem_params,
+ 5,
+ reg_params,
+ source->address,
+ source->size,
+ write_algorithm->address,
+ 0,
+ &armv7m_info);
+
+ if (retval == ERROR_FLASH_OPERATION_FAILED) {
+ LOG_ERROR("error executing bluenrg-x flash write algorithm");
+
+ uint32_t error = buf_get_u32(reg_params[0].value, 0, 32);
+
+ if (error != 0)
+ LOG_ERROR("flash write failed = %08" PRIx32, error);
+ }
+ if (retval == ERROR_OK) {
+ uint32_t rp;
+ /* Read back rp and check that is valid */
+ retval = target_read_u32(target, source->address+4, &rp);
if (retval == ERROR_OK) {
- uint32_t rp;
- /* Read back rp and check that is valid */
- retval = target_read_u32(target, source->address+4, &rp);
- if (retval == ERROR_OK) {
- if ((rp < source->address+8) || (rp > (source->address + source->size))) {
- LOG_ERROR("flash write failed = %08" PRIx32, rp);
- retval = ERROR_FLASH_OPERATION_FAILED;
- }
+ if ((rp < source->address+8) || (rp > (source->address + source->size))) {
+ LOG_ERROR("flash write failed = %08" PRIx32, rp);
+ retval = ERROR_FLASH_OPERATION_FAILED;
}
}
- target_free_working_area(target, source);
- target_free_working_area(target, write_algorithm);
- target_free_working_area(target, write_algorithm_sp);
-
- destroy_reg_param(&reg_params[0]);
- destroy_reg_param(&reg_params[1]);
- destroy_reg_param(&reg_params[2]);
- destroy_reg_param(&reg_params[3]);
- destroy_reg_param(&reg_params[4]);
- if (retval != ERROR_OK)
- return retval;
-
}
+ target_free_working_area(target, source);
+ target_free_working_area(target, write_algorithm);
+ target_free_working_area(target, write_algorithm_sp);
+
+ destroy_reg_param(&reg_params[0]);
+ destroy_reg_param(&reg_params[1]);
+ destroy_reg_param(&reg_params[2]);
+ destroy_reg_param(&reg_params[3]);
+ destroy_reg_param(&reg_params[4]);
+ destroy_mem_param(&mem_params[0]);
- /* Program chunk at end, not addressable by fast burst write algorithm */
- retval = bluenrgx_write_bytes(bank, bank->base+post_offset,
- (uint8_t *) (buffer+pre_size+fast_size), post_size);
- if (retval) {
- LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
- return ERROR_FAIL;
- }
return retval;
}
@@ -567,7 +371,7 @@ static int bluenrgx_probe(struct flash_bank *bank)
if (retval != ERROR_OK)
return retval;
- if (idcode != BLUENRGLP_IDCODE) {
+ if (idcode != flash_priv_data_lp.jtag_idcode) {
retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode);
if (retval != ERROR_OK)
return retval;
@@ -575,19 +379,16 @@ static int bluenrgx_probe(struct flash_bank *bank)
/* Default device is BlueNRG-1 */
bluenrgx_info->flash_ptr = &flash_priv_data_1;
- bluenrgx_info->flash_write_code = flash_priv_data_1.flash_write_code;
- bluenrgx_info->flash_write_code_size = flash_priv_data_1.flash_write_code_size;
+ bank->base = flash_priv_data_1.flash_base;
for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) {
if (idcode == (*flash_ctrl[i]).jtag_idcode) {
bluenrgx_info->flash_ptr = flash_ctrl[i];
- bluenrgx_info->flash_write_code = (*flash_ctrl[i]).flash_write_code;
- bluenrgx_info->flash_write_code_size = (*flash_ctrl[i]).flash_write_code_size;
+ bank->base = (*flash_ctrl[i]).flash_base;
break;
}
}
-
- retval = target_read_u32(bank->target, FLASH_SIZE_REG(bluenrgx_info), &size_info);
+ retval = bluenrgx_read_flash_reg(bank, FLASH_SIZE_REG, &size_info);
if (retval != ERROR_OK)
return retval;
@@ -596,7 +397,6 @@ static int bluenrgx_probe(struct flash_bank *bank)
return retval;
bank->size = (size_info + 1) * FLASH_WORD_LEN;
- bank->base = FLASH_BASE(bluenrgx_info);
bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info);
bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors);
@@ -650,12 +450,12 @@ const struct flash_driver bluenrgx_flash = {
.name = "bluenrg-x",
.flash_bank_command = bluenrgx_flash_bank_command,
.erase = bluenrgx_erase,
- .protect = bluenrgx_protect,
+ .protect = NULL,
.write = bluenrgx_write,
.read = default_flash_read,
.probe = bluenrgx_probe,
.erase_check = default_flash_blank_check,
- .protect_check = bluenrgx_protect_check,
+ .protect_check = NULL,
.auto_probe = bluenrgx_auto_probe,
.info = bluenrgx_get_info,
};
diff --git a/src/flash/nor/bluenrg-x.h b/src/flash/nor/bluenrg-x.h
new file mode 100644
index 00000000..3b84b8b1
--- /dev/null
+++ b/src/flash/nor/bluenrg-x.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2019 by STMicroelectronics. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * 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, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef OPENOCD_FLASH_NOR_BLUENRGX_H
+#define OPENOCD_FLASH_NOR_BLUENRGX_H
+
+/* Flash Controller registers offsets */
+#define FLASH_REG_COMMAND 0x00
+#define FLASH_REG_CONFIG 0x04
+#define FLASH_REG_IRQSTAT 0x08
+#define FLASH_REG_IRQMASK 0x0C
+#define FLASH_REG_IRQRAW 0x10
+#define FLASH_REG_ADDRESS 0x18
+#define FLASH_REG_UNLOCKM 0x1C
+#define FLASH_REG_UNLOCKL 0x20
+#define FLASH_REG_DATA0 0x40
+#define FLASH_REG_DATA1 0x44
+#define FLASH_REG_DATA2 0x48
+#define FLASH_REG_DATA3 0x4C
+#define FLASH_SIZE_REG 0x14
+
+/* Flash Controller commands */
+#define FLASH_CMD_ERASE_PAGE 0x11
+#define FLASH_CMD_MASSERASE 0x22
+#define FLASH_CMD_WRITE 0x33
+#define FLASH_CMD_BURSTWRITE 0xCC
+#define FLASH_INT_CMDDONE 0x01
+
+#define FLASH_WORD_LEN 4
+
+#endif /* OPENOCD_FLASH_NOR_BLUENRGX_H */