/** * @brief This function writes the NDEF file from the RAM to the FLASH * @param dataToWrite : The buffer which contains the memory to be written * @param size : The buffer size * @param address : The destination address inside the FLASH * @retval FLASH_OK : The file is written successfully * @retval FLASH_ERROR_SIZE : The NDEF size is higher than the FLASH available */ uint8_t writeNDEFToFlash(uint8_t *dataToWrite, uint32_t size, uint32_t address) { #ifndef DISABLE_NDEF_FLASH int32_t j; uint32_t data=0; uint32_t *pdata; uint32_t EraseCounter = 0x0; uint32_t NbrOfPage = 0; FLASH_Status FLASHStatus = FLASH_COMPLETE; /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (!IS_FLASH_PROGRAM_ADDRESS(size + FLASH_MAGIC_NUMBER_LENTH + address)) { return FLASH_ERROR_SIZE; } /* Unlock the FLASH */ FLASH_Unlock(); /* Clear All pending flags */ FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR); /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ NbrOfPage = FLASH_PagesMask(size + FLASH_MAGIC_NUMBER_LENTH); /* Erase the FLASH pages */ for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(address + (PAGE_SIZE * EraseCounter)); } pdata = (uint32_t*)(dataToWrite); /* Write the magic number */ FLASH_ProgramWord(address,FLASH_MAGIC_NUMBER); address+=FLASH_MAGIC_NUMBER_LENTH; for(j=0;j<size;j+=4) { data = *pdata; FLASH_ProgramWord(address,data); pdata++; address += 4; } /* Lock the FLASH */ FLASH_Lock(); #endif return FLASH_OK; }
void FLASH_ProgramStart(void) { FLASH_Status FLASHStatus = FLASH_COMPLETE; u32 NbrOfPage = 0; vu32 EraseCounter = 0; FLASH_Unlock(); NbrOfPage = FLASH_PagesMask(ApplicationSize); for (; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(ApplicationAddress + (PAGE_SIZE * EraseCounter)); } }
/******************************************************************************* * Function Name :u32 FLASH_WriteBank(u32 *pData, u32 addr, u32 size) * Description :写入一块数据 * Input :pData:数据;addr:数据的地址;size:长度 * Output :TRUE:成功,FALSE:失败。 * Other : * Date :2013.02.24 *******************************************************************************/ u32 FLASH_WriteBank(u8 *pData, u32 addr, u16 size) { vu16 *pDataTemp = (vu16 *)pData; vu32 temp = addr; FLASH_Status FLASHStatus = FLASH_COMPLETE; u32 NbrOfPage = 0; NbrOfPage = FLASH_PagesMask(addr + size - ApplicationAddress); for (; (m_EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); m_EraseCounter++) { FLASHStatus = FLASH_ErasePage(ApplicationAddress + (PAGE_SIZE * m_EraseCounter)); } for (; temp < (addr + size); pDataTemp++, temp += 2) { FLASH_ProgramHalfWord(temp, *pDataTemp); if (*pDataTemp != *(vu16 *)temp) { return FALSE; } } return TRUE; }
/** * @brief Receive a file using the ymodem protocol * @param buf: Address of the first byte * @retval The size of the file */ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0; /* Initialize FlashDestination variable */ FlashDestination = ApplicationAddress; for (session_done = 0, errors = 0, session_begin = 0; ;) { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) { switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT)) { case 0: errors = 0; switch (packet_length) { /* Abort by sender */ case - 1: Send_Byte(ACK); return 0; /* End of transmission */ case 0: Send_Byte(ACK); file_done = 1; break; /* Normal packet */ default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) { Send_Byte(NAK); } else { if (packets_received == 0) { /* Filename packet */ if (packet_data[PACKET_HEADER] != 0) { /* Filename packet has valid data */ for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &size); /* Test the size of the image to be sent */ /* Image size is greater than Flash size */ if (size > (FLASH_SIZE - 1)) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -1; } /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ NbrOfPage = FLASH_PagesMask(size); /* Erase the FLASH pages */ for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } Send_Byte(ACK); Send_Byte(CRC16); } /* Filename packet is empty, end session */ else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } /* Data packet */ else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; for (j = 0;(j < packet_length) && (FlashDestination < ApplicationAddress + size);j += 4) { /* Program the data received into STM32F10x Flash */ FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) { /* End session */ Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; } Send_Byte(ACK); } packets_received ++; session_begin = 1; } } break; case 1: Send_Byte(CA); Send_Byte(CA); return -3; default: if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); break; } if (file_done != 0) { break; } } if (session_done != 0) { break; } } return (int32_t)size; }
void OTPWriter_IAP_from_SD(void) { FIL fsrc; FRESULT res; UINT br; int32_t size = 0; uint32_t FlashDestination = ApplicationAddress; /* Flash user program offset */ uint16_t PageSize = PAGE_SIZE; uint32_t EraseCounter = 0x0; uint32_t NbrOfPage = 0; FLASH_Status FLASHStatus = FLASH_COMPLETE; uint32_t RamSource; int32_t i; /* Flash unlock */ FLASH_Unlock(); /* open the file which while update*/ res = f_open(&fsrc, "0:/OTPWriterFW.bin", FA_OPEN_EXISTING | FA_READ); if(res != FR_OK){ printf("open file error : %d\r\n",res); } else { /* get file size */ size = f_size(&fsrc); /* Erase the needed pages where the user application will be loaded */ /* Define the number of page to be erased */ NbrOfPage = FLASH_PagesMask(size); /* Erase the FLASH pages */ for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } for(;;) { res = f_read(&fsrc, buffer, PAGE_SIZE, &br); /* Read a chunk of source file */ if (res || br == 0) break; /* error or eof */ /* write to flash */ RamSource = (uint32_t)buffer; for (i = 0;(i < br) && (FlashDestination < ApplicationAddress + size);i += 4) { /* Program the data into STM32F10x Flash */ FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) { /* End session */ printf("Applicate update error\n\n"); break; } FlashDestination += 4; RamSource += 4; } } /* close file */ f_close(&fsrc); } printf("\r\nProgram the Flash OK \n!!!"); }
bool FLASH_EraseMemory(flash_device_t flashDeviceID, uint32_t startAddress, uint32_t length) { uint32_t eraseCounter = 0; uint32_t numPages = 0; if (FLASH_CheckValidAddressRange(flashDeviceID, startAddress, length) != true) { return false; } if (flashDeviceID == FLASH_INTERNAL) { /* Check which sector has to be erased */ uint16_t flashSector = FLASH_SectorToErase(FLASH_INTERNAL, startAddress); if (flashSector > FLASH_Sector_11) { return false; } /* Disable memory write protection if any */ FLASH_WriteProtectMemory(FLASH_INTERNAL, startAddress, length, false); /* Unlock the Flash Program Erase Controller */ FLASH_Unlock(); /* Define the number of Internal Flash pages to be erased */ numPages = FLASH_PagesMask(length, INTERNAL_FLASH_PAGE_SIZE); /* Clear All pending flags */ FLASH_ClearFlags(); /* Erase the Internal Flash pages */ for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++) { FLASH_Status status = FLASH_EraseSector(flashSector + (8 * eraseCounter), VoltageRange_3); /* If erase operation fails, return Failure */ if (status != FLASH_COMPLETE) { return false; } } /* Locks the FLASH Program Erase Controller */ FLASH_Lock(); return true; } else if (flashDeviceID == FLASH_SERIAL) { #ifdef USE_SERIAL_FLASH /* Initialize SPI Flash */ sFLASH_Init(); /* Define the number of External Flash pages to be erased */ numPages = FLASH_PagesMask(length, sFLASH_PAGESIZE); /* Erase the SPI Flash pages */ for (eraseCounter = 0; (eraseCounter < numPages); eraseCounter++) { sFLASH_EraseSector(startAddress + (sFLASH_PAGESIZE * eraseCounter)); } /* Return Success */ return true; #endif } /* Return Failure */ return false; }
/******************************************************************************* * @函数名称 Ymodem_Receive * @函数说明 通过 ymodem协议接收一个文件 * @输入参数 buf: 首地址指针 * @输出参数 无 * @返回参数 文件长度 *******************************************************************************/ int32_t Ymodem_Receive (uint8_t *buf) { uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr; int32_t i, j, packet_length, session_done, file_done, packets_received, errors, session_begin; uint32_t receive_file_size = 0; uint8_t receive_result; //初始化Flash地址变量 FlashDestination = ApplicationAddress; for (session_done = 0, errors = 0, session_begin = 0; ;) //死循环,初始化 { for (packets_received = 0, file_done = 0, buf_ptr = buf; ;) //死循环,初始化 { //0: 正常返回 //-1: 超时或者数据包错误 //1: 用户取消 receive_result=Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT); //for debug // Send_Byte(receive_result); // Send_Byte(packet_length); switch (receive_result) //从发送端接收一个数据包 { case 0: //0:正常返回 errors = 0; switch (packet_length) { //发送端终止 case - 1: Send_Byte(ACK); return 0; //结束传输 case 0: Send_Byte(ACK); file_done = 1; break; //正常的数据包 default: if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff)) //数据包编号错误 { Send_Byte(NAK); } else //包编号正确 { //表示第0帧,即文件名数据包 if (packets_received == 0) { //文件名数据包 if (packet_data[PACKET_HEADER] != 0) { //文件名数据包有效数据区域 for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);) { file_name[i++] = *file_ptr++; } file_name[i++] = '\0'; //上位机发送的文件名 for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);) { file_size[i++] = *file_ptr++; } file_size[i++] = '\0'; Str2Int(file_size, &receive_file_size); //size表示上位机发送过来的文件的大小 //for debug // Send_Byte(size); //测试数据包是否过大 if (receive_file_size > (FLASH_SIZE - 1)) { //结束 Send_Byte(CA); Send_Byte(CA); return -1; } //计算需要擦除Flash的页 NbrOfPage = FLASH_PagesMask(receive_file_size); //for debug // Send_Byte(0xfd); //擦除Flash for (EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++) { FLASHStatus = FLASH_ErasePage(FlashDestination + (PageSize * EraseCounter)); } //for debug // Send_Byte(0xfe); Send_Byte(ACK); //收到上位机发送的第0帧之后发送ACK命令 Send_Byte(CRC16); //接着再发送C,表示等待上位机发送数据帧 //for debug // Send_Byte(0xff); } //文件名数据包空,结束传输 else { Send_Byte(ACK); file_done = 1; session_done = 1; break; } } //非第0帧的协议数据包 else { memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length); RamSource = (uint32_t)buf; //内层for循环初始化buf_ptr = buf for (j = 0; (j < packet_length) && (FlashDestination < ApplicationAddress + receive_file_size); j += 4) { //把接收到的数据编写到Flash中 FLASH_ProgramWord(FlashDestination, *(uint32_t*)RamSource); if (*(uint32_t*)FlashDestination != *(uint32_t*)RamSource) //检查写flash是否成功 { //结束 Send_Byte(CA); Send_Byte(CA); return -2; } FlashDestination += 4; RamSource += 4; }//非第0帧的协议数据包结束 Send_Byte(ACK); //接受到第非0帧数据帧之后,发送ACK命令 } packets_received ++; //不管是第0帧还是第非0帧,数据包编号自增 session_begin = 1; //接受数据包成功则会话开始 }//包编号正确结束 }//内层switch循环结束 break; case 1: //1: 用户取消 Send_Byte(CA); Send_Byte(CA); return -3; default: //-1: 超时或者数据包错误 if (session_begin > 0) { errors ++; } if (errors > MAX_ERRORS) //如果错误次数大于MAX_ERRORS=5 { Send_Byte(CA); Send_Byte(CA); return 0; } Send_Byte(CRC16); //发送C break; }//外层switch结束 if (file_done != 0) { break; } }//内层for循环结束 if (session_done != 0) { break; } }//外层for循环结束 return (int32_t)receive_file_size; }