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 BLUENRG2_IDCODE (0x0200A041)
29 #define BLUENRGLP_IDCODE (0x0201E041)
30 #define BLUENRG2_JTAG_REG (flash_priv_data_2.jtag_idcode_reg)
31 #define BLUENRGLP_JTAG_REG (flash_priv_data_lp.jtag_idcode_reg)
33 #define FLASH_SIZE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_size_reg)
34 #define DIE_ID_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->die_id_reg)
35 #define JTAG_IDCODE_REG(bluenrgx_info) (bluenrgx_info->flash_ptr->jtag_idcode_reg)
36 #define FLASH_BASE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_base)
37 #define FLASH_PAGE_SIZE(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_page_size)
38 #define FLASH_REG_COMMAND(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_command)
39 #define FLASH_REG_IRQRAW(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_irqraw)
40 #define FLASH_REG_ADDRESS(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_address)
41 #define FLASH_REG_DATA(bluenrgx_info) (bluenrgx_info->flash_ptr->flash_reg_data)
42 #define FLASH_CMD_ERASE_PAGE 0x11
43 #define FLASH_CMD_MASSERASE 0x22
44 #define FLASH_CMD_WRITE 0x33
45 #define FLASH_CMD_BURSTWRITE 0xCC
46 #define FLASH_INT_CMDDONE 0x01
47 #define FLASH_WORD_LEN 4
49 /* See contrib/loaders/flash/bluenrg-x/bluenrg-x_write.c for source and
50 * hints how to generate the data!
52 static const uint8_t bluenrgx_flash_write_code_2[] = {
53 #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-2_write.inc"
56 static const uint8_t bluenrgx_flash_write_code_lp[] = {
57 #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-lp_write.inc"
60 struct flash_ctrl_priv_data {
61 uint32_t flash_size_reg;
63 uint32_t jtag_idcode_reg;
65 uint32_t flash_page_size;
66 uint32_t flash_reg_command;
67 uint32_t flash_reg_irqraw;
68 uint32_t flash_reg_address;
69 uint32_t flash_reg_data;
72 const uint8_t *flash_write_code;
73 uint32_t flash_write_code_size;
76 const struct flash_ctrl_priv_data flash_priv_data_1 = {
77 .flash_size_reg = 0x40100014,
78 .die_id_reg = 0x4090001C,
79 .jtag_idcode_reg = 0x40900028,
80 .flash_base = 0x10040000,
81 .flash_page_size = 2048,
82 .flash_reg_command = 0x40100000,
83 .flash_reg_irqraw = 0x40100010,
84 .flash_reg_address = 0x40100018,
85 .flash_reg_data = 0x40100040,
86 .jtag_idcode = 0x00000000,
87 .part_name = "BLUENRG-1",
88 .flash_write_code = bluenrgx_flash_write_code_2,
89 .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
92 const struct flash_ctrl_priv_data flash_priv_data_2 = {
93 .flash_size_reg = 0x40100014,
94 .die_id_reg = 0x4090001C,
95 .jtag_idcode_reg = 0x40900028,
96 .flash_base = 0x10040000,
97 .flash_page_size = 2048,
98 .flash_reg_command = 0x40100000,
99 .flash_reg_irqraw = 0x40100010,
100 .flash_reg_address = 0x40100018,
101 .flash_reg_data = 0x40100040,
102 .jtag_idcode = BLUENRG2_IDCODE,
103 .part_name = "BLUENRG-2",
104 .flash_write_code = bluenrgx_flash_write_code_2,
105 .flash_write_code_size = sizeof(bluenrgx_flash_write_code_2),
108 const struct flash_ctrl_priv_data flash_priv_data_lp = {
109 .flash_size_reg = 0x40001014,
110 .die_id_reg = 0x40000000,
111 .jtag_idcode_reg = 0x40000004,
112 .flash_base = 0x10040000,
113 .flash_page_size = 2048,
114 .flash_reg_command = 0x40001000,
115 .flash_reg_irqraw = 0x40001010,
116 .flash_reg_address = 0x40001018,
117 .flash_reg_data = 0x40001040,
118 .jtag_idcode = BLUENRGLP_IDCODE,
119 .part_name = "BLUENRG-LP",
120 .flash_write_code = bluenrgx_flash_write_code_lp,
121 .flash_write_code_size = sizeof(bluenrgx_flash_write_code_lp),
124 struct bluenrgx_flash_bank {
127 const struct flash_ctrl_priv_data *flash_ptr;
128 const uint8_t *flash_write_code;
129 uint32_t flash_write_code_size;
132 const struct flash_ctrl_priv_data *flash_ctrl[] = {&flash_priv_data_1, &flash_priv_data_2, &flash_priv_data_lp};
134 static int bluenrgx_protect_check(struct flash_bank *bank)
136 /* Nothing to do. Protection is only handled in SW. */
140 /* flash_bank bluenrg-x 0 0 0 0 <target#> */
141 FLASH_BANK_COMMAND_HANDLER(bluenrgx_flash_bank_command)
143 struct bluenrgx_flash_bank *bluenrgx_info;
144 /* Create the bank structure */
145 bluenrgx_info = calloc(1, sizeof(*bluenrgx_info));
147 /* Check allocation */
148 if (bluenrgx_info == NULL) {
149 LOG_ERROR("failed to allocate bank structure");
153 bank->driver_priv = bluenrgx_info;
155 bluenrgx_info->probed = 0;
158 return ERROR_COMMAND_SYNTAX_ERROR;
163 static int bluenrgx_erase(struct flash_bank *bank, int first, int last)
165 int retval = ERROR_OK;
166 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
167 int num_sectors = (last - first + 1);
168 int mass_erase = (num_sectors == bank->num_sectors);
169 struct target *target = bank->target;
170 uint32_t address, command;
172 /* check preconditions */
173 if (bluenrgx_info->probed == 0)
174 return ERROR_FLASH_BANK_NOT_PROBED;
176 if (bank->target->state != TARGET_HALTED) {
177 LOG_ERROR("Target not halted");
178 return ERROR_TARGET_NOT_HALTED;
180 /* Disable blue module */
181 if (target_write_u32(target, 0x200000c0, 0) != ERROR_OK) {
182 LOG_ERROR("Blue disable failed");
187 command = FLASH_CMD_MASSERASE;
188 address = bank->base;
189 if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
190 LOG_ERROR("Register write failed");
194 if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
195 (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
196 LOG_ERROR("Register write failed");
200 if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
201 LOG_ERROR("Register write failed");
205 for (int i = 0; i < 100; i++) {
207 if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
208 LOG_ERROR("Register write failed");
211 if (value & FLASH_INT_CMDDONE)
214 LOG_ERROR("Mass erase command failed (timeout)");
220 command = FLASH_CMD_ERASE_PAGE;
221 for (int i = first; i <= last; i++) {
222 address = bank->base+i*FLASH_PAGE_SIZE(bluenrgx_info);
223 LOG_DEBUG("address = %08x, index = %d", address, i);
225 if (target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f) != ERROR_OK) {
226 LOG_ERROR("Register write failed");
230 if (target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
231 (address - FLASH_BASE(bluenrgx_info)) >> 2) != ERROR_OK) {
232 LOG_ERROR("Register write failed");
236 if (target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), command) != ERROR_OK) {
241 for (int j = 0; j < 100; j++) {
243 if (target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), &value)) {
244 LOG_ERROR("Register write failed");
247 if (value & FLASH_INT_CMDDONE)
250 LOG_ERROR("Erase command failed (timeout)");
261 static int bluenrgx_protect(struct flash_bank *bank, int set, int first, int last)
263 /* Protection is only handled in software: no hardware write protection
264 available in BlueNRG-x devices */
267 for (sector = first; sector <= last; sector++)
268 bank->sectors[sector].is_protected = set;
272 static int bluenrgx_write_word(struct flash_bank *bank, uint32_t address_base, uint8_t *values, uint32_t count)
274 int retval = ERROR_OK;
275 struct target *target = bank->target;
276 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
278 retval = target_write_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), 0x3f);
279 if (retval != ERROR_OK) {
280 LOG_ERROR("Register write failed, error code: %d", retval);
284 for (uint32_t i = 0; i < count; i++) {
285 uint32_t address = address_base + i * FLASH_WORD_LEN;
287 retval = target_write_u32(target, FLASH_REG_ADDRESS(bluenrgx_info),
288 (address - FLASH_BASE(bluenrgx_info)) >> 2);
289 if (retval != ERROR_OK) {
290 LOG_ERROR("Register write failed, error code: %d", retval);
294 retval = target_write_buffer(target, FLASH_REG_DATA(bluenrgx_info),
295 FLASH_WORD_LEN, values + i * FLASH_WORD_LEN);
296 if (retval != ERROR_OK) {
297 LOG_ERROR("Register write failed, error code: %d", retval);
301 retval = target_write_u32(target, FLASH_REG_COMMAND(bluenrgx_info), FLASH_CMD_WRITE);
302 if (retval != ERROR_OK) {
303 LOG_ERROR("Register write failed, error code: %d", retval);
307 for (int j = 0; j < 100; j++) {
309 retval = target_read_u32(target, FLASH_REG_IRQRAW(bluenrgx_info), ®_value);
311 if (retval != ERROR_OK) {
312 LOG_ERROR("Register read failed, error code: %d", retval);
316 if (reg_value & FLASH_INT_CMDDONE)
320 LOG_ERROR("Write command failed (timeout)");
328 static int bluenrgx_write_bytes(struct flash_bank *bank, uint32_t address_base, uint8_t *buffer, uint32_t count)
330 int retval = ERROR_OK;
331 struct target *target = bank->target;
332 uint8_t *new_buffer = NULL;
333 uint32_t pre_bytes = 0, post_bytes = 0, pre_word, post_word, pre_address, post_address;
336 /* Just return if there are no bytes to write */
340 if (address_base & 3) {
341 pre_bytes = address_base & 3;
342 pre_address = address_base - pre_bytes;
345 if ((count + pre_bytes) & 3) {
346 post_bytes = ((count + pre_bytes + 3) & ~3) - (count + pre_bytes);
347 post_address = (address_base + count) & ~3;
350 if (pre_bytes || post_bytes) {
351 uint32_t old_count = count;
353 count = old_count + pre_bytes + post_bytes;
355 new_buffer = malloc(count);
357 if (new_buffer == NULL) {
358 LOG_ERROR("odd number of bytes to write and no memory "
359 "for padding buffer");
363 LOG_INFO("Requested number of bytes to write and/or address not word aligned (%" PRIu32 "), extending to %"
364 PRIu32 " ", old_count, count);
367 if (target_read_u32(target, pre_address, &pre_word)) {
368 LOG_ERROR("Memory read failed");
376 if (target_read_u32(target, post_address, &post_word)) {
377 LOG_ERROR("Memory read failed");
384 memcpy(new_buffer, &pre_word, pre_bytes);
385 memcpy((new_buffer+((pre_bytes+old_count) & ~3)), &post_word, 4);
386 memcpy(new_buffer+pre_bytes, buffer, old_count);
390 retval = bluenrgx_write_word(bank, address_base - pre_bytes, buffer, count/4);
398 static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer,
399 uint32_t offset, uint32_t count)
401 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
402 struct target *target = bank->target;
403 uint32_t buffer_size = 16384 + 8;
404 struct working_area *write_algorithm;
405 struct working_area *write_algorithm_sp;
406 struct working_area *source;
407 uint32_t address = bank->base + offset;
408 struct reg_param reg_params[5];
409 struct armv7m_algorithm armv7m_info;
410 int retval = ERROR_OK;
411 uint32_t pre_size = 0, fast_size = 0, post_size = 0;
412 uint32_t pre_offset = 0, fast_offset = 0, post_offset = 0;
414 /* check preconditions */
415 if (bluenrgx_info->probed == 0)
416 return ERROR_FLASH_BANK_NOT_PROBED;
418 if ((offset + count) > bank->size) {
419 LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %d, size=%d",
422 return ERROR_FLASH_DST_OUT_OF_BANK;
425 if (bank->target->state != TARGET_HALTED) {
426 LOG_ERROR("Target not halted");
427 return ERROR_TARGET_NOT_HALTED;
430 /* We are good here and we need to compute pre_size, fast_size, post_size */
431 pre_size = MIN(count, ((offset+0xF) & ~0xF) - offset);
433 fast_size = 16*((count - pre_size) / 16);
434 fast_offset = offset + pre_size;
435 post_size = (count-pre_size-fast_size) % 16;
436 post_offset = fast_offset + fast_size;
438 LOG_DEBUG("pre_size = %08x, pre_offset=%08x", pre_size, pre_offset);
439 LOG_DEBUG("fast_size = %08x, fast_offset=%08x", fast_size, fast_offset);
440 LOG_DEBUG("post_size = %08x, post_offset=%08x", post_size, post_offset);
442 /* Program initial chunk not 16 bytes aligned */
443 retval = bluenrgx_write_bytes(bank, bank->base+pre_offset, (uint8_t *) buffer, pre_size);
445 LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
449 /* Program chunk 16 bytes aligned in fast mode */
452 if (target_alloc_working_area(target, bluenrgx_info->flash_write_code_size,
453 &write_algorithm) != ERROR_OK) {
454 LOG_WARNING("no working area available, can't do block memory writes");
455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
458 retval = target_write_buffer(target, write_algorithm->address,
459 bluenrgx_info->flash_write_code_size,
460 bluenrgx_info->flash_write_code);
461 if (retval != ERROR_OK)
465 if (target_alloc_working_area(target, buffer_size, &source)) {
466 LOG_WARNING("no large enough working area available");
467 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
470 /* Stack pointer area */
471 if (target_alloc_working_area(target, 64,
472 &write_algorithm_sp) != ERROR_OK) {
473 LOG_DEBUG("no working area for write code stack pointer");
474 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
477 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
478 armv7m_info.core_mode = ARM_MODE_THREAD;
480 init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
481 init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
482 init_reg_param(®_params[2], "r2", 32, PARAM_OUT);
483 init_reg_param(®_params[3], "r3", 32, PARAM_OUT);
484 init_reg_param(®_params[4], "sp", 32, PARAM_OUT);
486 /* FIFO start address (first two words used for write and read pointers) */
487 buf_set_u32(reg_params[0].value, 0, 32, source->address);
488 /* FIFO end address (first two words used for write and read pointers) */
489 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
490 /* Flash memory address */
491 buf_set_u32(reg_params[2].value, 0, 32, address+pre_size);
492 /* Number of bytes */
493 buf_set_u32(reg_params[3].value, 0, 32, fast_size);
494 /* Stack pointer for program working area */
495 buf_set_u32(reg_params[4].value, 0, 32, write_algorithm_sp->address);
497 LOG_DEBUG("source->address = " TARGET_ADDR_FMT, source->address);
498 LOG_DEBUG("source->address+ source->size = " TARGET_ADDR_FMT, source->address+source->size);
499 LOG_DEBUG("write_algorithm_sp->address = " TARGET_ADDR_FMT, write_algorithm_sp->address);
500 LOG_DEBUG("address = %08x", address+pre_size);
501 LOG_DEBUG("count = %08x", count);
503 retval = target_run_flash_async_algorithm(target,
506 16, /* Block size: we write in block of 16 bytes to enjoy burstwrite speed */
513 write_algorithm->address,
517 if (retval == ERROR_FLASH_OPERATION_FAILED) {
518 LOG_ERROR("error executing bluenrg-x flash write algorithm");
520 uint32_t error = buf_get_u32(reg_params[0].value, 0, 32);
523 LOG_ERROR("flash write failed = %08" PRIx32, error);
525 if (retval == ERROR_OK) {
527 /* Read back rp and check that is valid */
528 retval = target_read_u32(target, source->address+4, &rp);
529 if (retval == ERROR_OK) {
530 if ((rp < source->address+8) || (rp > (source->address + source->size))) {
531 LOG_ERROR("flash write failed = %08" PRIx32, rp);
532 retval = ERROR_FLASH_OPERATION_FAILED;
536 target_free_working_area(target, source);
537 target_free_working_area(target, write_algorithm);
538 target_free_working_area(target, write_algorithm_sp);
540 destroy_reg_param(®_params[0]);
541 destroy_reg_param(®_params[1]);
542 destroy_reg_param(®_params[2]);
543 destroy_reg_param(®_params[3]);
544 destroy_reg_param(®_params[4]);
545 if (retval != ERROR_OK)
550 /* Program chunk at end, not addressable by fast burst write algorithm */
551 retval = bluenrgx_write_bytes(bank, bank->base+post_offset,
552 (uint8_t *) (buffer+pre_size+fast_size), post_size);
554 LOG_ERROR("bluenrgx_write_bytes failed %d", retval);
560 static int bluenrgx_probe(struct flash_bank *bank)
562 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
563 uint32_t idcode, size_info, die_id;
565 int retval = target_read_u32(bank->target, BLUENRGLP_JTAG_REG, &idcode);
567 if (retval != ERROR_OK)
570 if (idcode != BLUENRGLP_IDCODE) {
571 retval = target_read_u32(bank->target, BLUENRG2_JTAG_REG, &idcode);
572 if (retval != ERROR_OK)
576 /* Default device is BlueNRG-1 */
577 bluenrgx_info->flash_ptr = &flash_priv_data_1;
578 bluenrgx_info->flash_write_code = flash_priv_data_1.flash_write_code;
579 bluenrgx_info->flash_write_code_size = flash_priv_data_1.flash_write_code_size;
581 for (i = 0; i < (int)(sizeof(flash_ctrl)/sizeof(*flash_ctrl)); i++) {
582 if (idcode == (*flash_ctrl[i]).jtag_idcode) {
583 bluenrgx_info->flash_ptr = flash_ctrl[i];
584 bluenrgx_info->flash_write_code = (*flash_ctrl[i]).flash_write_code;
585 bluenrgx_info->flash_write_code_size = (*flash_ctrl[i]).flash_write_code_size;
590 retval = target_read_u32(bank->target, FLASH_SIZE_REG(bluenrgx_info), &size_info);
591 if (retval != ERROR_OK)
594 retval = target_read_u32(bank->target, DIE_ID_REG(bluenrgx_info), &die_id);
595 if (retval != ERROR_OK)
598 bank->size = (size_info + 1) * FLASH_WORD_LEN;
599 bank->base = FLASH_BASE(bluenrgx_info);
600 bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info);
601 bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors);
603 for (i = 0; i < bank->num_sectors; i++) {
604 bank->sectors[i].offset = i * FLASH_PAGE_SIZE(bluenrgx_info);
605 bank->sectors[i].size = FLASH_PAGE_SIZE(bluenrgx_info);
606 bank->sectors[i].is_erased = -1;
607 bank->sectors[i].is_protected = 0;
610 bluenrgx_info->probed = 1;
611 bluenrgx_info->die_id = die_id;
616 static int bluenrgx_auto_probe(struct flash_bank *bank)
618 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
620 if (bluenrgx_info->probed)
623 return bluenrgx_probe(bank);
626 /* This method must return a string displaying information about the bank */
627 static int bluenrgx_get_info(struct flash_bank *bank, char *buf, int buf_size)
629 struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv;
630 int mask_number, cut_number;
632 if (!bluenrgx_info->probed) {
633 int retval = bluenrgx_probe(bank);
634 if (retval != ERROR_OK) {
635 snprintf(buf, buf_size,
636 "Unable to find bank information.");
641 mask_number = (bluenrgx_info->die_id >> 4) & 0xF;
642 cut_number = bluenrgx_info->die_id & 0xF;
644 snprintf(buf, buf_size,
645 "%s - Rev: %d.%d", bluenrgx_info->flash_ptr->part_name, mask_number, cut_number);
649 const struct flash_driver bluenrgx_flash = {
651 .flash_bank_command = bluenrgx_flash_bank_command,
652 .erase = bluenrgx_erase,
653 .protect = bluenrgx_protect,
654 .write = bluenrgx_write,
655 .read = default_flash_read,
656 .probe = bluenrgx_probe,
657 .erase_check = default_flash_blank_check,
658 .protect_check = bluenrgx_protect_check,
659 .auto_probe = bluenrgx_auto_probe,
660 .info = bluenrgx_get_info,