//------------------------------------------------------------------------------ /// Erases all the content of the memory chip. /// \param pAt26 Pointer to an AT26 driver instance. //------------------------------------------------------------------------------ unsigned char AT26D_EraseChip(At26 *pAt26) { unsigned char status; unsigned char error; SANITY_CHECK(pAt26); // Check that the flash is unprotected status = AT26D_ReadStatus(pAt26); if ((status & AT26_STATUS_SWP) != AT26_STATUS_SWP_PROTNONE) { return AT26_ERROR_PROTECTED; } // Enable critical write operation AT26D_EnableWrite(pAt26); // Erase the chip error = AT26_SendCommand(pAt26, AT26_CHIP_ERASE_2, 1, 0, 0, 0, 0, 0); ASSERT(!error, "-F- AT26_ChipErase: Could not issue command.\n\r"); // Wait for transfer to finish AT26D_Wait(pAt26); // Poll the Serial flash status register until the operation is achieved AT26D_WaitReady(pAt26); return 0; }
//------------------------------------------------------------------------------ // Reads and returns the status register of the serial flash. // \param pAt26 Pointer to an AT26 driver instance. //------------------------------------------------------------------------------ unsigned char AT26F004_Unprotect(At26 *pAt26) { unsigned char error; unsigned int sector, sectorAddress = 0; for (sector = 0 ; sector < 11 ; sector ++) { sectorAddress = 0x0; if (sector == 10) sectorAddress = 0x7C000; else if (sector == 9) sectorAddress = 0x7A000; else if (sector == 8) sectorAddress = 0x78000; else if (sector == 7) sectorAddress = 0x70000; else sectorAddress = sectorAddress + (0x10000 * sector); // Write Enable AT26D_EnableWrite(pAt26); error = AT26_SendCommand(pAt26, AT26_UNPROTECT_SECTOR, 4, 0, 0, sectorAddress, 0, 0); ASSERT(!error, "-F- AT26_SectorUnprotect: Failed to issue command.\n\r"); // Wait for transfer to finish AT26D_Wait(pAt26); } return 0; }
//------------------------------------------------------------------------------ /// Unprotects the contents of the serial flash device. /// Returns 0 if the device has been unprotected; otherwise returns /// SF_PROTECTED. /// \param pAt26 Pointer to an AT26 driver instance. //------------------------------------------------------------------------------ unsigned char AT26D_Unprotect(At26 *pAt26) { unsigned char status; SANITY_CHECK(pAt26); // Get the status register value to check the current protection status = AT26D_ReadStatus(pAt26); if ((status & AT26_STATUS_SWP) == AT26_STATUS_SWP_PROTNONE) { // Protection already disabled return 0; } // Check if sector protection registers are locked if ((status & AT26_STATUS_SPRL) == AT26_STATUS_SPRL_LOCKED) { // Unprotect sector protection registers by writing the status reg. AT26D_EnableWrite(pAt26); AT26D_WriteStatus(pAt26, 0); } // Perform a global unprotect command AT26D_EnableWrite(pAt26); #if defined(BOARD_AT26F004) AT26F004_Unprotect(pAt26); #endif AT26D_WriteStatus(pAt26, 0); // Check the new status status = AT26D_ReadStatus(pAt26); if ((status & (AT26_STATUS_SPRL | AT26_STATUS_SWP)) != 0) { return AT26_ERROR_PROTECTED; } else { return 0; } }
//------------------------------------------------------------------------------ /// 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. /// Returns 0 if successful; otherwise, returns AT26_ERROR_PROGRAM is there has /// been an error during the data programming. /// \param pAt26 Pointer to an AT26 driver instance. /// \param pData Data buffer. /// \param size Number of bytes in buffer. /// \param address Write address. //------------------------------------------------------------------------------ unsigned char AT26D_Write( At26 *pAt26, unsigned char *pData, unsigned int size, unsigned int address) { unsigned int pageSize; unsigned int writeSize; unsigned char error; unsigned char status; SANITY_CHECK(pAt26); SANITY_CHECK(pData); // Retrieve device page size pageSize = AT26_PageSize(pAt26); // 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 AT26D_EnableWrite(pAt26); // Program page error = AT26_SendCommand(pAt26, AT26_BYTE_PAGE_PROGRAM, 4, pData, writeSize, address, 0, 0); ASSERT(!error, "-F- AT26_WritePage: Failed to issue command.\n\r"); // Wait for transfer to finish AT26D_Wait(pAt26); // Poll the Serial flash status register until the operation is achieved AT26D_WaitReady(pAt26); // Make sure that write was without error status = AT26D_ReadStatus(pAt26); if ((status & AT26_STATUS_EPE) == AT26_STATUS_EPE_ERROR) { return AT26_ERROR_PROGRAM; } pData += writeSize; size -= writeSize; address += writeSize; } return 0; }
//------------------------------------------------------------------------------ /// 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. /// Returns 0 if successful; otherwise, returns AT26_ERROR_PROGRAM is there has /// been an error during the data programming. /// \param pAt26 Pointer to an AT26 driver instance. /// \param pData Data buffer. /// \param size Number of bytes in buffer. /// \param address Write address. //------------------------------------------------------------------------------ unsigned char AT26D_Write( At26 *pAt26, unsigned char *pData, unsigned int size, unsigned int address) { unsigned int pageSize; unsigned int writeSize; unsigned char error; #if !defined(BOARD_AT26F004) unsigned char status; #endif unsigned int i = 0; SANITY_CHECK(pAt26); SANITY_CHECK(pData); // Retrieve device page size pageSize = AT26_PageSize(pAt26); // Program one page after the other while (size > 0) { // Compute number of bytes to program in page #if defined(BOARD_AT26F004) writeSize = 1; #else writeSize = min(size, pageSize - (address % pageSize)); #endif // Enable critical write operation AT26D_EnableWrite(pAt26); if (AT26_ManId(pAt26) == SST_SPI_FLASH) { error = AT26_SendCommand(pAt26, AT26_SEQUENTIAL_PROGRAM_1, 4, pData, 2, address, 0, 0); ASSERT(!error, "-F- AT26_WritePage: Failed to issue command.\n\r"); /* Wait for transfer to finish */ AT26D_Wait(pAt26); /* Poll the Serial flash status register until the operation is achieved */ AT26D_WaitReady(pAt26); for (i = 2; i < pageSize; i += 2) { error = AT26_SendCommand(pAt26, AT26_SEQUENTIAL_PROGRAM_1, 1, pData + i, 2, 0, 0, 0); ASSERT(!error, "-F- AT26_WritePage: Failed to issue command.\n\r"); /* Wait for transfer to finish */ AT26D_Wait(pAt26); /* Poll the Serial flash status register until the operation is achieved */ AT26D_WaitReady(pAt26); } } else { // Program page error = AT26_SendCommand(pAt26, AT26_BYTE_PAGE_PROGRAM, 4, pData, writeSize, address, 0, 0); ASSERT(!error, "-F- AT26_WritePage: Failed to issue command.\n\r"); // Wait for transfer to finish AT26D_Wait(pAt26); // Poll the Serial flash status register until the operation is achieved AT26D_WaitReady(pAt26); } #if !defined(AT26F004) // Make sure that write was without error status = AT26D_ReadStatus(pAt26); if ((status & AT26_STATUS_EPE) == AT26_STATUS_EPE_ERROR) { return AT26_ERROR_PROGRAM; } #endif pData += writeSize; size -= writeSize; address += writeSize; } return 0; }