X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstm32h7x.c;h=72afc8542170aa6b009137ff8dfc4a7fabd63e32;hp=fcfcf9142a65d7fc5bf04ad9549cb2e7a78ade49;hb=5b06b88af849805480060a2dcc2189a13d23d76d;hpb=4999c9d98013eeb9746082f6b018e4b763ae3d37 diff --git a/src/flash/nor/stm32h7x.c b/src/flash/nor/stm32h7x.c index fcfcf9142a..72afc85421 100644 --- a/src/flash/nor/stm32h7x.c +++ b/src/flash/nor/stm32h7x.c @@ -38,18 +38,18 @@ #define FLASH_SR 0x10 #define FLASH_CCR 0x14 #define FLASH_OPTCR 0x18 -#define FLASH_OPTCUR 0x1C -#define FLASH_OPTPRG 0x20 +#define FLASH_OPTSR_CUR 0x1C +#define FLASH_OPTSR_PRG 0x20 #define FLASH_OPTCCR 0x24 -#define FLASH_WPSNCUR 0x38 -#define FLASH_WPSNPRG 0x3C +#define FLASH_WPSN_CUR 0x38 +#define FLASH_WPSN_PRG 0x3C /* FLASH_CR register bits */ #define FLASH_LOCK (1 << 0) #define FLASH_PG (1 << 1) #define FLASH_SER (1 << 2) -#define FLASH_BER_CMD (1 << 3) +#define FLASH_BER (1 << 3) #define FLASH_PSIZE_8 (0 << 4) #define FLASH_PSIZE_16 (1 << 4) #define FLASH_PSIZE_32 (2 << 4) @@ -61,6 +61,7 @@ /* FLASH_SR register bits */ #define FLASH_BSY (1 << 0) /* Operation in progress */ +#define FLASH_QW (1 << 2) /* Operation queue in progress */ #define FLASH_WRPERR (1 << 17) /* Write protection error */ #define FLASH_PGSERR (1 << 18) /* Programming sequence error */ #define FLASH_STRBERR (1 << 19) /* Strobe error */ @@ -78,9 +79,6 @@ #define OPT_LOCK (1 << 0) #define OPT_START (1 << 1) -/* FLASH_OPTCUR bit definitions (reading) */ -#define IWDG1_HW (1 << 4) - /* register unlock keys */ #define KEY1 0x45670123 #define KEY2 0xCDEF89AB @@ -109,7 +107,6 @@ struct stm32x_options { uint8_t user_options; uint8_t user2_options; uint8_t user3_options; - uint8_t independent_watchdog_selection; }; struct stm32h7x_part_info { @@ -136,7 +133,7 @@ struct stm32h7x_flash_bank { }; static const struct stm32h7x_rev stm32_450_revs[] = { - { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, + { 0x1000, "A" }, { 0x1001, "Z" }, { 0x1003, "Y" }, { 0x2001, "X" }, }; static const struct stm32h7x_part_info stm32h7x_parts[] = { @@ -144,7 +141,7 @@ static const struct stm32h7x_part_info stm32h7x_parts[] = { .id = 0x450, .revs = stm32_450_revs, .num_revs = ARRAY_SIZE(stm32_450_revs), - .device_str = "STM32H7xx 2M", + .device_str = "STM32H74x/75x", .page_size = 128, /* 128 KB */ .max_flash_size_kb = 2048, .first_bank_size_kb = 1024, @@ -188,33 +185,33 @@ static inline int stm32x_get_flash_status(struct flash_bank *bank, uint32_t *sta return target_read_u32(target, stm32x_get_flash_reg(bank, FLASH_SR), status); } -static int stm32x_wait_status_busy(struct flash_bank *bank, int timeout) +static int stm32x_wait_flash_op_queue(struct flash_bank *bank, int timeout) { struct target *target = bank->target; struct stm32h7x_flash_bank *stm32x_info = bank->driver_priv; uint32_t status; int retval; - /* wait for busy to clear */ + /* wait for flash operations completion */ for (;;) { retval = stm32x_get_flash_status(bank, &status); if (retval != ERROR_OK) { - LOG_INFO("wait_status_busy, target_read_u32 : error : remote address 0x%x", stm32x_info->flash_base); + LOG_INFO("wait_flash_op_queue, target_read_u32 : error : remote address 0x%x", stm32x_info->flash_base); return retval; } - if ((status & FLASH_BSY) == 0) + if ((status & FLASH_QW) == 0) break; if (timeout-- <= 0) { - LOG_INFO("wait_status_busy, time out expired, status: 0x%" PRIx32 "", status); + LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status); return ERROR_FAIL; } alive_sleep(1); } if (status & FLASH_WRPERR) { - LOG_INFO("wait_status_busy, WRPERR : error : remote address 0x%x", stm32x_info->flash_base); + LOG_INFO("wait_flash_op_queue, WRPERR : error : remote address 0x%x", stm32x_info->flash_base); retval = ERROR_FAIL; } @@ -317,7 +314,7 @@ static int stm32x_read_options(struct flash_bank *bank) stm32x_info = bank->driver_priv; /* read current option bytes */ - int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCUR, &optiondata); + int retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_CUR, &optiondata); if (retval != ERROR_OK) return retval; @@ -325,24 +322,19 @@ static int stm32x_read_options(struct flash_bank *bank) stm32x_info->option_bytes.user_options = optiondata & 0xfc; stm32x_info->option_bytes.RDP = (optiondata >> 8) & 0xff; stm32x_info->option_bytes.user2_options = (optiondata >> 16) & 0xff; - stm32x_info->option_bytes.user3_options = (optiondata >> 24) & 0x83; - - if (optiondata & IWDG1_HW) - stm32x_info->option_bytes.independent_watchdog_selection = 1; - else - stm32x_info->option_bytes.independent_watchdog_selection = 0; + stm32x_info->option_bytes.user3_options = (optiondata >> 24) & 0xa3; if (stm32x_info->option_bytes.RDP != 0xAA) LOG_INFO("Device Security Bit Set"); /* read current WPSN option bytes */ - retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSNCUR, &optiondata); + retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSN_CUR, &optiondata); if (retval != ERROR_OK) return retval; stm32x_info->option_bytes.protection = optiondata & 0xff; /* read current WPSN2 option bytes */ - retval = target_read_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSNCUR, &optiondata); + retval = target_read_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSN_CUR, &optiondata); if (retval != ERROR_OK) return retval; stm32x_info->option_bytes.protection2 = optiondata & 0xff; @@ -366,35 +358,30 @@ static int stm32x_write_options(struct flash_bank *bank) optiondata = stm32x_info->option_bytes.user_options; optiondata |= (stm32x_info->option_bytes.RDP << 8); optiondata |= (stm32x_info->option_bytes.user2_options & 0xff) << 16; - optiondata |= (stm32x_info->option_bytes.user3_options & 0x83) << 24; - - if (stm32x_info->option_bytes.independent_watchdog_selection) - optiondata |= IWDG1_HW; - else - optiondata &= ~IWDG1_HW; + optiondata |= (stm32x_info->option_bytes.user3_options & 0xa3) << 24; /* program options */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTPRG, optiondata); - if (retval != ERROR_OK) - return retval; + retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTSR_PRG, optiondata); + if (retval != ERROR_OK) + return retval; optiondata = stm32x_info->option_bytes.protection & 0xff; /* Program protection WPSNPRG */ - retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSNPRG, optiondata); - if (retval != ERROR_OK) - return retval; + retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_WPSN_PRG, optiondata); + if (retval != ERROR_OK) + return retval; optiondata = stm32x_info->option_bytes.protection2 & 0xff; /* Program protection WPSNPRG2 */ - retval = target_write_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSNPRG, optiondata); - if (retval != ERROR_OK) - return retval; + retval = target_write_u32(target, FLASH_REG_BASE_B1 + FLASH_WPSN_PRG, optiondata); + if (retval != ERROR_OK) + return retval; optiondata = 0x40000000; /* Remove OPT error flag before programming */ retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCCR, optiondata); - if (retval != ERROR_OK) - return retval; + if (retval != ERROR_OK) + return retval; /* start programming cycle */ retval = target_write_u32(target, FLASH_REG_BASE_B0 + FLASH_OPTCR, OPT_START); @@ -407,14 +394,14 @@ static int stm32x_write_options(struct flash_bank *bank) uint32_t status; retval = target_read_u32(target, FLASH_REG_BASE_B0 + FLASH_SR, &status); if (retval != ERROR_OK) { - LOG_INFO("stm32x_write_options: wait_status_busy : error"); + LOG_INFO("stm32x_write_options: wait_flash_op_queue : error"); return retval; } - if ((status & FLASH_BSY) == 0) + if ((status & FLASH_QW) == 0) break; if (timeout-- <= 0) { - LOG_INFO("wait_status_busy, time out expired, status: 0x%" PRIx32 "", status); + LOG_INFO("wait_flash_op_queue, time out expired, status: 0x%" PRIx32 "", status); return ERROR_FAIL; } alive_sleep(1); @@ -473,12 +460,12 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) /* Sector Erase To erase a sector, follow the procedure below: - 1. Check that no Flash memory operation is ongoing by checking the BSY bit in the + 1. Check that no Flash memory operation is ongoing by checking the QW bit in the FLASH_SR register 2. Set the SER bit and select the sector you wish to erase (SNB) in the FLASH_CR register 3. Set the STRT bit in the FLASH_CR register - 4. Wait for the BSY bit to be cleared + 4. Wait for flash operations completion */ for (int i = first; i <= last; i++) { LOG_DEBUG("erase sector %d", i); @@ -494,7 +481,7 @@ static int stm32x_erase(struct flash_bank *bank, int first, int last) LOG_ERROR("Error erase sector %d", i); return retval; } - retval = stm32x_wait_status_busy(bank, FLASH_ERASE_TIMEOUT); + retval = stm32x_wait_flash_op_queue(bank, FLASH_ERASE_TIMEOUT); if (retval != ERROR_OK) { LOG_ERROR("erase time-out or operation error sector %d", i); @@ -701,11 +688,11 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, /* Standard programming The Flash memory programming sequence is as follows: - 1. Check that no main Flash memory operation is ongoing by checking the BSY bit in the + 1. Check that no main Flash memory operation is ongoing by checking the QW bit in the FLASH_SR register. 2. Set the PG bit in the FLASH_CR register 3. 8 x Word access (or Force Write FW) - 4. Wait for the BSY bit to be cleared + 4. Wait for flash operations completion */ while (blocks_remaining > 0) { retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_PG | FLASH_PSIZE_64); @@ -716,7 +703,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) goto flash_lock; - retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); + retval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT); if (retval != ERROR_OK) goto flash_lock; @@ -739,7 +726,7 @@ static int stm32x_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) goto flash_lock; - retval = stm32x_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); + retval = stm32x_wait_flash_op_queue(bank, FLASH_WRITE_TIMEOUT); if (retval != ERROR_OK) goto flash_lock; } @@ -833,8 +820,8 @@ static int stm32x_probe(struct flash_bank *bank) /* This is the first bank */ flash_size_in_kb = stm32x_info->part_info->first_bank_size_kb; } else { - LOG_WARNING("STM32H flash bank base address config is incorrect." - " 0x%" PRIx32 " but should rather be 0x%" PRIx32 " or 0x%" PRIx32, + LOG_WARNING("STM32H flash bank base address config is incorrect. " + TARGET_ADDR_FMT " but should rather be 0x%" PRIx32 " or 0x%" PRIx32, bank->base, base_address, second_bank_base); return ERROR_FAIL; } @@ -965,7 +952,7 @@ COMMAND_HANDLER(stm32x_handle_lock_command) } if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", + command_print(CMD, "%s failed to read options", bank->driver->name); return ERROR_OK; } @@ -973,11 +960,11 @@ COMMAND_HANDLER(stm32x_handle_lock_command) stm32x_info->option_bytes.RDP = 0; if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to lock device", + command_print(CMD, "%s failed to lock device", bank->driver->name); return ERROR_OK; } - command_print(CMD_CTX, "%s locked", bank->driver->name); + command_print(CMD, "%s locked", bank->driver->name); return ERROR_OK; } @@ -1011,7 +998,7 @@ COMMAND_HANDLER(stm32x_handle_unlock_command) } if (stm32x_read_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to read options", bank->driver->name); + command_print(CMD, "%s failed to read options", bank->driver->name); return ERROR_OK; } @@ -1020,10 +1007,10 @@ COMMAND_HANDLER(stm32x_handle_unlock_command) stm32x_info->option_bytes.RDP = 0xAA; if (stm32x_write_options(bank) != ERROR_OK) { - command_print(CMD_CTX, "%s failed to unlock device", bank->driver->name); + command_print(CMD, "%s failed to unlock device", bank->driver->name); return ERROR_OK; } - command_print(CMD_CTX, "%s unlocked.\n", bank->driver->name); + command_print(CMD, "%s unlocked.\n", bank->driver->name); return ERROR_OK; } @@ -1043,16 +1030,16 @@ static int stm32x_mass_erase(struct flash_bank *bank) return retval; /* mass erase flash memory bank */ - retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_BER_CMD | FLASH_PSIZE_64); + retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), FLASH_BER | FLASH_PSIZE_64); if (retval != ERROR_OK) return retval; retval = target_write_u32(target, stm32x_get_flash_reg(bank, FLASH_CR), - FLASH_BER_CMD | FLASH_PSIZE_64 | FLASH_START); + FLASH_BER | FLASH_PSIZE_64 | FLASH_START); if (retval != ERROR_OK) return retval; - retval = stm32x_wait_status_busy(bank, 30000); + retval = stm32x_wait_flash_op_queue(bank, 30000); if (retval != ERROR_OK) return retval; @@ -1069,7 +1056,7 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) int i; if (CMD_ARGC < 1) { - command_print(CMD_CTX, "stm32h7x mass_erase "); + command_print(CMD, "stm32h7x mass_erase "); return ERROR_COMMAND_SYNTAX_ERROR; } @@ -1084,9 +1071,9 @@ COMMAND_HANDLER(stm32x_handle_mass_erase_command) for (i = 0; i < bank->num_sectors; i++) bank->sectors[i].is_erased = 1; - command_print(CMD_CTX, "stm32h7x mass erase complete"); + command_print(CMD, "stm32h7x mass erase complete"); } else { - command_print(CMD_CTX, "stm32h7x mass erase failed"); + command_print(CMD, "stm32h7x mass erase failed"); } return retval; @@ -1128,7 +1115,7 @@ static const struct command_registration stm32x_command_handlers[] = { COMMAND_REGISTRATION_DONE }; -struct flash_driver stm32h7x_flash = { +const struct flash_driver stm32h7x_flash = { .name = "stm32h7x", .commands = stm32x_command_handlers, .flash_bank_command = stm32x_flash_bank_command,