/* * flash.c * * Created on: 2019. 7. 15. * Author: parkyj */ #include "flash.h" #include "zig_operate.h" uint8_t flashinit = 0; uint32_t Address = FLASH_USER_START_ADDR; typedef void (*fptr)(void); fptr jump_to_app; uint32_t jump_addr; void Jump_App(void){ __HAL_RCC_TIM6_CLK_DISABLE(); // 留ㅼ씤???占쏙옙癒몌옙?? ?占쏙옙占�??占쏙옙?占쏙옙?占쏙옙 printf("boot loader start\n"); //硫붿꽭占�? 異쒕젰 jump_addr = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4); jump_to_app = (fptr) jump_addr; /* init user app's sp */ printf("jump!\n"); __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); jump_to_app(); } void FLASH_If_Init(void) { /* Unlock the Program memory */ HAL_FLASH_Unlock(); /* Clear all FLASH flags */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); /* Unlock the Program memory */ HAL_FLASH_Lock(); } void Flash_InitRead(void) // ?占쏙옙湲고븿?占쏙옙 { uint32_t Address = 0; Address = FLASH_USER_START_ADDR; for(uint32_t i = 0; i < INDEX_BLUE_EOF + 1; i++ ){ // printf("%08x : %02X \n",Address ,*(uint8_t*)Address); Address++; } #if 0 // PYJ.2019.03.27_BEGIN -- for(uint32_t i = 0; i < 13848; i++ ){ printf("%08x : %02X \n",Address ,*(uint8_t*)Address); Address++; } Address = StartAddr; for(uint32_t i = 0; i < 13848; i++ ){ printf("%02X ",*(uint8_t*)Address); Address++; } #endif // PYJ.2019.03.27_END -- } #define INDEX_LENGTH 2 uint8_t Flash_RGB_Data_Write(uint8_t* data){ uint16_t Firmdata = 0; uint8_t ret = 0; for(uint8_t i = 0; i < data[INDEX_LENGTH] - 2; i+=2){ Firmdata = ((data[(INDEX_LENGTH + 1) + i]) & 0x00FF); Firmdata += ((data[(INDEX_LENGTH + 1) + (i + 1)] << 8) & 0xFF00); if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD,Address , (uint16_t)Firmdata) != HAL_OK){ printf("HAL NOT OK \n"); ret = 1; } Address += 2; } return ret; } #define INDEX_HEADER 0 uint8_t Flash_write(uint8_t* data) // ?占쏙옙湲고븿?占쏙옙 { /*Variable used for Erase procedure*/ static FLASH_EraseInitTypeDef EraseInitStruct; static uint32_t PAGEError = 0; uint8_t ret = 0; /* Fill EraseInit structure*/ EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; EraseInitStruct.PageAddress = FLASH_USER_START_ADDR; EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE; HAL_FLASH_Unlock(); // lock ??占�? if(flashinit == 0){ flashinit= 1; //FLASH_PageErase(StartAddr); if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK){ printf("Erase Failed \r\n"); } } // FLASH_If_Erase(); ret = Flash_RGB_Data_Write(&data[INDEX_HEADER]); HAL_FLASH_Lock(); // lock ?占쏙옙洹멸린 return ret; } /* 페이지 별로 1Kbyte로 이루어져 있으며 사용하는 MCU 메모리 크기에 따라 물리 페이지가 늘어나거나 줄어듭니다. 위 페이지 범위를 보고 사용자의 MCU에 맞게 사용할 페이지의 시작 주소와 끝주소를 정해줍니다. 예제에서는 1개 페이지만 사용하도록 설정하였습니다. 아래에서의 시작번지는 11페이지 이므로 시작 주소는 0x08002C00 가 되겠습니다. */ //그리고 Flash memory에 저장할 사용자 데이터를 정의 합니다. 예제에서는 4byte 변수를 사용하기 위해 어드레스를 4byte단위로 증가시켰습니다. #define USER_DATA1 (FLASH_USER_START_ADDR) #define USER_DATA2 (FLASH_USER_START_ADDR + 4) #define USER_DATA3 (FLASH_USER_START_ADDR + 8) #define USER_DATA4 (FLASH_USER_START_ADDR + 12) void FLASH_Byte_Write(uint8_t* data){ /* 페이지 단위로 지울수 있도록 구조체변수를 선언해 주고 멤버변수값들을 정해줍니다. 데이터를 새로 쓰기위해서는 먼저 페이지 단위로 메모리를 지워 줘야 합니다. */ static FLASH_EraseInitTypeDef EraseInitStruct; EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES; //0x00 EraseInitStruct.PageAddress = FLASH_USER_START_ADDR; // 지우기 페이지의 시작 어드레스 EraseInitStruct.NbPages = (FLASH_USER_END_ADDR - FLASH_USER_START_ADDR) / FLASH_PAGE_SIZE; //지울 페이지 수 static uint32_t PAGEError = 0; // printf("Flash Write Start \r\n"); data[INDEX_BLUE_HEADER] = 0xbe; data[INDEX_BLUE_TYPE] = 1; data[INDEX_BLUE_LENGTH] = INDEX_BLUE_EOF - 2; data[INDEX_BLUE_CRCINDEX] = INDEX_BLUE_EOF - 1; /* Flash메모리를 조작 할 수 있도록 락을 풀어 줍니다. */ HAL_FLASH_Unlock(); /* 앞에서 설정한 페이지를 지워 줍니다. 페이지 지우기에 실패하면 무한루프에 빠지게 하여 기기의 오작동을 예방합니다. */ if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) { printf("Eraser Error\r\n"); while(1); } /* 유저 데이터를 메모리에 써 줍니다. 임의의 유저데이터를 써주기 위해 변수를 하나 만들어 줘봤습니다. */ uint16_t WriteData = 0; /* 그리고 데이터 쓰기 */ /////////유저가 설정한 페이지에 데이터 쓰기 //////////////////////////////////////////////////// //HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data) for(int i = 0; i < INDEX_BLUE_EOF + 1; i += 2){ WriteData = ((data[i]) & 0x00FF); WriteData += ((data[i + 1] << 8) & 0xFF00); if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_USER_START_ADDR + i, ((uint16_t)WriteData)) != HAL_OK){ printf("Write Error %d\r\n",__LINE__); while(1); } } /* 마지막으로 Flash 메모리를 보호하기 위해 락을 걸어 줍니다. */ HAL_FLASH_Lock(); /* 이제 메모리에 저장된 데이터를 꺼내 보겠습니다. */ ///////////////메모리에서 데이터 읽기//////////////////////////////////////////////////////////// #if 0// PYJ.2019.07.31_BEGIN -- for(int i = 0; i < INDEX_BLUE_EOF+1; i += 2){ printf("Addr = %x, Data = %x\r\n", FLASH_USER_START_ADDR + i, *(__IO uint16_t *)(FLASH_USER_START_ADDR + i)); } #endif // PYJ.2019.07.31_END -- /////////////////////////////////////////////////////////////////////////////////////////////////// } uint8_t Bluecell_Flash_Write(uint8_t* data){ /*Variable used for Erase procedure*/ // flashtest(); FLASH_Byte_Write(&data[INDEX_BLUE_HEADER]); return true; } bool Bluecell_Flash_Read(uint8_t* data){ for(int i = 0; i < INDEX_BLUE_EOF + 1; i += 2){ // printf("Addr = %x, Data = %x\r\n", FLASH_USER_START_ADDR + i, *(__IO uint16_t *)(FLASH_USER_START_ADDR + i)); data[INDEX_BLUE_HEADER + i] = *(__IO uint16_t *)(FLASH_USER_START_ADDR + i) &0x00FF; data[INDEX_BLUE_HEADER + i + 1] = (*(__IO uint16_t *)(FLASH_USER_START_ADDR + i) & 0xFF00) >> 8; } #if 0 // PYJ.2019.07.31_BEGIN -- for(int i = 0; i < INDEX_BLUE_EOF + 1; i++){ printf("Data = %x\r\n", data[i]); } #endif // PYJ.2019.07.31_END -- return true; }