1 /* To be built with arm-none-eabi-gcc -c -mthumb -mcpu=cortex-m0 -O3 bluenrgx.c */
2 /* Then postprocess output of command "arm-none-eabi-objdump -d bluenrgx.o" to make a C array of bytes */
5 #include "../../../../src/flash/nor/bluenrg-x.h"
7 /* Status Values ----------------------------------------------------------*/
9 #define ERR_UNALIGNED 1
10 #define ERR_INVALID_ADDRESS 2
11 #define ERR_INVALID_TYPE 3
12 #define ERR_WRITE_PROTECTED 4
13 #define ERR_WRITE_FAILED 5
14 #define ERR_ERASE_REQUIRED 6
15 #define ERR_VERIFY_FAILED 7
17 #define MFB_MASS_ERASE 0x01
18 #define MFB_PAGE_ERASE 0x02
20 #define DO_ERASE 0x0100
21 #define DO_VERIFY 0x0200
23 #define MFB_BOTTOM (0x10040000)
24 #define MFB_SIZE_B(regs_base) ((16 * (((*(volatile uint32_t *)(regs_base + FLASH_SIZE_REG)) + 1) >> 12)) * 1024)
25 #define MFB_SIZE_W (MFB_SIZE_B/4)
26 #define MFB_TOP (MFB_BOTTOM+MFB_SIZE_B-1)
27 #define MFB_PAGE_SIZE_B (2048)
28 #define MFB_PAGE_SIZE_W (MFB_PAGE_SIZE_B/4)
30 #define AREA_ERROR 0x01
38 /* Flash Commands --------------------------------------------------------*/
39 static inline __attribute__((always_inline)) uint32_t flashWrite(uint32_t address, uint8_t **data,
40 uint32_t writeLength, uint32_t flash_regs_base)
42 uint32_t index, flash_word[4];
45 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQMASK)) = 0;
46 for (index = 0; index < writeLength; index += (FLASH_WORD_LEN*4)) {
47 for (i = 0; i < 4; i++)
48 flash_word[i] = (*(uint32_t *) (*data + i*4));
50 /* Clear the IRQ flags */
51 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) = 0x0000003F;
52 /* Load the flash address to write */
53 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_ADDRESS)) = (uint16_t)((address + index - MFB_BOTTOM) >> 2);
54 /* Prepare and load the data to flash */
55 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA0)) = flash_word[0];
56 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA1)) = flash_word[1];
57 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA2)) = flash_word[2];
58 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_DATA3)) = flash_word[3];
59 /* Flash write command */
60 *((volatile uint32_t *)(flash_regs_base + FLASH_REG_COMMAND)) = FLASH_CMD_BURSTWRITE;
61 /* Wait the end of the flash write command */
62 while ((*((volatile uint32_t *)(flash_regs_base + FLASH_REG_IRQRAW)) & FLASH_INT_CMDDONE) == 0)
64 *data += (FLASH_WORD_LEN * 4);
70 __attribute__((naked)) __attribute__((noreturn)) void write(uint8_t *work_area_p,
72 uint8_t *target_address,
74 uint32_t flash_regs_base)
77 volatile work_area_t *work_area = (work_area_t *) work_area_p;
78 uint8_t *fifo_start = (uint8_t *) work_area->rp;
81 volatile int32_t fifo_linear_size;
83 /* Wait for some data in the FIFO */
84 while (work_area->rp == work_area->wp)
86 if (work_area->wp == 0) {
87 /* Aborted by other party */
90 if (work_area->rp > work_area->wp) {
91 fifo_linear_size = fifo_end-work_area->rp;
93 fifo_linear_size = (work_area->wp - work_area->rp);
94 if (fifo_linear_size < 0)
97 if (fifo_linear_size < 16) {
98 /* We should never get here */
102 retval = flashWrite((uint32_t) target_address, (uint8_t **) &work_area->rp, fifo_linear_size, flash_regs_base);
103 if (retval != SUCCESS) {
104 work_area->rp = (uint8_t *)retval;
107 target_address += fifo_linear_size;
108 if (work_area->rp >= fifo_end)
109 work_area->rp = fifo_start;
110 count -= fifo_linear_size;