| | |
| | | */ |
| | | int FMC_Erase(FLCTL_T *fmc,unsigned int Addr,unsigned char cmd) |
| | | { |
| | | #if FMC_DBG_LOG |
| | | if (cmd == CMD_ERASE_SECTOR) { |
| | | SYS_TEST("Erase Addr: 0x%08x (Sector Erase)\n", Addr); |
| | | } else if (cmd == CMD_ERASE_32K) { |
| | | SYS_TEST("Erase Addr: 0x%08x (BLK32k Erase)\n", Addr); |
| | | } else if (cmd == CMD_ERASE_64K) { |
| | | SYS_TEST("Erase Addr: 0x%08x (BLK64k Erase)\n", Addr); |
| | | } else { |
| | | SYS_TEST("Unhandled Erase CMD, Addr: 0x%08x, CMD: %d\n", Addr, cmd); |
| | | } |
| | | #endif |
| | | |
| | | unsigned char offset = 0; |
| | | unsigned char bytes_num_w; |
| | | |
| | |
| | | if (addr >= FMC_GetFlashCodeAreaSize(fmc)) { |
| | | return -1; |
| | | } |
| | | |
| | | // Ensure we will not touch the flash INFO area |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | return FMC_Erase(fmc,addr,CMD_ERASE_SECTOR); |
| | | } |
| | | |
| | |
| | | || (addr < 0x7000)) { |
| | | return -1; |
| | | } |
| | | |
| | | // Ensure we will not touch the flash INFO area |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | return FMC_Erase(fmc,addr,CMD_ERASE_32K); |
| | | } |
| | | |
| | |
| | | || (addr < 0xF000)) { |
| | | return -1; |
| | | } |
| | | return FMC_Erase(fmc,addr,CMD_ERASE_64K); |
| | | } |
| | | |
| | | /** |
| | | * @brief Erase the whole flash memory. |
| | | * |
| | | * This function is used to erase all data in flash, include |
| | | * Code Area and Info Area. |
| | | * |
| | | * @note This API should only be used when you really know what |
| | | * you are doing. |
| | | * |
| | | * @param fmc: where fmc is a flash peripheral. |
| | | * @retval 0: Success. |
| | | * @retval -1: Fail. |
| | | */ |
| | | int FMC_EraseChip(FLCTL_T *fmc) |
| | | { |
| | | return FMC_Erase(fmc,0x0,CMD_ERASE_CHIP); |
| | | // Ensure we will not touch the flash INFO area |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | return FMC_Erase(fmc,addr,CMD_ERASE_64K); |
| | | } |
| | | |
| | | static void find_special_chunk_in_range(size_t chunk_pattern, uint32_t range_start_sector_idx, uint16_t range_sector_num, |
| | |
| | | return -1; |
| | | } |
| | | |
| | | // Fine 32K blocks from the initial data chunk |
| | | // Find 32K blocks from the initial data chunk |
| | | find_special_chunk_in_range(8, start_phy_sector_idx, sector_num, &block_32k_start_sector_idx, &block_32k_sector_num); |
| | | |
| | | if (block_32k_sector_num == 0) { // No 32k-block found |
| | |
| | | return (unsigned char *)&(FLCTL_BUFF->X_FL_BUFFER[0]); |
| | | } |
| | | |
| | | /** |
| | | * @brief This function is used to read data stream from flash |
| | | * @param fmc where fmc is a flash peripheral. |
| | | * @param Addr where Addr is start address to read |
| | | * @param cmd where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD |
| | | * @param buf where buf is a buffer to store read data |
| | | * @param len where len is data length of bytes to read |
| | | * @retval None |
| | | */ |
| | | int FMC_ReadStream(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len) |
| | | static int FMC_ReadStreamInternal(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len) |
| | | { |
| | | unsigned int tmp_addr = Addr; |
| | | unsigned int tmp_size = len; |
| | |
| | | } |
| | | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief This function is used to read data stream from flash |
| | | * @param fmc where fmc is a flash peripheral. |
| | | * @param Addr where Addr is start address to read |
| | | * @param cmd where cmd can be \ref CMD_FAST_READ or \ref CMD_DREAD |
| | | * @param buf where buf is a buffer to store read data |
| | | * @param len where len is data length of bytes to read |
| | | * @retval None |
| | | */ |
| | | int FMC_ReadStream(FLCTL_T *fmc, unsigned int Addr, unsigned char cmd, unsigned char *buf, unsigned int len) |
| | | { |
| | | // Ensure we will not touch the flash INFO area |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | return FMC_ReadStreamInternal(fmc, Addr, cmd, buf, len); |
| | | } |
| | | /** |
| | | * @brief This function is used to write data to buffer, |
| | |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * @brief This function is used to write data stream to flash |
| | | * @param fmc where fmc is a flash peripheral |
| | | * @param Addr where Addr is start address to write, can be any valid address |
| | | * @param buf where buf is a buffer to store data to write |
| | | * @param len where len is data length of bytes to write |
| | | * @retval None |
| | | */ |
| | | int FMC_WriteStream(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len) |
| | | static int FMC_WriteStreamInternal(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len) |
| | | { |
| | | unsigned int OffsetOfFirstPage = Addr % 256; |
| | | unsigned int WriteSizeInFirstPage = (len < (256 - OffsetOfFirstPage)) ? len : (256 - OffsetOfFirstPage); |
| | |
| | | } |
| | | |
| | | /** |
| | | * @brief This function is used to write data stream to flash |
| | | * @param fmc where fmc is a flash peripheral |
| | | * @param Addr where Addr is start address to write, can be any valid address |
| | | * @param buf where buf is a buffer to store data to write |
| | | * @param len where len is data length of bytes to write |
| | | * @retval None |
| | | */ |
| | | int FMC_WriteStream(FLCTL_T *fmc, unsigned int Addr, unsigned char *buf, unsigned int len) |
| | | { |
| | | // Ensure we will not touch the flash INFO area |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | return FMC_WriteStreamInternal(fmc, Addr, buf, len); |
| | | } |
| | | |
| | | /** |
| | | * @brief This function is used to read data from the flash 4KB INFO area. |
| | | * @param fmc where fmc is a flash peripheral. |
| | | * @param Addr where Addr is start address to read, can be 0 ~ 4095 |
| | |
| | | fmc->X_FL_CONFIG |= BIT1; //set info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | FMC_ReadStream(fmc, Addr, cmd, buf, len); |
| | | FMC_ReadStreamInternal(fmc, Addr, cmd, buf, len); |
| | | |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | |
| | | fmc->X_FL_CONFIG |= BIT1; //set info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | FMC_WriteStream(fmc, Addr, buf, len); |
| | | FMC_WriteStreamInternal(fmc, Addr, buf, len); |
| | | |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | |
| | | fmc->X_FL_CONFIG |= BIT1; //set info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |
| | | |
| | | ret = FMC_EraseSector(fmc, 0x0); |
| | | ret = FMC_Erase(fmc, 0x0, CMD_ERASE_SECTOR); |
| | | |
| | | fmc->X_FL_CONFIG &= ~BIT1; //clear info_en bit |
| | | fmc->X_FL_CONFIG |= BIT2; //set tx_address_transaction bit |