bluenrg-x: simplyfied the driver
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