/** *\brief Erases the specified 64KB block of the serial firmware dataflash. * * \param pAt25 Pointer to an AT25 driver instance. * \param address Address of the block to erase. * * \return 0 if successful; otherwise returns AT25_ERROR_PROTECTED if the * device is protected or AT25_ERROR_BUSY if it is busy executing a command. */ unsigned char AT25D_EraseBlock(At25 *pAt25, unsigned int address) { unsigned char status; unsigned char error; assert(pAt25); /* Check that the flash is ready and unprotected */ status = AT25D_ReadStatus(pAt25); if ((status & AT25_STATUS_RDYBSY) != AT25_STATUS_RDYBSY_READY) { TRACE_ERROR("AT25D_EraseBlock : Flash busy\n\r"); return AT25_ERROR_BUSY; } else if ((status & AT25_STATUS_SWP) != AT25_STATUS_SWP_PROTNONE) { TRACE_ERROR("AT25D_EraseBlock : Flash protected\n\r"); return AT25_ERROR_PROTECTED; } /* Enable critical write operation */ AT25D_EnableWrite(pAt25); /* Start the block erase command */ error = AT25_SendCommand(pAt25, AT25_BlockEraseCmd(pAt25), 4, 0, 0, address, 0, 0); assert(!error); /* Wait for transfer to finish */ AT25D_Wait(pAt25); /* Poll the Serial flash status register until the operation is achieved */ AT25D_WaitReady(pAt25); return 0; }
/** * \brief Erases all the content of the memory chip. * * \param pAt25 Pointer to an AT25 driver instance. * * \return 0 if the device has been unprotected; otherwise returns * AT25_ERROR_PROTECTED. */ unsigned char AT25D_EraseChip(At25 *pAt25) { unsigned char status; unsigned char error; assert(pAt25); /* Check that the flash is unprotected */ status = AT25D_ReadStatus(pAt25); if ((status & AT25_STATUS_SWP) != AT25_STATUS_SWP_PROTNONE) { return AT25_ERROR_PROTECTED; } /* Enable critical write operation */ AT25D_EnableWrite(pAt25); /* Erase the chip */ error = AT25_SendCommand(pAt25, AT25_CHIP_ERASE_2, 1, 0, 0, 0, 0, 0); assert(!error); /* Wait for transfer to finish */ AT25D_Wait(pAt25); /* Poll the Serial flash status register until the operation is achieved */ AT25D_WaitReady(pAt25); return 0; }
/** * \brief Unprotects the contents of the serial flash device. * * \param pAt25 Pointer to an AT25 driver instance. * * \return 0 if the device has been unprotected; otherwise returns * AT25_ERROR_PROTECTED. */ unsigned char AT25D_Unprotect(At25 *pAt25) { unsigned char status; assert(pAt25); /* Get the status register value to check the current protection */ status = AT25D_ReadStatus(pAt25); if ((status & AT25_STATUS_SWP) == AT25_STATUS_SWP_PROTNONE) { /* Protection already disabled */ return 0; } /* Check if sector protection registers are locked */ if ((status & AT25_STATUS_SPRL) == AT25_STATUS_SPRL_LOCKED) { /* Unprotect sector protection registers by writing the status reg. */ AT25D_EnableWrite(pAt25); AT25D_WriteStatus(pAt25, 0); } /* Perform a global unprotect command */ AT25D_EnableWrite(pAt25); AT25D_WriteStatus(pAt25, 0); /* Check the new status */ status = AT25D_ReadStatus(pAt25); if ((status & (AT25_STATUS_SPRL | AT25_STATUS_SWP)) != 0) { return AT25_ERROR_PROTECTED; } else { return 0; } }
/** * \brief Writes data at the specified address on the serial firmware dataflash. The * page(s) to program must have been erased prior to writing. This function * handles page boundary crossing automatically. * * \param pAt25 Pointer to an AT25 driver instance. * \param pData Data buffer. * \param size Number of bytes in buffer. * \param address Write address. * * \return 0 if successful; otherwise, returns AT25_ERROR_PROGRAM is there has * been an error during the data programming. */ unsigned char AT25D_Write( At25 *pAt25, unsigned char *pData, unsigned int size, unsigned int address) { unsigned int pageSize; unsigned int writeSize; unsigned char error; unsigned char status; assert(pAt25); assert(pData); /* Retrieve device page size */ pageSize = AT25_PageSize(pAt25); /* Program one page after the other */ while (size > 0) { /* Compute number of bytes to program in page */ writeSize = min(size, pageSize - (address % pageSize)); /* Enable critical write operation */ AT25D_EnableWrite(pAt25); /* Program page */ error = AT25_SendCommand(pAt25, AT25_BYTE_PAGE_PROGRAM, 4, pData, writeSize, address, 0, 0); assert(!error); /* Wait for transfer to finish */ AT25D_Wait(pAt25); /* Poll the Serial flash status register until the operation is achieved */ AT25D_WaitReady(pAt25); /* Make sure that write was without error */ status = AT25D_ReadStatus(pAt25); if ((status & AT25_STATUS_EPE) == AT25_STATUS_EPE_ERROR) { return AT25_ERROR_PROGRAM; } pData += writeSize; size -= writeSize; address += writeSize; } return 0; }