bluenrg-x: simplyfied the driver 93/5393/4
authorluca vinci <luca.vinci@st.com>
Wed, 8 Jan 2020 09:15:40 +0000 (10:15 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Sat, 7 Mar 2020 15:31:09 +0000 (15:31 +0000)
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>
contrib/loaders/flash/bluenrg-x/Makefile
contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc [deleted file]
contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc [deleted file]
contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c
contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc [new file with mode: 0644]
doc/openocd.texi
src/flash/nor/Makefile.am
src/flash/nor/bluenrg-x.c
src/flash/nor/bluenrg-x.h [new file with mode: 0644]
tcl/target/bluenrg-x.cfg

index ce86e481a49affdbe47eb749a1027af92c555796..1a5cfc013f420816a77af5b4c3071a267f74cbc3 100644 (file)
@@ -8,18 +8,15 @@ OBJDUMP=$(CROSS_COMPILE)objdump
 
 CFLAGS =  -c -mthumb -mcpu=cortex-m0 -O3 -g
 
-all:bluenrg-2_write.inc bluenrg-lp_write.inc
+all: bluenrg-x_write.inc
 
 .PHONY: clean
 
 .INTERMEDIATE: bluenrg-x_write.o
 
-bluenrg-2_write.o: bluenrg-x_write.c
+%.o: %.c
        $(CC) $(CFLAGS) -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@
 
-bluenrg-lp_write.o: bluenrg-x_write.c
-       $(CC) $(CFLAGS) -D BLUENRG_LP -Wall -Wextra -Wa,-adhln=$*.lst $< -o $@
-
 %.bin: %.o
        $(OBJCOPY) -Obinary $< $@
 
diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc
deleted file mode 100644 (file)
index 1ce4c86..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Autogenerated with ../../../../src/helper/bin2char.sh */
-0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d,
-0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68,
-0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a,
-0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b,
-0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96,
-0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46,
-0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91,
-0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60,
-0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46,
-0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0,
-0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e,
-0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68,
-0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,
-0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46,
-0x10,0x00,0x10,0x40,0x18,0x00,0x10,0x40,0x0c,0x00,0x10,0x40,0x00,0x00,0xfc,0xef,
-0x40,0x00,0x10,0x40,0x44,0x00,0x10,0x40,0x48,0x00,0x10,0x40,0x4c,0x00,0x10,0x40,
-0x00,0x00,0x10,0x40,
diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc
deleted file mode 100644 (file)
index cc9b2a1..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Autogenerated with ../../../../src/helper/bin2char.sh */
-0x05,0x93,0x43,0x68,0x06,0x00,0x09,0x93,0x05,0x9b,0x07,0x91,0x06,0x92,0x34,0x4d,
-0x34,0x4c,0x00,0x2b,0x5d,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0xfb,0xd0,0x33,0x68,
-0x00,0x2b,0x56,0xd0,0x72,0x68,0x33,0x68,0x9a,0x42,0x53,0xd9,0x73,0x68,0x07,0x9a,
-0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x00,0x21,0x2b,0x4a,0x03,0x93,0x11,0x60,0x00,0x2b,
-0x37,0xd0,0x2a,0x4a,0x06,0x9b,0x94,0x46,0x63,0x44,0x18,0x00,0x73,0x68,0x08,0x96,
-0x04,0x93,0x1a,0x00,0x26,0x4b,0x99,0x46,0x26,0x4b,0x98,0x46,0x26,0x4b,0x9c,0x46,
-0x26,0x4b,0x9b,0x46,0x26,0x4b,0x9a,0x46,0x01,0x23,0x91,0x68,0x17,0x68,0x01,0x91,
-0xd1,0x68,0x56,0x68,0x02,0x91,0x3f,0x21,0x29,0x60,0x81,0x03,0x09,0x0c,0x21,0x60,
-0x49,0x46,0x0f,0x60,0x47,0x46,0x3e,0x60,0x66,0x46,0x01,0x99,0x31,0x60,0x5e,0x46,
-0x02,0x99,0x31,0x60,0x51,0x46,0xcc,0x26,0x0e,0x60,0x29,0x68,0x0b,0x42,0xfc,0xd0,
-0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,0x51,0x1a,0x8e,0x42,0xdd,0xd8,0x08,0x9e,
-0x72,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,0x63,0x44,0x06,0x93,0x07,0x9a,0x73,0x68,
-0x9a,0x42,0x01,0xd8,0x09,0x9b,0x73,0x60,0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,
-0xa1,0xd1,0x00,0xbe,0x33,0x68,0x72,0x68,0x9b,0x1a,0xaa,0xd5,0x9b,0xe7,0xc0,0x46,
-0x10,0x10,0x00,0x40,0x18,0x10,0x00,0x40,0x0c,0x10,0x00,0x40,0x00,0x00,0xfc,0xef,
-0x40,0x10,0x00,0x40,0x44,0x10,0x00,0x40,0x48,0x10,0x00,0x40,0x4c,0x10,0x00,0x40,
-0x00,0x10,0x00,0x40,
index 695f9145ae9f60f6a5541d90411072c0dc808700..f09f7f58abcfb3c32486609a83dd1a2236d3c84a 100644 (file)
@@ -2,6 +2,7 @@
 /* Then postprocess output of command "arm-none-eabi-objdump -d bluenrgx.o" to make a C array of bytes */
 
 #include <stdint.h>
+#include "../../../../src/flash/nor/bluenrg-x.h"
 
 /* Status Values ----------------------------------------------------------*/
 #define SUCCESS             0
 #define ERR_ERASE_REQUIRED  6
 #define ERR_VERIFY_FAILED   7
 
-/* Flash Controller defines ---------------------------------------------------*/
-#ifdef BLUENRG_LP
-#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40001000)
-#define FLASH_REG_CONFIG  ((volatile uint32_t *)0x40001004)
-#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40001008)
-#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4000100C)
-#define FLASH_REG_IRQRAW  ((volatile uint32_t *)0x40001010)
-#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40001018)
-#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4000101C)
-#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40001020)
-#define FLASH_REG_DATA0   ((volatile uint32_t *)0x40001040)
-#define FLASH_REG_DATA1   ((volatile uint32_t *)0x40001044)
-#define FLASH_REG_DATA2   ((volatile uint32_t *)0x40001048)
-#define FLASH_REG_DATA3   ((volatile uint32_t *)0x4000104C)
-#define FLASH_SIZE_REG 0x40001014
-#else
-#define FLASH_REG_COMMAND ((volatile uint32_t *)0x40100000)
-#define FLASH_REG_CONFIG  ((volatile uint32_t *)0x40100004)
-#define FLASH_REG_IRQSTAT ((volatile uint32_t *)0x40100008)
-#define FLASH_REG_IRQMASK ((volatile uint32_t *)0x4010000C)
-#define FLASH_REG_IRQRAW  ((volatile uint32_t *)0x40100010)
-#define FLASH_REG_ADDRESS ((volatile uint32_t *)0x40100018)
-#define FLASH_REG_UNLOCKM ((volatile uint32_t *)0x4010001C)
-#define FLASH_REG_UNLOCKL ((volatile uint32_t *)0x40100020)
-#define FLASH_REG_DATA0   ((volatile uint32_t *)0x40100040)
-#define FLASH_REG_DATA1   ((volatile uint32_t *)0x40100044)
-#define FLASH_REG_DATA2   ((volatile uint32_t *)0x40100048)
-#define FLASH_REG_DATA3   ((volatile uint32_t *)0x4010004C)
-#define FLASH_SIZE_REG 0x40100014
-#endif
-
 #define MFB_MASS_ERASE 0x01
 #define MFB_PAGE_ERASE 0x02
 
 #define DO_ERASE  0x0100
 #define DO_VERIFY 0x0200
-#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 MFB_BOTTOM          (0x10040000)
-#define MFB_SIZE_B          ((16 * (((*(uint32_t *) FLASH_SIZE_REG) + 1) >> 12)) * 1024)
-#define MFB_SIZE_W          (MFB_SIZE_B/4)
-#define MFB_TOP             (MFB_BOTTOM+MFB_SIZE_B-1)
-#define MFB_PAGE_SIZE_B     (2048)
-#define MFB_PAGE_SIZE_W     (MFB_PAGE_SIZE_B/4)
+
+#define MFB_BOTTOM                (0x10040000)
+#define MFB_SIZE_B(regs_base)     ((16 * (((*(volatile uint32_t *)(regs_base + FLASH_SIZE_REG)) + 1) >> 12)) * 1024)
+#define MFB_SIZE_W                (MFB_SIZE_B/4)
+#define MFB_TOP                   (MFB_BOTTOM+MFB_SIZE_B-1)
+#define MFB_PAGE_SIZE_B           (2048)
+#define MFB_PAGE_SIZE_W           (MFB_PAGE_SIZE_B/4)
 
 #define AREA_ERROR 0x01
 #define AREA_MFB   0x04
 
-#define FLASH_WORD_LEN       4
-
 typedef struct {
        volatile uint8_t *wp;
        uint8_t *rp;
@@ -73,29 +37,29 @@ typedef struct {
 
 /* Flash Commands --------------------------------------------------------*/
 static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t address, uint8_t **data,
-                                                                uint32_t writeLength)
+                                                                uint32_t writeLength, uint32_t flash_regs_base)
 {
        uint32_t index, flash_word[4];
        uint8_t i;
 
-       *FLASH_REG_IRQMASK = 0;
+       *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQMASK)) = 0;
        for (index = 0; index < writeLength; index += (FLASH_WORD_LEN*4)) {
                for (i = 0; i < 4; i++)
                        flash_word[i] = (*(uint32_t *) (*data + i*4));
 
                /* Clear the IRQ flags */
-               *FLASH_REG_IRQRAW = 0x0000003F;
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) = 0x0000003F;
                /* Load the flash address to write */
-               *FLASH_REG_ADDRESS = (uint16_t)((address + index - MFB_BOTTOM) >> 2);
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_ADDRESS)) = (uint16_t)((address + index - MFB_BOTTOM) >> 2);
                /* Prepare and load the data to flash */
-               *FLASH_REG_DATA0 = flash_word[0];
-               *FLASH_REG_DATA1 = flash_word[1];
-               *FLASH_REG_DATA2 = flash_word[2];
-               *FLASH_REG_DATA3 = flash_word[3];
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA0)) = flash_word[0];
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA1)) = flash_word[1];
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA2)) = flash_word[2];
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA3)) = flash_word[3];
                /* Flash write command */
-               *FLASH_REG_COMMAND = FLASH_CMD_BURSTWRITE;
+               *((volatile uint32_t *)(flash_regs_base + FLASH_REG_COMMAND)) = FLASH_CMD_BURSTWRITE;
                /* Wait the end of the flash write command */
-               while ((*FLASH_REG_IRQRAW & FLASH_INT_CMDDONE) == 0)
+               while ((*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) & FLASH_INT_CMDDONE) == 0)
                        ;
                *data += (FLASH_WORD_LEN * 4);
        }
@@ -106,7 +70,8 @@ static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t addres
 __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p,
                                                            uint8_t *fifo_end,
                                                            uint8_t *target_address,
-                                                           uint32_t count)
+                                                           uint32_t count,
+                                                           uint32_t flash_regs_base)
 {
        uint32_t retval;
        volatile work_area_t *work_area = (work_area_t *) work_area_p;
@@ -134,7 +99,7 @@ __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p
                        continue;
                }
 
-               retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size);
+               retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size, flash_regs_base);
                if (retval != SUCCESS) {
                        work_area->rp = (uint8_t *)retval;
                        break;
diff --git a/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc b/contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc
new file mode 100644 (file)
index 0000000..ff05634
--- /dev/null
@@ -0,0 +1,17 @@
+/* Autogenerated with ../../../../src/helper/bin2char.sh */
+0x05,0x93,0x43,0x68,0x14,0x9e,0x09,0x93,0x05,0x9b,0x05,0x00,0x07,0x91,0x06,0x92,
+0x01,0x24,0xb1,0x46,0x00,0x2b,0x68,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0xfb,0xd0,
+0x2b,0x68,0x00,0x2b,0x61,0xd0,0x6a,0x68,0x2b,0x68,0x9a,0x42,0x5e,0xd9,0x6b,0x68,
+0x07,0x9a,0xd3,0x1a,0x0f,0x2b,0xef,0xdd,0x4a,0x46,0x00,0x21,0x03,0x93,0xd1,0x60,
+0x00,0x2b,0x42,0xd0,0x40,0x22,0x4a,0x44,0x90,0x46,0x44,0x22,0x4a,0x44,0x00,0x92,
+0x48,0x22,0x4a,0x44,0x93,0x46,0x4c,0x22,0x27,0x4f,0x4a,0x44,0xbc,0x46,0x4e,0x46,
+0x92,0x46,0x06,0x99,0x4b,0x46,0x61,0x44,0x08,0x00,0x00,0x99,0x18,0x36,0x6a,0x68,
+0x08,0x95,0x8c,0x46,0x55,0x46,0xda,0x46,0xb3,0x46,0x10,0x33,0x04,0x92,0x11,0x68,
+0x5e,0x46,0x00,0x91,0x51,0x68,0x97,0x68,0x01,0x91,0xd1,0x68,0x02,0x91,0x3f,0x21,
+0x19,0x60,0x81,0x03,0x09,0x0c,0x31,0x60,0x46,0x46,0x00,0x99,0x31,0x60,0x66,0x46,
+0x01,0x99,0x31,0x60,0x56,0x46,0x02,0x99,0x37,0x60,0x29,0x60,0xcc,0x26,0x49,0x46,
+0x0e,0x60,0x19,0x68,0x0c,0x42,0xfc,0xd0,0x04,0x99,0x03,0x9e,0x10,0x32,0x10,0x30,
+0x51,0x1a,0x8e,0x42,0xdb,0xd8,0x08,0x9d,0x6a,0x60,0x03,0x9a,0x06,0x9b,0x94,0x46,
+0x63,0x44,0x06,0x93,0x07,0x9a,0x6b,0x68,0x9a,0x42,0x01,0xd8,0x09,0x9b,0x6b,0x60,
+0x05,0x9b,0x03,0x9a,0x9b,0x1a,0x05,0x93,0x96,0xd1,0x00,0xbe,0x2b,0x68,0x6a,0x68,
+0x9b,0x1a,0x9f,0xd5,0x90,0xe7,0xc0,0x46,0x00,0x00,0xfc,0xef,
index 8bb4df6851fdd0965aa26b29e1de11ff1d6d7a22..8aab1ad941e5a8946c55c7f402737a12bc5b7bbd 100644 (file)
@@ -5842,15 +5842,7 @@ Note that when users ask to erase all the sectors of the flash, a mass erase com
 each single sector one by one.
 
 @example
-flash erase_sector 0 0 79 # It will perform a mass erase on BlueNRG-1
-@end example
-
-@example
-flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-2
-@end example
-
-@example
-flash erase_sector 0 0 127 # It will perform a mass erase on BlueNRG-LP
+flash erase_sector 0 0 last # It will perform a mass erase
 @end example
 
 Triggering a mass erase is also useful when users want to disable readout protection.
index 18b3b859b15bf3349de3002d8ff56cdec8b1f132..64c4a9079c718678c0fceb760249a46588e894fc 100644 (file)
@@ -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 \
index 79821168e460bb0907caa72f97f8508a361fc0a2..f7f5e6370967bf4fa444dcad4bf9ce3fbe0c99a1 100644 (file)
 #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 (file)
index 0000000..3b84b8b
--- /dev/null
@@ -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 */
index 691bbbf83b2744ac0276ce422a9f7295f600f84c..a9d321ee6bc1e9ea7c3c9addc5d68eca004d15f2 100644 (file)
@@ -23,13 +23,7 @@ if { [info exists WORKAREASIZE] } {
 
 adapter speed 4000
 
-if { [info exists CPUTAPID] } {
-   set _CPUTAPID $CPUTAPID
-} else {
-   set _CPUTAPID 0x0bb11477
-}
-
-swj_newdap $_CHIPNAME cpu -expected-id $_CPUTAPID
+swj_newdap $_CHIPNAME cpu -expected-id 0x0bb11477 -expected-id 0x0bc11477
 dap create $_CHIPNAME.dap -chain-position $_CHIPNAME.cpu
 
 set _TARGETNAME $_CHIPNAME.cpu

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)