flash(1436).c 7.0 KB

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