X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fstm32l4x.c;h=f71369330eb451d6b5a5788d831e88a7e06c6e0a;hp=42e90bc746adc3de045b8da4d1c38dd7bf6e237a;hb=47d0930410bc6f9fdf1d59a60a60fcca4c7bb1d4;hpb=a28b94e9ab00c63951f68ac44833e9d51200f7db diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index 42e90bc746..f71369330e 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -13,8 +13,7 @@ * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc. * + * along with this program. If not, see . * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -28,18 +27,22 @@ /* STM32L4xxx series for reference. * - * RM0351 - * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/reference_manual/DM00083560.pdf + * RM0351 (STM32L4x5/STM32L4x6) + * http://www.st.com/resource/en/reference_manual/dm00083560.pdf * - * STM32L476RG Datasheet (for erase timing) - * http://www.st.com/st-web-ui/static/active/en/resource/technical/document/datasheet/DM00108832.pdf + * RM0394 (STM32L43x/44x/45x/46x) + * http://www.st.com/resource/en/reference_manual/dm00151940.pdf * + * STM32L476RG Datasheet (for erase timing) + * http://www.st.com/resource/en/datasheet/stm32l476rg.pdf * - * The device has normally two banks, but on 512 and 256 kiB devices an - * option byte is available to map all sectors to the first bank. + * The RM0351 devices have normally two banks, but on 512 and 256 kiB devices + * an option byte is available to map all sectors to the first bank. * Both STM32 banks are treated as one OpenOCD bank, as other STM32 devices * handlers do! * + * RM0394 devices have a single bank only. + * */ /* Erase time can be as high as 25ms, 10x this and assume it's toast... */ @@ -184,6 +187,8 @@ static int stm32l4_wait_status_busy(struct flash_bank *bank, int timeout) /* Clear but report errors */ if (status & FLASH_ERROR) { + if (retval == ERROR_OK) + retval = ERROR_FAIL; /* If this operation fails, we ignore it and report the original * retval */ @@ -458,18 +463,8 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, struct armv7m_algorithm armv7m_info; int retval = ERROR_OK; - /* See contrib/loaders/flash/stm32l4x.S for source and - * hints how to generate the data! - */ - static const uint8_t stm32l4_flash_write_code[] = { - 0xd0, 0xf8, 0x00, 0x80, 0xb8, 0xf1, 0x00, 0x0f, 0x1e, 0xd0, 0x45, 0x68, - 0xb8, 0xeb, 0x05, 0x06, 0x07, 0x2e, 0xf5, 0xd3, 0xdf, 0xf8, 0x34, 0x60, - 0x66, 0x61, 0xf5, 0xe8, 0x02, 0x67, 0xe2, 0xe8, 0x02, 0x67, 0xbf, 0xf3, - 0x4f, 0x8f, 0x26, 0x69, 0x16, 0xf4, 0x80, 0x3f, 0xfb, 0xd1, 0x16, 0xf0, - 0xfa, 0x0f, 0x07, 0xd1, 0x8d, 0x42, 0x28, 0xbf, 0x00, 0xf1, 0x08, 0x05, - 0x45, 0x60, 0x01, 0x3b, 0x13, 0xb1, 0xdd, 0xe7, 0x00, 0x21, 0x41, 0x60, - 0x30, 0x46, 0x00, 0xbe, 0x01, 0x00, 0x00, 0x00 +#include "../../../contrib/loaders/flash/stm32/stm32l4x.inc" }; if (target_alloc_working_area(target, sizeof(stm32l4_flash_write_code), @@ -599,6 +594,7 @@ static int stm32l4_probe(struct flash_bank *bank) struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; int i; uint16_t flash_size_in_kb = 0xffff; + uint16_t max_flash_size_in_kb; uint32_t device_id; uint32_t options; uint32_t base_address = 0x08000000; @@ -613,7 +609,15 @@ static int stm32l4_probe(struct flash_bank *bank) /* set max flash size depending on family */ switch (device_id & 0xfff) { + case 0x461: case 0x415: + max_flash_size_in_kb = 1024; + break; + case 0x462: + max_flash_size_in_kb = 512; + break; + case 0x435: + max_flash_size_in_kb = 256; break; default: LOG_WARNING("Cannot identify target as a STM32L4 family."); @@ -623,17 +627,31 @@ static int stm32l4_probe(struct flash_bank *bank) /* get flash size from target. */ retval = target_read_u16(target, FLASH_SIZE_REG, &flash_size_in_kb); + /* failed reading flash size or flash size invalid (early silicon), + * default to max target family */ + if (retval != ERROR_OK || flash_size_in_kb == 0xffff || flash_size_in_kb == 0) { + LOG_WARNING("STM32 flash size failed, probe inaccurate - assuming %dk flash", + max_flash_size_in_kb); + flash_size_in_kb = max_flash_size_in_kb; + } + + LOG_INFO("flash size = %dkbytes", flash_size_in_kb); + + /* did we assign flash size? */ + assert(flash_size_in_kb != 0xffff); + /* get options to for DUAL BANK. */ retval = target_read_u32(target, STM32_FLASH_OPTR, &options); + if (retval != ERROR_OK) + return retval; + /* only devices with < 1024 kiB may be set to single bank dual banks */ if ((flash_size_in_kb == 1024) || !(options & OPT_DUALBANK)) stm32l4_info->option_bytes.bank_b_start = 256; else stm32l4_info->option_bytes.bank_b_start = flash_size_in_kb << 9; - LOG_INFO("flash size = %dkbytes", flash_size_in_kb); - /* did we assign flash size? */ assert((flash_size_in_kb != 0xffff) && flash_size_in_kb); @@ -685,7 +703,7 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) if (retval != ERROR_OK) return retval; - uint16_t device_id = dbgmcu_idcode & 0xffff; + uint16_t device_id = dbgmcu_idcode & 0xfff; uint8_t rev_id = dbgmcu_idcode >> 28; uint8_t rev_minor = 0; int i; @@ -700,8 +718,20 @@ static int get_stm32l4_info(struct flash_bank *bank, char *buf, int buf_size) const char *device_str; switch (device_id) { - case 0x6415: - device_str = "STM32L4xx"; + case 0x461: + device_str = "STM32L496/4A6"; + break; + + case 0x415: + device_str = "STM32L475/476/486"; + break; + + case 0x462: + device_str = "STM32L45x/46x"; + break; + + case 0x435: + device_str = "STM32L43x/44x"; break; default: @@ -914,4 +944,5 @@ struct flash_driver stm32l4x_flash = { .erase_check = default_flash_blank_check, .protect_check = stm32l4_protect_check, .info = get_stm32l4_info, + .free_driver_priv = default_flash_free_driver_priv, };