123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- #include "drv_chipFlash.h"
- #include "stm32f1xx.h"
- //#include "stm32f103xb.h"
- #include "stm32f1xx_hal_flash.h"
- #include "drv_IAP.h"
- //#define TEST
- //unsigned short ipaFlag = 0;
- //BASE_CONFIG base_config;
- Cclient_info client_info;
- //从指定地址开始读取多个数据
- int FLASH_ReadMoreData(uint32_t startAddress, uint32_t *readData, uint32_t countToRead){
-
- #ifdef TEST
- //解锁
- HAL_FLASH_Unlock();
- uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址
- uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置
- uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址
- if(FLASH_ErasePage(sectorStartAddress, 1) != 0){
- //写操作上锁
- HAL_FLASH_Lock();
- return -1;
- }
- HAL_FLASH_Lock();
- #endif
- //数据大小必须双字节对齐
- if(countToRead % 2 != 0 )
- return -1;
-
- uint16_t dataIndex = 0;
- for(dataIndex = 0; dataIndex < (countToRead / 2); dataIndex++){
- readData[dataIndex] = FLASH_ReadHalfWord(startAddress + dataIndex * 2);
- }
- return 0;
- }
- //读取指定地址的半字(16位数据)
- uint16_t FLASH_ReadHalfWord(uint32_t address){
- return *(volatile uint16_t *)address;
- }
- //读取指定地址的全字(32位数据)
- static uint32_t FLASH_ReadWord(uint32_t address){
- uint32_t temp1 = 0, temp2 = 0;
- temp1 = *(volatile uint16_t *)address;
- temp2 = *(volatile uint16_t *)(address + 2);
- return (temp2 << 16) | temp1;
- }
- //擦除指定地址的扇区
- int FLASH_ErasePage(uint32_t ErasePageAddr, uint32_t PageNumber){
- FLASH_EraseInitTypeDef eraseInit = {0};
- uint32_t PageError = 0;
- eraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
- eraseInit.PageAddress = ErasePageAddr;
- eraseInit.NbPages = PageNumber;
- //关闭中断
- __disable_irq();
- //HAL_NVIC_DisableIRQ(SysTick_IRQn);
-
- if(HAL_FLASHEx_Erase(&eraseInit, &PageError) != HAL_OK){
- //恢复中断
- __enable_irq();
- //HAL_NVIC_EnableIRQ(SysTick_IRQn);
- return -1;
- }
- //恢复中断
- __enable_irq();
- //HAL_NVIC_EnableIRQ(SysTick_IRQn);
- return 0;
- }
- //从指定地址开始写入多个数据
- int FLASH_WriteMoreData(uint32_t startAddress, uint32_t *writeData, uint32_t countToWrite){
-
- //非法地址
- if(startAddress < FLASH_BASE || ((startAddress + countToWrite) >= (FLASH_BASE + 1024 * CHIPFLASH_SIZE)))
- return -1;
-
- //数据大小必须双字节对齐
- if(countToWrite % 2!= 0 )
- return -1;
- //解锁
- HAL_FLASH_Unlock();
-
- //计算扇区信息
- uint32_t offsetAddress = startAddress - FLASH_BASE; //计算实际偏移地址
- uint32_t sectorPosition = offsetAddress / SECTOR_SIZE; //计算扇区位置
- uint32_t sectorStartAddress = sectorPosition * SECTOR_SIZE + FLASH_BASE; //计算扇区起始地址
-
- //启用扇区擦除
- if(FLASH_ErasePage(sectorStartAddress, 1) != 0){
- //写操作上锁
- HAL_FLASH_Lock();
- return -1;
- }
- uint16_t dataIndex = 0;
- for(dataIndex = 0; dataIndex < (countToWrite / 2); dataIndex++){
- __disable_irq();
- if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, startAddress + dataIndex * 2
- , writeData[dataIndex]) != HAL_OK){
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
- return -1;
- }
- }
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
-
- return 0;
- }
- int FLASH_INFO_SetFlag(void){
- #ifdef FUNC
- uint8_t *p = (uint8_t *)&client_info;
-
- int i;
- int count = 0;
- for(i = 0; i < sizeof(client_info); i++){
- if(p[i] != 0xFF){
- count = 0;
- }
- if(p[i] == 0xFF){
- count++;
- }
- }
-
- if(count == sizeof(client_info)){
- return -1;
- }
- #endif
- if(client_info._init_flag == 1){
- return 0;
- }
- return -1;
- }
- void erasure_bin_flash(void){
- HAL_FLASH_Unlock();
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_BSY
- | FLASH_FLAG_WRPERR | FLASH_FLAG_OPTVERR );
- //获取APP开始地址所在扇区
- uint32_t UserStartSector = (APPLICATION_ADDRESS - FLASH_BASE) / SECTOR_SIZE;
- //获取APP结束地址所在扇区
- uint32_t UserEndSector = UserStartSector + (iap_bin_Size + SECTOR_SIZE - 1) / SECTOR_SIZE;
-
- // 如果结束地址错误。APP地址从FLASH_Sector_4开始
- if(UserEndSector < UserStartSector){
- while(1){
- send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
- HAL_Delay(600);
- }
- }
-
- // 擦写到FLASH_Sector_7需要3.5s时间
- for(uint32_t i = UserStartSector; i <= UserEndSector; i++){
- //驱动电压在[2.7V to 3.6V]范围内,擦除操作将按字擦除
- if(FLASH_ErasePage(FLASH_BASE + i * SECTOR_SIZE, 1)!= 0){
- HAL_FLASH_Lock();
- while(1){
- //擦除失败
- send_mavlink_bootloader_status(BOOTLOADER_STATUS_FLASH_ERASOR_ERROR);
- HAL_Delay(600);
- }
- }
- }
- }
- int FLASH_Write(volatile uint32_t FlashAddress, uint32_t *WriteData, uint32_t DataLength){
- uint32_t i =0;
- //解锁
- HAL_FLASH_Unlock();
- for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 4)); i++){
- __disable_irq();
-
- //if(FLASH_WriteMoreData(FlashAddress, (uint32_t *)(WriteData + i), 4) == 0)
- if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddress, *(uint32_t*)(WriteData + i))== HAL_OK)
- {
- __enable_irq();
- if(*(uint32_t *)FlashAddress != *(uint32_t*)(WriteData + i)){
- //FLASH中数据与SRAM中内容不一致
- //写操作上锁
- HAL_FLASH_Lock();
- return -1;
- }
- FlashAddress += 4;
- }
- else{
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
- //编程Flash memory时发生错误
- return -1;
- }
- }
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
- cur_address = FlashAddress;
-
- return 0;
- }
- int FLASH_Write_HalfWord(volatile uint32_t FlashAddress, uint16_t *WriteData, uint16_t DataLength){
- //解锁
- HAL_FLASH_Unlock();
- uint32_t i =0;
- for(i = 0; (i < DataLength) && (FlashAddress <= (USER_FLASH_END_ADDR - 2)); i++)
- {
- __disable_irq();
- if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddress, *(uint16_t*)(WriteData + i)) == HAL_OK)
- {
- __enable_irq();
- if(*(uint16_t *)FlashAddress!= *(uint16_t*)(WriteData + i)){
- //FLASH中数据与SRAM中内容不一致
- //写操作上锁
- HAL_FLASH_Lock();
- return -1;
- }
- FlashAddress += 2;
- }
- else{
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
- //编程Flash memory时发生错误
- return -1;
- }
- }
- __enable_irq();
- //写操作上锁
- HAL_FLASH_Lock();
- cur_address = FlashAddress;
-
- return 0;
- }
|