From: openocd-gerrit <ope...@us...> - 2025-06-13 16:23:53
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 2da332fa83b1aa55a61a44e6fe4d2089a9bb34b9 (commit) from 37a0f013f8893ae5041136900a2198ef16d38226 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 2da332fa83b1aa55a61a44e6fe4d2089a9bb34b9 Author: HAOUES Ahmed <ahm...@st...> Date: Tue May 27 11:42:42 2025 +0100 flash/bluenrg-x: support programming without loader fallback programming without loader when resources are not available while at there refactor reused code (wait for interrupt and command execution) Change-Id: I2cba0f53d3470bc324f4a72614c236cebf196f64 Signed-off-by: BOCHKATI Tarek <tar...@st...> Signed-off-by: HAOUES Ahmed <ahm...@st...> Reviewed-on: https://review.openocd.org/c/openocd/+/8883 Tested-by: jenkins Reviewed-by: Antonio Borneo <bor...@gm...> diff --git a/src/flash/nor/bluenrg-x.c b/src/flash/nor/bluenrg-x.c index a953e9b28..ccbbcc66e 100644 --- a/src/flash/nor/bluenrg-x.c +++ b/src/flash/nor/bluenrg-x.c @@ -143,8 +143,45 @@ static inline int bluenrgx_write_flash_reg(struct flash_bank *bank, uint32_t reg return target_write_u32(bank->target, bluenrgx_get_flash_reg(bank, reg_offset), value); } -static int bluenrgx_erase(struct flash_bank *bank, unsigned int first, - unsigned int last) +static int bluenrgx_wait_for_interrupt(struct flash_bank *bank, uint32_t interrupt_flag) +{ + bool flag_raised = false; + for (unsigned int j = 0; j < 100; j++) { + uint32_t value; + if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value) != ERROR_OK) { + LOG_ERROR("Register read failed"); + return ERROR_FAIL; + } + + if (value & interrupt_flag) { + flag_raised = true; + break; + } + } + + /* clear the interrupt */ + if (flag_raised) { + if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, interrupt_flag) != ERROR_OK) { + LOG_ERROR("Cannot clear interrupt flag"); + return ERROR_FAIL; + } + + return ERROR_OK; + } + + LOG_ERROR("Erase command failed (timeout)"); + return ERROR_TIMEOUT_REACHED; +} + +static inline int bluenrgx_wait_for_command(struct flash_bank *bank) +{ + if (bluenrgx_wait_for_interrupt(bank, FLASH_INT_CMDSTART) == ERROR_OK) + return bluenrgx_wait_for_interrupt(bank, FLASH_INT_CMDDONE); + + return ERROR_FAIL; +} + +static int bluenrgx_erase(struct flash_bank *bank, unsigned int first, unsigned int last) { int retval = ERROR_OK; struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; @@ -186,19 +223,8 @@ static int bluenrgx_erase(struct flash_bank *bank, unsigned int first, return ERROR_FAIL; } - for (unsigned int i = 0; i < 100; i++) { - uint32_t value; - if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { - LOG_ERROR("Register write failed"); - return ERROR_FAIL; - } - if (value & FLASH_INT_CMDDONE) - break; - if (i == 99) { - LOG_ERROR("Mass erase command failed (timeout)"); - retval = ERROR_FAIL; - } - } + if (bluenrgx_wait_for_command(bank) != ERROR_OK) + return ERROR_FAIL; } else { command = FLASH_CMD_ERASE_PAGE; @@ -222,19 +248,8 @@ static int bluenrgx_erase(struct flash_bank *bank, unsigned int first, return ERROR_FAIL; } - for (unsigned int j = 0; j < 100; j++) { - uint32_t value; - if (bluenrgx_read_flash_reg(bank, FLASH_REG_IRQRAW, &value)) { - LOG_ERROR("Register write failed"); - return ERROR_FAIL; - } - if (value & FLASH_INT_CMDDONE) - break; - if (j == 99) { - LOG_ERROR("Erase command failed (timeout)"); - retval = ERROR_FAIL; - } - } + if (bluenrgx_wait_for_command(bank) != ERROR_OK) + return ERROR_FAIL; } } @@ -242,7 +257,7 @@ static int bluenrgx_erase(struct flash_bank *bank, unsigned int first, } -static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, +static int bluenrgx_write_with_loader(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; @@ -264,22 +279,6 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, #include "../../../contrib/loaders/flash/bluenrg-x/bluenrg-x_write.inc" }; - /* check preconditions */ - if (!bluenrgx_info->probed) - return ERROR_FLASH_BANK_NOT_PROBED; - - if ((offset + count) > bank->size) { - LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %" PRIu32 ", size=%" PRIu32, - (offset + count), - bank->size); - return ERROR_FLASH_DST_OUT_OF_BANK; - } - - if (bank->target->state != TARGET_HALTED) { - LOG_ERROR("Target not halted"); - return ERROR_TARGET_NOT_HALTED; - } - 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"); @@ -366,6 +365,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, 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 */ @@ -377,6 +377,7 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, } } } + target_free_working_area(target, source); target_free_working_area(target, write_algorithm); target_free_working_area(target, write_algorithm_stack); @@ -391,6 +392,80 @@ static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, return retval; } +static int bluenrgx_write_without_loader(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + unsigned int data_count = count / FLASH_DATA_WIDTH; + + while (data_count--) { + /* clear flags */ + if (bluenrgx_write_flash_reg(bank, FLASH_REG_IRQRAW, 0x3f) != ERROR_OK) { + LOG_ERROR("Register write failed"); + return ERROR_FAIL; + } + + if (bluenrgx_write_flash_reg(bank, FLASH_REG_ADDRESS, offset >> 2) != ERROR_OK) { + LOG_ERROR("Register write failed"); + return ERROR_FAIL; + } + + if (target_write_memory(target, bluenrgx_get_flash_reg(bank, FLASH_REG_DATA0), + FLASH_WORD_LEN, FLASH_DATA_WIDTH_W, buffer) != ERROR_OK) { + LOG_ERROR("Failed to write data"); + return ERROR_FAIL; + } + + if (bluenrgx_write_flash_reg(bank, FLASH_REG_COMMAND, FLASH_CMD_BURSTWRITE) != ERROR_OK) { + LOG_ERROR("Failed"); + return ERROR_FAIL; + } + + if (bluenrgx_wait_for_command(bank) != ERROR_OK) + return ERROR_FAIL; + + /* increment offset, and buffer */ + offset += FLASH_DATA_WIDTH; + buffer += FLASH_DATA_WIDTH; + } + + return ERROR_OK; +} + +static int bluenrgx_write(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; + int retval = ERROR_OK; + + /* check preconditions */ + if (!bluenrgx_info->probed) + return ERROR_FLASH_BANK_NOT_PROBED; + + if ((offset + count) > bank->size) { + LOG_ERROR("Requested write past beyond of flash size: (offset+count) = %" PRIu32 ", size=%" PRIu32, + (offset + count), + bank->size); + return ERROR_FLASH_DST_OUT_OF_BANK; + } + + if (bank->target->state != TARGET_HALTED) { + LOG_ERROR("Target not halted"); + return ERROR_TARGET_NOT_HALTED; + } + + assert(offset % FLASH_WORD_LEN == 0); + assert(count % FLASH_WORD_LEN == 0); + + retval = bluenrgx_write_with_loader(bank, buffer, offset, count); + /* if resources are not available write without a loader */ + if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { + LOG_WARNING("falling back to programming without a flash loader (slower)"); + retval = bluenrgx_write_without_loader(bank, buffer, offset, count); + } + return retval; +} + static int bluenrgx_probe(struct flash_bank *bank) { struct bluenrgx_flash_bank *bluenrgx_info = bank->driver_priv; @@ -428,7 +503,7 @@ static int bluenrgx_probe(struct flash_bank *bank) return retval; bank->size = (size_info + 1) * FLASH_WORD_LEN; - bank->num_sectors = bank->size/FLASH_PAGE_SIZE(bluenrgx_info); + bank->num_sectors = bank->size / FLASH_PAGE_SIZE(bluenrgx_info); bank->sectors = realloc(bank->sectors, sizeof(struct flash_sector) * bank->num_sectors); for (unsigned int i = 0; i < bank->num_sectors; i++) { diff --git a/src/flash/nor/bluenrg-x.h b/src/flash/nor/bluenrg-x.h index 720cb6e61..03c66cd81 100644 --- a/src/flash/nor/bluenrg-x.h +++ b/src/flash/nor/bluenrg-x.h @@ -28,7 +28,12 @@ #define FLASH_CMD_WRITE 0x33 #define FLASH_CMD_BURSTWRITE 0xCC #define FLASH_INT_CMDDONE 0x01 +#define FLASH_INT_CMDSTART 0x02 +/* Flash Controller constants */ #define FLASH_WORD_LEN 4 +#define FLASH_DATA_WIDTH_W 4 +#define FLASH_DATA_WIDTH 16 + #endif /* OPENOCD_FLASH_NOR_BLUENRGX_H */ ----------------------------------------------------------------------- Summary of changes: src/flash/nor/bluenrg-x.c | 167 +++++++++++++++++++++++++++++++++------------- src/flash/nor/bluenrg-x.h | 5 ++ 2 files changed, 126 insertions(+), 46 deletions(-) hooks/post-receive -- Main OpenOCD repository |