flash.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /**
  2. * @Author: 李建
  3. * @Date: 2024/8/12 13:21
  4. * Description:
  5. * Copyright: Copyright (©) 2024 永续绿建. All rights reserved.
  6. */
  7. #include "flash.h"
  8. #ifndef FLASH_PAGE_TO_ADDR
  9. #define FLASH_PAGE_TO_ADDR(page) ((uint32_t)(FLASH_BASE+(FLASH_PAGE_SIZE)*(page))) /* Base @ of page address*/
  10. #endif
  11. #ifndef ADDR_TO_FLASH_PAGE
  12. #define ADDR_TO_FLASH_PAGE(addr) (((addr)-FLASH_BASE)/(FLASH_PAGE_SIZE))
  13. #endif
  14. #ifndef FLASH_USER_START_ADDR
  15. #define FLASH_USER_START_ADDR FLASH_PAGE_TO_ADDR(24) /* Start @ of user Flash area */
  16. #endif
  17. #ifndef FLASH_USER_END_ADDR
  18. #define FLASH_USER_END_ADDR FLASH_PAGE_TO_ADDR(34) /* End @ of user Flash area */
  19. #endif
  20. #define BUILD_UINT16(loByte, hiByte) \
  21. ((uint16_t)(((loByte) & 0x00FF) + (((hiByte) & 0x00FF) << 8)))
  22. #define BUILD_UINT32(Byte0, Byte1, Byte2, Byte3) \
  23. ((uint32_t)((uint32_t)((Byte0) & 0x00FF) \
  24. + ((uint32_t)((Byte1) & 0x00FF) << 8) \
  25. + ((uint32_t)((Byte2) & 0x00FF) << 16) \
  26. + ((uint32_t)((Byte3) & 0x00FF) << 24)))
  27. uint32_t flash_read ( uint32_t address, uint8_t* pdata, uint32_t size )
  28. {
  29. uint32_t read_index = 0;
  30. uint8_t value;
  31. uint32_t start_addr;
  32. uint32_t end_addr;
  33. if ( !pdata || size < 1 )
  34. {
  35. return 0;//FLASH_PARAM_ERROR;
  36. }
  37. // start_addr = address+FLASH_BASE_ADDRESS;
  38. start_addr = address;
  39. end_addr = start_addr + size;
  40. // if ( start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR )
  41. // {
  42. // return 0;//FLASH_ADDR_ERROR;
  43. // }
  44. read_index = 0;
  45. while ( read_index < size )
  46. {
  47. value = * ( __IO uint8_t* ) start_addr;
  48. start_addr = start_addr + 1;
  49. * ( pdata + read_index ) = value;
  50. read_index++;
  51. }
  52. return read_index;
  53. }
  54. FLASH_ERROR_CODE_E flash_erase( uint32_t start_addr,uint32_t end_addr)
  55. {
  56. static FLASH_EraseInitTypeDef EraseInitStruct;
  57. uint32_t PageError = 0;
  58. //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);
  59. if(start_addr > end_addr)
  60. {
  61. return FLASH_ADDR_ERROR;
  62. }
  63. /* Unlock the Flash to enable the flash control register access *************/
  64. HAL_FLASH_Unlock();
  65. /* Fill EraseInit structure*/
  66. EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  67. EraseInitStruct.PageAddress = start_addr;
  68. EraseInitStruct.NbPages = (end_addr - start_addr+(FLASH_PAGE_SIZE-1))/FLASH_PAGE_SIZE;
  69. if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
  70. {
  71. HAL_FLASH_Lock();
  72. return FLASH_ERASE_ERROR;
  73. }
  74. /* Lock the Flash to disable the flash control register access (recommended
  75. to protect the FLASH memory against possible unwanted operation) *********/
  76. HAL_FLASH_Lock();
  77. return FLASH_SUCCESS;
  78. }
  79. FLASH_ERROR_CODE_E flash_write(uint32_t address, const uint8_t* pdata, uint32_t size)
  80. {
  81. HAL_StatusTypeDef result = HAL_ERROR;
  82. uint32_t end_addr = 0;
  83. uint32_t start_addr;
  84. // uint16_t page_num;
  85. uint32_t word_num;
  86. uint8_t half_word_num;
  87. uint8_t byte_num;
  88. uint32_t write_index = 0;
  89. //parameter check
  90. if((!pdata) || (size<1))
  91. {
  92. return FLASH_PARAM_ERROR;
  93. }
  94. // page_num = (size % FLASH_PAGE_SIZE)?(size / FLASH_PAGE_SIZE+1):(size / FLASH_PAGE_SIZE);
  95. word_num = (size >> 2); // size/4
  96. half_word_num = (size % 4)>>1; // (size%4)>>1
  97. byte_num = (size % 2); // size % 2
  98. start_addr = address;
  99. end_addr = ( start_addr + size );
  100. // if ( start_addr < FLASH_USER_START_ADDR || end_addr > FLASH_USER_END_ADDR )
  101. // {
  102. // return FLASH_ADDR_ERROR;
  103. // }
  104. /* Unlock the Flash to enable the flash control register access *************/
  105. HAL_FLASH_Unlock();
  106. write_index = 0;
  107. while(write_index < word_num)
  108. {
  109. result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, start_addr, BUILD_UINT32 ( * ( pdata ), * ( pdata + 1 ), * ( pdata + 2 ), * ( pdata + 3 ) ));
  110. if(HAL_OK == result)
  111. {
  112. start_addr = start_addr + 4;
  113. pdata = pdata + 4;
  114. write_index++;
  115. }
  116. else
  117. {
  118. return FLASH_WRITE_WORD_ERROR;
  119. }
  120. }
  121. write_index = 0;
  122. while(write_index < half_word_num)
  123. {
  124. result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,start_addr,BUILD_UINT16 ( * ( pdata ), * ( pdata + 1 ) ));
  125. if ( HAL_OK == result )
  126. {
  127. start_addr = start_addr + 2;
  128. pdata = pdata + 2;
  129. write_index++;
  130. }
  131. else
  132. {
  133. return FLASH_WRITE_HALF_WORD_ERROR;
  134. }
  135. }
  136. write_index = 0;
  137. while(write_index < byte_num)
  138. {
  139. result = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,start_addr,BUILD_UINT16 ( * ( pdata ), 0xFFFF ));
  140. if ( HAL_OK == result )
  141. {
  142. start_addr = start_addr + 2;
  143. pdata = pdata + 2;
  144. write_index++;
  145. }
  146. else
  147. {
  148. return FLASH_WRITE_BYTE_ERROR;
  149. }
  150. }
  151. /* Lock the Flash to disable the flash control register access (recommended
  152. to protect the FLASH memory against possible unwanted operation) *********/
  153. HAL_FLASH_Lock();
  154. return FLASH_SUCCESS;
  155. }