/** * @fn spi_flash_erase * @brief Erase from data from SPI flash * @param[IN] u32Offset * Address to write to at the SPI flash * @param[IN] u32Sz * Data size * @return Status of execution * @note Data size is limited by the SPI flash size only */ sint8 spi_flash_erase(uint32 u32Offset, uint32 u32Sz) { uint32 i = 0; sint8 ret = M2M_SUCCESS; uint8 tmp = 0; #ifdef PROFILING uint32 t; t = GetTickCount(); #endif M2M_PRINT("\r\n>Start erasing...\r\n"); for(i = u32Offset; i < (u32Sz +u32Offset); i += (16*FLASH_PAGE_SZ)) { ret += spi_flash_write_enable(); ret += spi_flash_read_status_reg(&tmp); ret += spi_flash_sector_erase(i + 10); ret += spi_flash_read_status_reg(&tmp); do { if(ret != M2M_SUCCESS) goto ERR; ret += spi_flash_read_status_reg(&tmp); }while(tmp & 0x01); } M2M_PRINT("Done\r\n"); #ifdef PROFILING M2M_PRINT("#Erase time = %f sec\n", (GetTickCount()-t)/1000.0); #endif ERR: return ret; }
/** * @fn spi_flash_rdid * @brief Read SPI Flash ID * @return SPI FLash ID */ static uint32 spi_flash_rdid(void) { unsigned char cmd[1]; uint32 reg = 0; uint32 cnt = 0; sint8 ret = M2M_SUCCESS; cmd[0] = 0x9f; ret += nm_write_reg(SPI_FLASH_DATA_CNT, 4); ret += nm_write_reg(SPI_FLASH_BUF1, cmd[0]); ret += nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); ret += nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); ret += nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); do { ret += nm_read_reg_with_ret(SPI_FLASH_TR_DONE, (uint32 *)®); if(M2M_SUCCESS != ret) break; if(++cnt > 500) { ret = M2M_ERR_INIT; break; } } while(reg != 1); reg = (M2M_SUCCESS == ret)?(nm_read_reg(DUMMY_REGISTER)):(0); M2M_PRINT("Flash ID %x \n",(unsigned int)reg); return reg; }
static uint32 spi_flash_rdid(void) { unsigned char cmd[1]; uint32 reg; cmd[0] = 0x9f; nm_write_reg(SPI_FLASH_DATA_CNT, 4); nm_write_reg(SPI_FLASH_BUF1, cmd[0]); nm_write_reg(SPI_FLASH_BUF_DIR, 0x1); nm_write_reg(SPI_FLASH_DMA_ADDR, DUMMY_REGISTER); nm_write_reg(SPI_FLASH_CMD_CNT, 1 | (1<<7)); while(nm_read_reg(SPI_FLASH_TR_DONE) != 1); reg = nm_read_reg(DUMMY_REGISTER); M2M_PRINT("Flash id %x \n",reg); return reg; }
/** * @fn spi_flash_write * @brief Proram SPI flash * @param[IN] pu8Buf * Pointer to data buffer * @param[IN] u32Offset * Address to write to at the SPI flash * @param[IN] u32Sz * Data size * @return Status of execution */ sint8 spi_flash_write(uint8* pu8Buf, uint32 u32Offset, uint32 u32Sz) { #ifdef PROFILING uint32 t1 = 0; uint32 percent =0; uint32 tpercent =0; #endif sint8 ret = M2M_SUCCESS; uint32 u32wsz; uint32 u32off; uint32 u32Blksz; u32Blksz = FLASH_PAGE_SZ; u32off = u32Offset % u32Blksz; #ifdef PROFILING tpercent = (u32Sz/u32Blksz)+((u32Sz%u32Blksz)>0); t1 = GetTickCount(); M2M_PRINT(">Start programming...\r\n"); #endif if(u32Sz<=0) { M2M_ERR("Data size = %d",(int)u32Sz); ret = M2M_ERR_FAIL; goto ERR; } if (u32off)/*first part of data in the address page*/ { u32wsz = u32Blksz - u32off; if(spi_flash_pp(u32Offset, pu8Buf, (uint16)BSP_MIN(u32Sz, u32wsz))!=M2M_SUCCESS) { ret = M2M_ERR_FAIL; goto ERR; } if (u32Sz < u32wsz) goto EXIT; pu8Buf += u32wsz; u32Offset += u32wsz; u32Sz -= u32wsz; } while (u32Sz > 0) { u32wsz = BSP_MIN(u32Sz, u32Blksz); /*write complete page or the remaining data*/ if(spi_flash_pp(u32Offset, pu8Buf, (uint16)u32wsz)!=M2M_SUCCESS) { ret = M2M_ERR_FAIL; goto ERR; } pu8Buf += u32wsz; u32Offset += u32wsz; u32Sz -= u32wsz; #ifdef PROFILING percent++; printf("\r>Complete Percentage = %d%%.\r",((percent*100)/tpercent)); #endif } EXIT: #ifdef PROFILING M2M_PRINT("\rDone\t\t\t\t\t\t"); M2M_PRINT("\n#Programming time = %f sec\n\r",(GetTickCount() - t1)/1000.0); #endif ERR: return ret; }