flash.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * flash.c
  3. *
  4. * Created on: 2019. 7. 15.
  5. * Author: parkyj
  6. */
  7. #include "flash.h"
  8. #include "zig_operate.h"
  9. uint8_t flashinit = 0;
  10. uint32_t Address = FLASH_USER_START_ADDR;
  11. typedef void (*fptr)(void);
  12. fptr jump_to_app;
  13. uint32_t jump_addr;
  14. void Jump_App(void){
  15. __HAL_RCC_TIM6_CLK_DISABLE(); // 留ㅼ씤???占쏙옙癒몌옙?? ?占쏙옙占�??占쏙옙?占쏙옙?占쏙옙
  16. printf("boot loader start\n"); //硫붿꽭占�? 異쒕젰
  17. jump_addr = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
  18. jump_to_app = (fptr) jump_addr;
  19. /* init user app's sp */
  20. printf("jump!\n");
  21. __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
  22. jump_to_app();
  23. }
  24. void FLASH_If_Init(void)
  25. {
  26. /* Unlock the Program memory */
  27. HAL_FLASH_Unlock();
  28. /* Clear all FLASH flags */
  29. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR);
  30. /* Unlock the Program memory */
  31. HAL_FLASH_Lock();
  32. }
  33. void Flash_InitRead(void) // ?占쏙옙湲고븿?占쏙옙
  34. {
  35. uint32_t Address = 0;
  36. Address = FLASH_USER_START_ADDR;
  37. for(uint32_t i = 0; i < INDEX_BLUE_EOF + 1; i++ ){
  38. // printf("%08x : %02X \n",Address ,*(uint8_t*)Address);
  39. Address++;
  40. }
  41. #if 0 // PYJ.2019.03.27_BEGIN --
  42. for(uint32_t i = 0; i < 13848; i++ ){
  43. printf("%08x : %02X \n",Address ,*(uint8_t*)Address);
  44. Address++;
  45. }
  46. Address = StartAddr;
  47. for(uint32_t i = 0; i < 13848; i++ ){
  48. printf("%02X ",*(uint8_t*)Address);
  49. Address++;
  50. }
  51. #endif // PYJ.2019.03.27_END --
  52. }
  53. #define INDEX_LENGTH 2
  54. uint8_t Flash_RGB_Data_Write(uint8_t* data){
  55. uint16_t Firmdata = 0;
  56. uint8_t ret = 0;
  57. for(uint8_t i = 0; i < data[INDEX_LENGTH] - 2; i+=2){
  58. Firmdata = ((data[(INDEX_LENGTH + 1) + i]) & 0x00FF);
  59. Firmdata += ((data[(INDEX_LENGTH + 1) + (i + 1)] << 8) & 0xFF00);
  60. if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,Address , (uint16_t)Firmdata) != HAL_OK){
  61. printf("HAL NOT OK \n");
  62. ret = 1;
  63. }
  64. Address += 2;
  65. }
  66. return ret;
  67. }
  68. #define INDEX_HEADER 0
  69. uint8_t Flash_write(uint8_t* data) // ?占쏙옙湲고븿?占쏙옙
  70. {
  71. /*Variable used for Erase procedure*/
  72. static FLASH_EraseInitTypeDef EraseInitStruct;
  73. static uint32_t PAGEError = 0;
  74. uint8_t ret = 0;
  75. /* Fill EraseInit structure*/
  76. EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
  77. EraseInitStruct.PageAddress = FLASH_USER_START_ADDR;
  78. EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE;
  79. HAL_FLASH_Unlock(); // lock ??占�?
  80. if(flashinit == 0){
  81. flashinit= 1;
  82. //FLASH_PageErase(StartAddr);
  83. if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK){
  84. printf("Erase Failed \r\n");
  85. }
  86. }
  87. // FLASH_If_Erase();
  88. ret = Flash_RGB_Data_Write(&data[INDEX_HEADER]);
  89. HAL_FLASH_Lock(); // lock ?占쏙옙洹멸린
  90. return ret;
  91. }
  92. /*
  93. 페이지 별로 1Kbyte로 이루어져 있으며 사용하는 MCU 메모리 크기에 따라 물리 페이지가 늘어나거나 줄어듭니다.
  94. 위 페이지 범위를 보고 사용자의 MCU에 맞게 사용할 페이지의 시작 주소와 끝주소를 정해줍니다.
  95. 예제에서는 1개 페이지만 사용하도록 설정하였습니다.
  96. 아래에서의 시작번지는 11페이지 이므로 시작 주소는 0x08002C00 가 되겠습니다.
  97. */
  98. //그리고 Flash memory에 저장할 사용자 데이터를 정의 합니다. 예제에서는 4byte 변수를 사용하기 위해 어드레스를 4byte단위로 증가시켰습니다.
  99. #define USER_DATA1 (FLASH_USER_START_ADDR)
  100. #define USER_DATA2 (FLASH_USER_START_ADDR + 4)
  101. #define USER_DATA3 (FLASH_USER_START_ADDR + 8)
  102. #define USER_DATA4 (FLASH_USER_START_ADDR + 12)
  103. void FLASH_Byte_Write(uint8_t* data){
  104. /*
  105. 페이지 단위로 지울수 있도록 구조체변수를 선언해 주고 멤버변수값들을 정해줍니다.
  106. 데이터를 새로 쓰기위해서는 먼저 페이지 단위로 메모리를 지워 줘야 합니다.
  107. */
  108. static FLASH_EraseInitTypeDef EraseInitStruct;
  109. EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; //0x00
  110. EraseInitStruct.PageAddress = FLASH_USER_START_ADDR; // 지우기 페이지의 시작 어드레스
  111. EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE; //지울 페이지 수
  112. static uint32_t PAGEError = 0;
  113. // printf("Flash Write Start \r\n");
  114. data[INDEX_BLUE_HEADER] = 0xbe;
  115. data[INDEX_BLUE_TYPE] = 1;
  116. data[INDEX_BLUE_LENGTH] = INDEX_BLUE_EOF - 2;
  117. data[INDEX_BLUE_CRCINDEX] = INDEX_BLUE_EOF - 1;
  118. /*
  119. Flash메모리를 조작 할 수 있도록 락을 풀어 줍니다.
  120. */
  121. HAL_FLASH_Unlock();
  122. /*
  123. 앞에서 설정한 페이지를 지워 줍니다. 페이지 지우기에 실패하면 무한루프에 빠지게 하여 기기의 오작동을 예방합니다.
  124. */
  125. if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
  126. printf("Eraser Error\r\n");
  127. while(1);
  128. }
  129. /*
  130. 유저 데이터를 메모리에 써 줍니다.
  131. 임의의 유저데이터를 써주기 위해 변수를 하나 만들어 줘봤습니다.
  132. */
  133. uint16_t WriteData = 0;
  134. /*
  135. 그리고 데이터 쓰기
  136. */
  137. /////////유저가 설정한 페이지에 데이터 쓰기 ////////////////////////////////////////////////////
  138. //HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
  139. for(int i = 0; i < INDEX_BLUE_EOF + 1; i += 2){
  140. WriteData = ((data[i]) & 0x00FF);
  141. WriteData += ((data[i + 1] << 8) & 0xFF00);
  142. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_USER_START_ADDR + i, ((uint16_t)WriteData)) != HAL_OK){
  143. printf("Write Error %d\r\n",__LINE__);
  144. while(1);
  145. }
  146. }
  147. /*
  148. 마지막으로 Flash 메모리를 보호하기 위해 락을 걸어 줍니다.
  149. */
  150. HAL_FLASH_Lock();
  151. /*
  152. 이제 메모리에 저장된 데이터를 꺼내 보겠습니다.
  153. */
  154. ///////////////메모리에서 데이터 읽기////////////////////////////////////////////////////////////
  155. #if 0// PYJ.2019.07.31_BEGIN --
  156. for(int i = 0; i < INDEX_BLUE_EOF+1; i += 2){
  157. printf("Addr = %x, Data = %x\r\n", FLASH_USER_START_ADDR + i, *(__IO uint16_t *)(FLASH_USER_START_ADDR + i));
  158. }
  159. #endif // PYJ.2019.07.31_END --
  160. ///////////////////////////////////////////////////////////////////////////////////////////////////
  161. }
  162. uint8_t Bluecell_Flash_Write(uint8_t* data){
  163. /*Variable used for Erase procedure*/
  164. // flashtest();
  165. FLASH_Byte_Write(&data[INDEX_BLUE_HEADER]);
  166. return true;
  167. }
  168. bool Bluecell_Flash_Read(uint8_t* data){
  169. for(int i = 0; i < INDEX_BLUE_EOF + 1; i += 2){
  170. // printf("Addr = %x, Data = %x\r\n", FLASH_USER_START_ADDR + i, *(__IO uint16_t *)(FLASH_USER_START_ADDR + i));
  171. data[INDEX_BLUE_HEADER + i] = *(__IO uint16_t *)(FLASH_USER_START_ADDR + i) &0x00FF;
  172. data[INDEX_BLUE_HEADER + i + 1] = (*(__IO uint16_t *)(FLASH_USER_START_ADDR + i) & 0xFF00) >> 8;
  173. }
  174. #if 0 // PYJ.2019.07.31_BEGIN --
  175. for(int i = 0; i < INDEX_BLUE_EOF + 1; i++){
  176. printf("Data = %x\r\n", data[i]);
  177. }
  178. #endif // PYJ.2019.07.31_END --
  179. return true;
  180. }