diff --git a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_h7.c b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_h7.c index da42bb92b6..1bbbbadab1 100644 --- a/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_h7.c +++ b/bsp/stm32/libraries/HAL_Drivers/drv_flash/drv_flash_h7.c @@ -24,110 +24,6 @@ //#define DRV_DEBUG #define LOG_TAG "drv.flash" #include -#define ADDR_FLASH_SECTOR_0 ((rt_uint32_t)0x08000000) /* Base address of Sector 0, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_1 ((rt_uint32_t)0x08020000) /* Base address of Sector 1, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_2 ((rt_uint32_t)0x08040000) /* Base address of Sector 2, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_3 ((rt_uint32_t)0x08060000) /* Base address of Sector 3, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_4 ((rt_uint32_t)0x08080000) /* Base address of Sector 4, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_5 ((rt_uint32_t)0x080A0000) /* Base address of Sector 5, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_6 ((rt_uint32_t)0x080C0000) /* Base address of Sector 6, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_7 ((rt_uint32_t)0x080E0000) /* Base address of Sector 7, 128 Kbytes */ -#define ADDR_FLASH_SECTOR_8 ((rt_uint32_t)0x08100000) /* Base address of Sector 8, 128 Kbytes */ - -#define FLASH_SECTOR_0 0U /* Sector Number 0 */ -#define FLASH_SECTOR_1 1U /* Sector Number 1 */ -#define FLASH_SECTOR_2 2U /* Sector Number 2 */ -#define FLASH_SECTOR_3 3U /* Sector Number 3 */ -#define FLASH_SECTOR_4 4U /* Sector Number 4 */ -#define FLASH_SECTOR_5 5U /* Sector Number 5 */ -#define FLASH_SECTOR_6 6U /* Sector Number 6 */ -#define FLASH_SECTOR_7 7U /* Sector Number 7 */ -/** - * @brief Gets the sector of a given address - * @param addr flash address - * @param flash bank - * @param flash sector - * @retval The sector of a given address - */ -static void GetSector(rt_uint32_t Address,uint32_t* bank,uint32_t* sector) -{ -#if defined (FLASH_OPTCR_nDBANK) - FLASH_OBProgramInitTypeDef OBInit; - uint32_t nbank = 0; - - /* get duel bank ability:nDBANK(Bit29) */ - HAL_FLASHEx_OBGetConfig(&OBInit); - nbank = ((OBInit.USERConfig & 0x20000000U) >> 29); - /* 1:single bank mode */ - if (1 == nbank) - { - if ((Address < ADDR_FLASH_SECTOR_1) && (Address >= ADDR_FLASH_SECTOR_0)) - { - sector = FLASH_SECTOR_0; - } - else if ((Address < ADDR_FLASH_SECTOR_2) && (Address >= ADDR_FLASH_SECTOR_1)) - { - sector = FLASH_SECTOR_1; - } - else if ((Address < ADDR_FLASH_SECTOR_3) && (Address >= ADDR_FLASH_SECTOR_2)) - { - sector = FLASH_SECTOR_2; - } - else if ((Address < ADDR_FLASH_SECTOR_4) && (Address >= ADDR_FLASH_SECTOR_3)) - { - sector = FLASH_SECTOR_3; - } - else if ((Address < ADDR_FLASH_SECTOR_5) && (Address >= ADDR_FLASH_SECTOR_4)) - { - sector = FLASH_SECTOR_4; - } - else if ((Address < ADDR_FLASH_SECTOR_6) && (Address >= ADDR_FLASH_SECTOR_5)) - { - sector = FLASH_SECTOR_5; - } - else if ((Address < ADDR_FLASH_SECTOR_7) && (Address >= ADDR_FLASH_SECTOR_6)) - { - sector = FLASH_SECTOR_6; - } - else if ((Address < ADDR_FLASH_SECTOR_8) && (Address >= ADDR_FLASH_SECTOR_7)) - { - sector = FLASH_SECTOR_7; - } - else if ((Address < ADDR_FLASH_SECTOR_9) && (Address >= ADDR_FLASH_SECTOR_8)) - { - sector = FLASH_SECTOR_8; - } - else if ((Address < ADDR_FLASH_SECTOR_10) && (Address >= ADDR_FLASH_SECTOR_9)) - { - sector = FLASH_SECTOR_9; - } - else if ((Address < ADDR_FLASH_SECTOR_11) && (Address >= ADDR_FLASH_SECTOR_10)) - { - sector = FLASH_SECTOR_10; - } - else - { - sector = FLASH_SECTOR_11; - } - } - else /* 0:dual bank mode */ - { - LOG_E("rtthread doesn't support duel bank mode yet!"); - RT_ASSERT(0); - } -#else /* no dual bank ability */ - *sector = (Address&0xffffff)/FLASH_SIZE_GRANULARITY_128K; - if(*sector>7) - { - *bank = FLASH_BANK_1; - *sector = *sector/2; - } - else - { - *bank = FLASH_BANK_2; - } -#endif -} /** * Read data from flash. @@ -137,16 +33,16 @@ static void GetSector(rt_uint32_t Address,uint32_t* bank,uint32_t* sector) * @param buf buffer to store read data * @param size read bytes size * - * @return result + * @retval The length of bytes that have been read */ int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size) { size_t i; - if ((addr + size) > STM32_FLASH_END_ADDRESS) + if ((addr + size - 1) > FLASH_END) { LOG_E("read outrange flash size! addr is (0x%p)", (void *)(addr + size)); - return -1; + return -RT_ERROR; } for (i = 0; i < size; i++, buf++, addr++) @@ -166,47 +62,68 @@ int stm32_flash_read(rt_uint32_t addr, rt_uint8_t *buf, size_t size) * @param buf the write data buffer * @param size write bytes size * - * @return result + * @return The length of bytes that have been written */ int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size) { rt_err_t result = RT_EOK; - rt_uint32_t end_addr = addr + size; - rt_uint32_t bank = addr/ADDR_FLASH_SECTOR_8;; + rt_uint32_t end_addr = addr + size - 1, write_addr; + rt_uint32_t write_granularity = FLASH_NB_32BITWORD_IN_FLASHWORD * 4; + rt_uint32_t write_size = write_granularity; + rt_uint8_t write_buffer[32] = {0}; - if ((end_addr) > STM32_FLASH_END_ADDRESS) + if ((end_addr) > FLASH_END) { LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size)); return -RT_EINVAL; } + + if(addr % 32 != 0) + { + LOG_E("write addr must be 32-byte alignment"); + return -RT_EINVAL; + } if (size < 1) { return -RT_EINVAL; } - /* Unlock the Flash to enable the flash control register access */ HAL_FLASH_Unlock(); - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR ); - - for (size_t i = 0; i < size/32; i++, addr+=32, buf+=32) + write_addr = (uint32_t)buf; + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR); + while (addr < end_addr) { - /* write data to flash */ - if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, (uint64_t)((uint32_t)buf)) == HAL_OK) + if(end_addr - addr + 1 < write_granularity) { - if (*(rt_uint8_t *)addr != *buf) + write_size = end_addr - addr + 1; + for(size_t i = 0; i < write_size; i++) { - result = -RT_ERROR; - break; + write_buffer[i] = *(buf + i); } + write_addr = (uint32_t)((rt_uint32_t *)write_buffer); + } + if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, addr, write_addr) == HAL_OK) + { + for(rt_uint8_t i = 0; i < write_size; i++) + { + if (*(rt_uint8_t *)(addr + i) != *(rt_uint8_t *)(buf + i)) + { + result = -RT_ERROR; + goto __exit; + } + } + addr += write_granularity; + buf += write_granularity; } else { result = -RT_ERROR; - break; + goto __exit; } } +__exit: HAL_FLASH_Lock(); if (result != RT_EOK) @@ -230,42 +147,74 @@ int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size) int stm32_flash_erase(rt_uint32_t addr, size_t size) { rt_err_t result = RT_EOK; - rt_uint32_t FirstSector = 0, NbOfSectors = 0; rt_uint32_t SECTORError = 0; - rt_uint32_t bank = 0; - if ((addr + size) > STM32_FLASH_END_ADDRESS) + if ((addr + size - 1) > FLASH_END) { LOG_E("ERROR: erase outrange flash size! addr is (0x%p)\n", (void *)(addr + size)); return -RT_EINVAL; } + rt_uint32_t addr_bank1 = 0; + rt_uint32_t size_bank1 = 0; + rt_uint32_t addr_bank2 = 0; + rt_uint32_t size_bank2 = 0; + + if((addr + size) < FLASH_BANK2_BASE) + { + addr_bank1 = addr; + size_bank1 = size; + size_bank2 = 0; + } + else if(addr >= FLASH_BANK2_BASE) + { + size_bank1 = 0; + addr_bank2 = addr; + size_bank2 = size; + } + else + { + addr_bank1 = addr; + size_bank1 = FLASH_BANK2_BASE - addr_bank1; + addr_bank2 = FLASH_BANK2_BASE; + size_bank2 = addr + size - FLASH_BANK2_BASE; + } + /*Variable used for Erase procedure*/ FLASH_EraseInitTypeDef EraseInitStruct; - /* Unlock the Flash to enable the flash control register access */ HAL_FLASH_Unlock(); - - /* Get the 1st sector to erase */ - GetSector(addr,&bank,&FirstSector); - /* Get the number of sector to erase from 1st sector */ - GetSector(addr + size,0,&NbOfSectors); - NbOfSectors = NbOfSectors - FirstSector + 1; - /* Fill EraseInit structure */ EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3; - EraseInitStruct.Sector = FirstSector; - EraseInitStruct.NbSectors = NbOfSectors; - EraseInitStruct.Banks = bank; - - if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK) + SCB_DisableDCache(); + + if(size_bank1) { - result = -RT_ERROR; - goto __exit; + EraseInitStruct.Sector = (addr_bank1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE; + EraseInitStruct.NbSectors = (addr_bank1 + size_bank1 -1 - FLASH_BANK1_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1; + EraseInitStruct.Banks = FLASH_BANK_1; + if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK) + { + result = -RT_ERROR; + goto __exit; + } + } + + if(size_bank2) + { + EraseInitStruct.Sector = (addr_bank2 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE; + EraseInitStruct.NbSectors = (addr_bank2 + size_bank2 -1 - FLASH_BANK2_BASE) / FLASH_SECTOR_SIZE - EraseInitStruct.Sector + 1; + EraseInitStruct.Banks = FLASH_BANK_2; + if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK) + { + result = -RT_ERROR; + goto __exit; + } } __exit: + SCB_EnableDCache(); HAL_FLASH_Lock(); if (result != RT_EOK)