1 /***************************************************************************
2 * Copyright (C) 2017 by Michele Sardo *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
23 #include <target/algorithm.h>
24 #include <target/armv7m.h>
25 #include <target/cortex_m.h>
28 #define FLASH_SIZE_REG (0x40100014)
29 #define DIE_ID_REG (0x4090001C)
30 #define JTAG_IDCODE_REG (0x40900028)
31 #define BLUENRG2_IDCODE (0x0200A041)
32 #define FLASH_BASE (0x10040000)
33 #define FLASH_PAGE_SIZE (2048)
34 #define FLASH_REG_COMMAND (0x40100000)
35 #define FLASH_REG_IRQRAW (0x40100010)
36 #define FLASH_REG_ADDRESS (0x40100018)
37 #define FLASH_REG_DATA (0x40100040)
38 #define FLASH_CMD_ERASE_PAGE 0x11
39 #define FLASH_CMD_MASSERASE 0x22
40 #define FLASH_CMD_WRITE 0x33
41 #define FLASH_CMD_BURSTWRITE 0xCC
42 #define FLASH_INT_CMDDONE 0x01
43 #define FLASH_WORD_LEN 4
45 struct bluenrgx_flash_bank
{
51 static int bluenrgx_protect_check(struct flash_bank
*bank
)
53 /* Nothing to do. Protection is only handled in SW. */
57 /* flash_bank bluenrg-x 0 0 0 0 <target#> */
58 FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command
)
60 struct bluenrgx_flash_bank
*bluenrgx_info
;
61 /* Create the bank structure */
62 bluenrgx_info
= calloc(1, sizeof(*bluenrgx_info
));
64 /* Check allocation */
65 if (bluenrgx_info
== NULL
) {
66 LOG_ERROR("failed to allocate bank structure");
70 bank
->driver_priv
= bluenrgx_info
;
72 bluenrgx_info
->probed
= 0;
75 return ERROR_COMMAND_SYNTAX_ERROR
;
80 static int bluenrgx_erase(struct flash_bank
*bank
, int first
, int last
)
82 int retval
= ERROR_OK
;
83 struct bluenrgx_flash_bank
*bluenrgx_info
= bank
->driver_priv
;
84 int num_sectors
= (last
- first
+ 1);
85 int mass_erase
= (num_sectors
== bank
->num_sectors
);
86 struct target
*target
= bank
->target
;
87 uint32_t address
, command
;
89 /* check preconditions */
90 if (bluenrgx_info
->probed
== 0)
91 return ERROR_FLASH_BANK_NOT_PROBED
;
93 if (bank
->target
->state
!= TARGET_HALTED
) {
94 LOG_ERROR("Target not halted");
95 return ERROR_TARGET_NOT_HALTED
;
97 /* Disable blue module */
98 if (target_write_u32(target
, 0x200000c0, 0) != ERROR_OK
) {
99 LOG_ERROR("Blue disable failed");
104 command
= FLASH_CMD_MASSERASE
;
105 address
= bank
->base
;
106 if (target_write_u32(target
, FLASH_REG_IRQRAW
, 0x3f) != ERROR_OK
) {
107 LOG_ERROR("Register write failed");
111 if (target_write_u32(target
, FLASH_REG_ADDRESS
, address
>> 2) != ERROR_OK
) {
112 LOG_ERROR("Register write failed");
116 if (target_write_u32(target
, FLASH_REG_COMMAND
, command
) != ERROR_OK
) {
117 LOG_ERROR("Register write failed");
121 for (int i
= 0; i
< 100; i
++) {
123 if (target_read_u32(target
, FLASH_REG_IRQRAW
, &value
)) {
124 LOG_ERROR("Register write failed");
127 if (value
& FLASH_INT_CMDDONE
)
130 LOG_ERROR("Mass erase command failed (timeout)");
136 command
= FLASH_CMD_ERASE_PAGE
;
137 for (int i
= first
; i
<= last
; i
++) {
138 address
= bank
->base
+i
*FLASH_PAGE_SIZE
;
140 if (target_write_u32(target
, FLASH_REG_IRQRAW
, 0x3f) != ERROR_OK
) {
141 LOG_ERROR("Register write failed");
145 if (target_write_u32(target
, FLASH_REG_ADDRESS
, address
>> 2) != ERROR_OK
) {
146 LOG_ERROR("Register write failed");
150 if (target_write_u32(target
, FLASH_REG_COMMAND
, command
) != ERROR_OK
) {
155 for (int j
= 0; j
< 100; j
++) {
157 if (target_read_u32(target
, FLASH_REG_IRQRAW
, &value
)) {
158 LOG_ERROR("Register write failed");
161 if (value
& FLASH_INT_CMDDONE
)
164 LOG_ERROR("Erase command failed (timeout)");
175 static int bluenrgx_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
177 /* Protection is only handled in software: no hardware write protection
178 available in BlueNRG-x devices */
181 for (sector
= first
; sector
<= last
; sector
++)
182 bank
->sectors
[sector
].is_protected
= set
;
185 static int bluenrgx_write_word(struct target
*target
, uint32_t address_base
, uint8_t *values
, uint32_t count
)
187 int retval
= ERROR_OK
;
189 retval
= target_write_u32(target
, FLASH_REG_IRQRAW
, 0x3f);
190 if (retval
!= ERROR_OK
) {
191 LOG_ERROR("Register write failed, error code: %d", retval
);
195 for (uint32_t i
= 0; i
< count
; i
++) {
196 uint32_t address
= address_base
+ i
* FLASH_WORD_LEN
;
198 retval
= target_write_u32(target
, FLASH_REG_ADDRESS
, address
>> 2);
199 if (retval
!= ERROR_OK
) {
200 LOG_ERROR("Register write failed, error code: %d", retval
);
204 retval
= target_write_buffer(target
, FLASH_REG_DATA
, FLASH_WORD_LEN
, values
+ i
* FLASH_WORD_LEN
);
205 if (retval
!= ERROR_OK
) {
206 LOG_ERROR("Register write failed, error code: %d", retval
);
210 retval
= target_write_u32(target
, FLASH_REG_COMMAND
, FLASH_CMD_WRITE
);
211 if (retval
!= ERROR_OK
) {
212 LOG_ERROR("Register write failed, error code: %d", retval
);
216 for (int j
= 0; j
< 100; j
++) {
218 retval
= target_read_u32(target
, FLASH_REG_IRQRAW
, ®_value
);
220 if (retval
!= ERROR_OK
) {
221 LOG_ERROR("Register read failed, error code: %d", retval
);
225 if (reg_value
& FLASH_INT_CMDDONE
)
229 LOG_ERROR("Write command failed (timeout)");
237 static int bluenrgx_write_bytes(struct target
*target
, uint32_t address_base
, uint8_t *buffer
, uint32_t count
)
239 int retval
= ERROR_OK
;
240 uint8_t *new_buffer
= NULL
;
241 uint32_t pre_bytes
= 0, post_bytes
= 0, pre_word
, post_word
, pre_address
, post_address
;
244 /* Just return if there are no bytes to write */
248 if (address_base
& 3) {
249 pre_bytes
= address_base
& 3;
250 pre_address
= address_base
- pre_bytes
;
253 if ((count
+ pre_bytes
) & 3) {
254 post_bytes
= ((count
+ pre_bytes
+ 3) & ~3) - (count
+ pre_bytes
);
255 post_address
= (address_base
+ count
) & ~3;
258 if (pre_bytes
|| post_bytes
) {
259 uint32_t old_count
= count
;
261 count
= old_count
+ pre_bytes
+ post_bytes
;
263 new_buffer
= malloc(count
);
265 if (new_buffer
== NULL
) {
266 LOG_ERROR("odd number of bytes to write and no memory "
267 "for padding buffer");
271 LOG_INFO("Requested number of bytes to write and/or address not word aligned (%" PRIu32
"), extending to %"
272 PRIu32
" ", old_count
, count
);
275 if (target_read_u32(target
, pre_address
, &pre_word
)) {
276 LOG_ERROR("Memory read failed");
284 if (target_read_u32(target
, post_address
, &post_word
)) {
285 LOG_ERROR("Memory read failed");
292 memcpy(new_buffer
, &pre_word
, pre_bytes
);
293 memcpy((new_buffer
+((pre_bytes
+old_count
) & ~3)), &post_word
, 4);
294 memcpy(new_buffer
+pre_bytes
, buffer
, old_count
);
298 retval
= bluenrgx_write_word(target
, address_base
- pre_bytes
, buffer
, count
/4);
306 static int bluenrgx_write(struct flash_bank
*bank
, const uint8_t *buffer
,
307 uint32_t offset
, uint32_t count
)
309 struct target
*target
= bank
->target
;
310 uint32_t buffer_size
= 16384 + 8;
311 struct working_area
*write_algorithm
;
312 struct working_area
*write_algorithm_sp
;
313 struct working_area
*source
;
314 uint32_t address
= bank
->base
+ offset
;
315 struct reg_param reg_params
[5];
316 struct armv7m_algorithm armv7m_info
;
317 int retval
= ERROR_OK
;
318 uint32_t pre_size
= 0, fast_size
= 0, post_size
= 0;
319 uint32_t pre_offset
= 0, fast_offset
= 0, post_offset
= 0;
321 /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and
322 * hints how to generate the data!
324 static const uint8_t bluenrgx_flash_write_code
[] = {
325 #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc"
328 if ((offset
+ count
) > bank
->size
) {
329 LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %d, size=%d",
332 return ERROR_FLASH_DST_OUT_OF_BANK
;
335 if (bank
->target
->state
!= TARGET_HALTED
) {
336 LOG_ERROR("Target not halted");
337 return ERROR_TARGET_NOT_HALTED
;
340 /* We are good here and we need to compute pre_size, fast_size, post_size */
341 pre_size
= MIN(count
, ((offset
+0xF) & ~0xF) - offset
);
343 fast_size
= 16*((count
- pre_size
) / 16);
344 fast_offset
= offset
+ pre_size
;
345 post_size
= (count
-pre_size
-fast_size
) % 16;
346 post_offset
= fast_offset
+ fast_size
;
348 LOG_DEBUG("pre_size = %08x, pre_offset=%08x", pre_size
, pre_offset
);
349 LOG_DEBUG("fast_size = %08x, fast_offset=%08x", fast_size
, fast_offset
);
350 LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size
, post_offset
);
352 /* Program initial chunk not 16 bytes aligned */
353 retval
= bluenrgx_write_bytes(target
, bank
->base
+pre_offset
, (uint8_t *) buffer
, pre_size
);
355 LOG_ERROR("bluenrgx_write_bytes failed %d", retval
);
359 /* Program chunk 16 bytes aligned in fast mode */
362 if (target_alloc_working_area(target
, sizeof(bluenrgx_flash_write_code
),
363 &write_algorithm
) != ERROR_OK
) {
364 LOG_WARNING("no working area available, can't do block memory writes");
365 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
368 retval
= target_write_buffer(target
, write_algorithm
->address
,
369 sizeof(bluenrgx_flash_write_code
),
370 bluenrgx_flash_write_code
);
371 if (retval
!= ERROR_OK
)
375 if (target_alloc_working_area(target
, buffer_size
, &source
)) {
376 LOG_WARNING("no large enough working area available");
377 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
380 /* Stack pointer area */
381 if (target_alloc_working_area(target
, 64,
382 &write_algorithm_sp
) != ERROR_OK
) {
383 LOG_DEBUG("no working area for write code stack pointer");
384 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
387 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
388 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
390 init_reg_param(®_params
[0], "r0", 32, PARAM_IN_OUT
);
391 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
392 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
393 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
394 init_reg_param(®_params
[4], "sp", 32, PARAM_OUT
);
396 /* FIFO start address (first two words used for write and read pointers) */
397 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
398 /* FIFO end address (first two words used for write and read pointers) */
399 buf_set_u32(reg_params
[1].value
, 0, 32, source
->address
+ source
->size
);
400 /* Flash memory address */
401 buf_set_u32(reg_params
[2].value
, 0, 32, address
+pre_size
);
402 /* Number of bytes */
403 buf_set_u32(reg_params
[3].value
, 0, 32, fast_size
);
404 /* Stack pointer for program working area */
405 buf_set_u32(reg_params
[4].value
, 0, 32, write_algorithm_sp
->address
);
407 LOG_DEBUG("source->address = %08" TARGET_PRIxADDR
, source
->address
);
408 LOG_DEBUG("source->address+ source->size = %08" TARGET_PRIxADDR
, source
->address
+source
->size
);
409 LOG_DEBUG("write_algorithm_sp->address = %08" TARGET_PRIxADDR
, write_algorithm_sp
->address
);
410 LOG_DEBUG("address = %08x", address
+pre_size
);
411 LOG_DEBUG("count = %08x", count
);
413 retval
= target_run_flash_async_algorithm(target
,
416 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */
423 write_algorithm
->address
,
427 if (retval
== ERROR_FLASH_OPERATION_FAILED
) {
428 LOG_ERROR("error executing bluenrg-x flash write algorithm");
430 uint32_t error
= buf_get_u32(reg_params
[0].value
, 0, 32);
433 LOG_ERROR("flash write failed = %08" PRIx32
, error
);
435 if (retval
== ERROR_OK
) {
437 /* Read back rp and check that is valid */
438 retval
= target_read_u32(target
, source
->address
+4, &rp
);
439 if (retval
== ERROR_OK
) {
440 if ((rp
< source
->address
+8) || (rp
> (source
->address
+ source
->size
))) {
441 LOG_ERROR("flash write failed = %08" PRIx32
, rp
);
442 retval
= ERROR_FLASH_OPERATION_FAILED
;
446 target_free_working_area(target
, source
);
447 target_free_working_area(target
, write_algorithm
);
448 target_free_working_area(target
, write_algorithm_sp
);
450 destroy_reg_param(®_params
[0]);
451 destroy_reg_param(®_params
[1]);
452 destroy_reg_param(®_params
[2]);
453 destroy_reg_param(®_params
[3]);
454 destroy_reg_param(®_params
[4]);
455 if (retval
!= ERROR_OK
)
460 /* Program chunk at end, not addressable by fast burst write algorithm */
461 retval
= bluenrgx_write_bytes(target
, bank
->base
+post_offset
, (uint8_t *) (buffer
+pre_size
+fast_size
), post_size
);
463 LOG_ERROR("bluenrgx_write_bytes failed %d", retval
);
469 static int bluenrgx_probe(struct flash_bank
*bank
)
471 struct bluenrgx_flash_bank
*bluenrgx_info
= bank
->driver_priv
;
472 uint32_t idcode
, size_info
, die_id
;
474 int retval
= target_read_u32(bank
->target
, JTAG_IDCODE_REG
, &idcode
);
475 if (retval
!= ERROR_OK
)
477 retval
= target_read_u32(bank
->target
, FLASH_SIZE_REG
, &size_info
);
478 if (retval
!= ERROR_OK
)
481 retval
= target_read_u32(bank
->target
, DIE_ID_REG
, &die_id
);
482 if (retval
!= ERROR_OK
)
485 bank
->size
= (size_info
+ 1) * 4;
486 bank
->base
= FLASH_BASE
;
487 bank
->num_sectors
= bank
->size
/FLASH_PAGE_SIZE
;
488 bank
->sectors
= realloc(bank
->sectors
, sizeof(struct flash_sector
) * bank
->num_sectors
);
490 for (i
= 0; i
< bank
->num_sectors
; i
++) {
491 bank
->sectors
[i
].offset
= i
* FLASH_PAGE_SIZE
;
492 bank
->sectors
[i
].size
= FLASH_PAGE_SIZE
;
493 bank
->sectors
[i
].is_erased
= -1;
494 bank
->sectors
[i
].is_protected
= 0;
497 bluenrgx_info
->probed
= 1;
498 bluenrgx_info
->die_id
= die_id
;
499 bluenrgx_info
->idcode
= idcode
;
503 static int bluenrgx_auto_probe(struct flash_bank
*bank
)
505 struct bluenrgx_flash_bank
*bluenrgx_info
= bank
->driver_priv
;
507 if (bluenrgx_info
->probed
)
510 return bluenrgx_probe(bank
);
513 /* This method must return a string displaying information about the bank */
514 static int bluenrgx_get_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
516 struct bluenrgx_flash_bank
*bluenrgx_info
= bank
->driver_priv
;
517 int mask_number
, cut_number
;
520 if (!bluenrgx_info
->probed
) {
521 int retval
= bluenrgx_probe(bank
);
522 if (retval
!= ERROR_OK
) {
523 snprintf(buf
, buf_size
,
524 "Unable to find bank information.");
529 if (bluenrgx_info
->idcode
== BLUENRG2_IDCODE
)
530 part_name
= "BLUENRG-2";
532 part_name
= "BLUENRG-1";
534 mask_number
= (bluenrgx_info
->die_id
>> 4) & 0xF;
535 cut_number
= bluenrgx_info
->die_id
& 0xF;
537 snprintf(buf
, buf_size
,
538 "%s - Rev: %d.%d", part_name
, mask_number
, cut_number
);
542 struct flash_driver bluenrgx_flash
= {
544 .flash_bank_command
= bluenrgx_flash_bank_command
,
545 .erase
= bluenrgx_erase
,
546 .protect
= bluenrgx_protect
,
547 .write
= bluenrgx_write
,
548 .read
= default_flash_read
,
549 .probe
= bluenrgx_probe
,
550 .erase_check
= default_flash_blank_check
,
551 .protect_check
= bluenrgx_protect_check
,
552 .auto_probe
= bluenrgx_auto_probe
,
553 .info
= bluenrgx_get_info
,