/** * @Author: 李建 * @Date: 2024/8/12 13:21 * Description: * Copyright: Copyright (©) 2024 永续绿建. All rights reserved. */ #include "flash.h" #ifndef FLASH_PAGE_TO_ADDR #define FLASH_PAGE_TO_ADDR(page) ((uint32_t)(FLASH_BASE+(FLASH_PAGE_SIZE)*(page))) /* Base @ of page address*/ #endif #ifndef ADDR_TO_FLASH_PAGE #define ADDR_TO_FLASH_PAGE(addr) (((addr)-FLASH_BASE)/(FLASH_PAGE_SIZE)) #endif #ifndef FLASH_USER_START_ADDR #define FLASH_USER_START_ADDR FLASH_PAGE_TO_ADDR(24) /* Start @ of user Flash area */ #endif #ifndef FLASH_USER_END_ADDR #define FLASH_USER_END_ADDR FLASH_PAGE_TO_ADDR(34) /* End @ of user Flash area */ #endif #define BUILD_UINT16(loByte, hiByte) \ ((uint16_t)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8))) #define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \ ((uint32_t)((uint32_t)((Byte0) & 0x00FF) \ + ((uint32_t)((Byte1) & 0x00FF) << 8) \ + ((uint32_t)((Byte2) & 0x00FF) << 16) \ + ((uint32_t)((Byte3) & 0x00FF) << 24))) uint32_t flash_read ( uint32_t address, uint8_t* pdata, uint32_t size ) { uint32_t read_index = 0; uint8_t value; uint32_t start_addr; uint32_t end_addr; if ( !pdata || size < 1 ) { return 0;//FLASH_PARAM_ERROR; } // start_addr = address+FLASH_BASE_ADDRESS; start_addr = address; end_addr = start_addr + size; // if ( start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR ) // { // return 0;//FLASH_ADDR_ERROR; // } read_index = 0; while ( read_index < size ) { value = * ( __IO uint8_t* ) start_addr; start_addr = start_addr + 1; * ( pdata + read_index ) = value; read_index++; } return read_index; } FLASH_ERROR_CODE_E flash_erase( uint32_t start_addr,uint32_t end_addr) { static FLASH_EraseInitTypeDef EraseInitStruct; uint32_t PageError = 0; //printf("start_addr = %lx,end_addr=%lx,FLASH_USER_START_ADDR = %lx,FLASH_USER_END_ADDR = %lx\r\n",start_addr,end_addr,FLASH_USER_START_ADDR,FLASH_USER_END_ADDR); if(start_addr > end_addr) { return FLASH_ADDR_ERROR; } /* Unlock the Flash to enable the flash control register access *************/ HAL_FLASH_Unlock(); /* Fill EraseInit structure*/ EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = start_addr; EraseInitStruct.NbPages = (end_addr - start_addr+(FLASH_PAGE_SIZE-1))/FLASH_PAGE_SIZE; if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK) { HAL_FLASH_Lock(); return FLASH_ERASE_ERROR; } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ HAL_FLASH_Lock(); return FLASH_SUCCESS; } FLASH_ERROR_CODE_E flash_write(uint32_t address, const uint8_t* pdata, uint32_t size) { HAL_StatusTypeDef result = HAL_ERROR; uint32_t end_addr = 0; uint32_t start_addr; // uint16_t page_num; uint32_t word_num; uint8_t half_word_num; uint8_t byte_num; uint32_t write_index = 0; //parameter check if((!pdata) || (size<1)) { return FLASH_PARAM_ERROR; } // page_num = (size % FLASH_PAGE_SIZE)?(size / FLASH_PAGE_SIZE+1):(size / FLASH_PAGE_SIZE); word_num = (size >> 2); // size/4 half_word_num = (size % 4)>>1; // (size%4)>>1 byte_num = (size % 2); // size % 2 start_addr = address; end_addr = ( start_addr + size ); // if ( start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR ) // { // return FLASH_ADDR_ERROR; // } /* Unlock the Flash to enable the flash control register access *************/ HAL_FLASH_Unlock(); write_index = 0; while(write_index < word_num) { result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, start_addr, BUILD_UINT32 ( * ( pdata ), * ( pdata + 1 ), * ( pdata + 2 ), * ( pdata + 3 ) )); if(HAL_OK == result) { start_addr = start_addr + 4; pdata = pdata + 4; write_index++; } else { return FLASH_WRITE_WORD_ERROR; } } write_index = 0; while(write_index < half_word_num) { result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,start_addr,BUILD_UINT16 ( * ( pdata ), * ( pdata + 1 ) )); if ( HAL_OK == result ) { start_addr = start_addr + 2; pdata = pdata + 2; write_index++; } else { return FLASH_WRITE_HALF_WORD_ERROR; } } write_index = 0; while(write_index < byte_num) { result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,start_addr,BUILD_UINT16 ( * ( pdata ), 0xFFFF )); if ( HAL_OK == result ) { start_addr = start_addr + 2; pdata = pdata + 2; write_index++; } else { return FLASH_WRITE_BYTE_ERROR; } } /* Lock the Flash to disable the flash control register access (recommended to protect the FLASH memory against possible unwanted operation) *********/ HAL_FLASH_Lock(); return FLASH_SUCCESS; }