Driver for AT25SF041 SPI Flash Memory, just basic operations
at25sf041.cpp
- Committer:
- tpadovani
- Date:
- 2015-09-17
- Revision:
- 0:9225e2aef6b3
- Child:
- 1:e6ad2967ec95
File content as of revision 0:9225e2aef6b3:
#include "at25sf041.h" /** CTOR **/ AT25SF041::AT25SF041(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) {} AT25SF041::AT25SF041(SPI &spi, PinName cs) : _spi(spi), _cs(cs) {} /** DTOR **/ AT25SF041::~AT25SF041() {} /** Setup SPI and pinout **/ void AT25SF041::Init() { /* Disable device */ DF_CS_inactive; /* Setup SPI */ _spi.format(8, 0); } /** * Read status register * @return The content of the status register **/ uint8_t AT25SF041::ReadStatusRegister(int n) { uint8_t status; DF_CS_inactive; DF_CS_active; /* Send status read command */ if(n == 1){ spi_transfer(READ_STATUS_REGISTER_BYTE_1); } else{ spi_transfer(READ_STATUS_REGISTER_BYTE_2); } /* Get result with a dummy write */ status = spi_transfer(0x00); DF_CS_inactive; return status; } void AT25SF041::WriteEnable() { DF_CS_inactive; DF_CS_active; spi_transfer(WRITE_ENABLE); DF_CS_inactive; } void AT25SF041::WriteDisable() { DF_CS_inactive; DF_CS_active; spi_transfer(WRITE_DISABLE); DF_CS_inactive; } /** * Read Manufacturer and Device ID * @note if id.extendedInfoLength is not equal to zero, * successive calls to spi_transfer(0xff) will return * the extended device information string bytes. * @param id Pointer to the ID structure to initialize **/ void AT25SF041::ReadManufacturerAndDeviceID(struct AT25SF041::ID *id) { DF_CS_inactive; /* Make sure to toggle CS signal in order */ DF_CS_active; /* to reset Dataflash command decoder */ /* Send status read command */ spi_transfer(READ_MANUFACTURER_AND_DEVICE_ID); /* Manufacturer ID */ id->manufacturer = spi_transfer(0xff); /* Device ID (part 1) */ id->device[0] = spi_transfer(0xff); /* Device ID (part 2) */ id->device[1] = spi_transfer(0xff); DF_CS_inactive; } void AT25SF041::ReadArray(uint32_t address, uint32_t length, uint8_t *buffer) { DF_CS_inactive; /* Make sure to toggle CS signal in order */ DF_CS_active; /* to reset Dataflash command decoder */ /* Send opcode */ spi_transfer(READ_ARRAY_HF); /* Address (page | offset) */ spi_transfer((uint8_t)((address >> 16) & 0xff)); spi_transfer((uint8_t)((address >> 8) & 0xff)); spi_transfer((uint8_t)(address & 0xff)); spi_transfer(0x00); for(int i=0; i < length; i++){ buffer[i] = spi_transfer(0x00); } } void AT25SF041::WriteArray(uint32_t address, uint32_t length, uint8_t *buffer){ DF_CS_inactive; /* Make sure to toggle CS signal in order */ DF_CS_active; /* to reset Dataflash command decoder */ /* Send opcode */ spi_transfer(PROGRAM); /* Address (page | offset) */ spi_transfer((uint8_t)((address >> 16) & 0xff)); spi_transfer((uint8_t)((address >> 8) & 0xff)); spi_transfer((uint8_t)(address & 0xff)); for(int i=0; i < length; i++){ spi_transfer(buffer[i]); } EndAndWait(); } /** * Erase the entire chip memory. Sectors proteced or locked down will * not be erased. **/ void AT25SF041::ChipErase() { WriteEnable(); DF_CS_inactive; DF_CS_active; spi_transfer(CHIP_ERASE); EndAndWait(); WriteDisable(); } /** * Perform a low-to-high transition on the CS pin and then poll * the status register to check if the dataflash is busy. **/ void AT25SF041::EndAndWait() { DF_CS_inactive; /* End current operation */ DF_CS_active; /* Some internal operation may occur * (buffer to page transfer, page erase, etc... ) */ /* Wait for the chip to be ready */ while((ReadStatusRegister(1) & READY_BUSY) > 0); DF_CS_inactive; /* Release SPI Bus */ }