Driver for AT25SF041 SPI Flash Memory, just basic operations

Committer:
tpadovani
Date:
Thu Sep 17 19:53:27 2015 +0000
Revision:
1:e6ad2967ec95
Parent:
0:9225e2aef6b3
Credits header

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tpadovani 1:e6ad2967ec95 1 /**
tpadovani 1:e6ad2967ec95 2 * AT45DB161D module for arduino (C) Vincent
tpadovani 1:e6ad2967ec95 3 * SPI flash memory
tpadovani 1:e6ad2967ec95 4 * http://blog.blockos.org/?p=27
tpadovani 1:e6ad2967ec95 5 *
tpadovani 1:e6ad2967ec95 6 * bug fix by todotani
tpadovani 1:e6ad2967ec95 7 * http://todotani.cocolog-nifty.com/blog/2009/07/arduino-4cf4.html
tpadovani 1:e6ad2967ec95 8 *
tpadovani 1:e6ad2967ec95 9 * Modified for mbed, 2011 Suga.
tpadovani 1:e6ad2967ec95 10 *
tpadovani 1:e6ad2967ec95 11 * Adapted for AT25SF041 SPI flash memory, 2015 tpadovani.
tpadovani 1:e6ad2967ec95 12 */
tpadovani 1:e6ad2967ec95 13
tpadovani 0:9225e2aef6b3 14 #include "at25sf041.h"
tpadovani 0:9225e2aef6b3 15
tpadovani 0:9225e2aef6b3 16 /** CTOR **/
tpadovani 0:9225e2aef6b3 17 AT25SF041::AT25SF041(PinName mosi, PinName miso, PinName sclk, PinName cs)
tpadovani 0:9225e2aef6b3 18 : _spi(mosi, miso, sclk), _cs(cs)
tpadovani 0:9225e2aef6b3 19 {}
tpadovani 0:9225e2aef6b3 20
tpadovani 0:9225e2aef6b3 21 AT25SF041::AT25SF041(SPI &spi, PinName cs)
tpadovani 0:9225e2aef6b3 22 : _spi(spi), _cs(cs)
tpadovani 0:9225e2aef6b3 23 {}
tpadovani 0:9225e2aef6b3 24
tpadovani 0:9225e2aef6b3 25 /** DTOR **/
tpadovani 0:9225e2aef6b3 26 AT25SF041::~AT25SF041()
tpadovani 0:9225e2aef6b3 27 {}
tpadovani 0:9225e2aef6b3 28
tpadovani 0:9225e2aef6b3 29 /** Setup SPI and pinout **/
tpadovani 0:9225e2aef6b3 30 void AT25SF041::Init()
tpadovani 0:9225e2aef6b3 31 {
tpadovani 0:9225e2aef6b3 32 /* Disable device */
tpadovani 0:9225e2aef6b3 33 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 34
tpadovani 0:9225e2aef6b3 35 /* Setup SPI */
tpadovani 0:9225e2aef6b3 36 _spi.format(8, 0);
tpadovani 0:9225e2aef6b3 37
tpadovani 0:9225e2aef6b3 38 }
tpadovani 0:9225e2aef6b3 39
tpadovani 0:9225e2aef6b3 40 /**
tpadovani 0:9225e2aef6b3 41 * Read status register
tpadovani 0:9225e2aef6b3 42 * @return The content of the status register
tpadovani 0:9225e2aef6b3 43 **/
tpadovani 0:9225e2aef6b3 44 uint8_t AT25SF041::ReadStatusRegister(int n)
tpadovani 0:9225e2aef6b3 45 {
tpadovani 0:9225e2aef6b3 46 uint8_t status;
tpadovani 0:9225e2aef6b3 47
tpadovani 0:9225e2aef6b3 48 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 49 DF_CS_active;
tpadovani 0:9225e2aef6b3 50
tpadovani 0:9225e2aef6b3 51 /* Send status read command */
tpadovani 0:9225e2aef6b3 52 if(n == 1){
tpadovani 0:9225e2aef6b3 53 spi_transfer(READ_STATUS_REGISTER_BYTE_1);
tpadovani 0:9225e2aef6b3 54 } else{
tpadovani 0:9225e2aef6b3 55 spi_transfer(READ_STATUS_REGISTER_BYTE_2);
tpadovani 0:9225e2aef6b3 56 }
tpadovani 0:9225e2aef6b3 57 /* Get result with a dummy write */
tpadovani 0:9225e2aef6b3 58 status = spi_transfer(0x00);
tpadovani 0:9225e2aef6b3 59
tpadovani 0:9225e2aef6b3 60 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 61
tpadovani 0:9225e2aef6b3 62 return status;
tpadovani 0:9225e2aef6b3 63 }
tpadovani 0:9225e2aef6b3 64
tpadovani 0:9225e2aef6b3 65 void AT25SF041::WriteEnable()
tpadovani 0:9225e2aef6b3 66 {
tpadovani 0:9225e2aef6b3 67 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 68 DF_CS_active;
tpadovani 0:9225e2aef6b3 69
tpadovani 0:9225e2aef6b3 70 spi_transfer(WRITE_ENABLE);
tpadovani 0:9225e2aef6b3 71
tpadovani 0:9225e2aef6b3 72 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 73 }
tpadovani 0:9225e2aef6b3 74
tpadovani 0:9225e2aef6b3 75 void AT25SF041::WriteDisable()
tpadovani 0:9225e2aef6b3 76 {
tpadovani 0:9225e2aef6b3 77 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 78 DF_CS_active;
tpadovani 0:9225e2aef6b3 79
tpadovani 0:9225e2aef6b3 80 spi_transfer(WRITE_DISABLE);
tpadovani 0:9225e2aef6b3 81
tpadovani 0:9225e2aef6b3 82 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 83 }
tpadovani 0:9225e2aef6b3 84
tpadovani 0:9225e2aef6b3 85 /**
tpadovani 0:9225e2aef6b3 86 * Read Manufacturer and Device ID
tpadovani 0:9225e2aef6b3 87 * @note if id.extendedInfoLength is not equal to zero,
tpadovani 0:9225e2aef6b3 88 * successive calls to spi_transfer(0xff) will return
tpadovani 0:9225e2aef6b3 89 * the extended device information string bytes.
tpadovani 0:9225e2aef6b3 90 * @param id Pointer to the ID structure to initialize
tpadovani 0:9225e2aef6b3 91 **/
tpadovani 0:9225e2aef6b3 92 void AT25SF041::ReadManufacturerAndDeviceID(struct AT25SF041::ID *id)
tpadovani 0:9225e2aef6b3 93 {
tpadovani 0:9225e2aef6b3 94
tpadovani 0:9225e2aef6b3 95 DF_CS_inactive; /* Make sure to toggle CS signal in order */
tpadovani 0:9225e2aef6b3 96 DF_CS_active; /* to reset Dataflash command decoder */
tpadovani 0:9225e2aef6b3 97
tpadovani 0:9225e2aef6b3 98 /* Send status read command */
tpadovani 0:9225e2aef6b3 99 spi_transfer(READ_MANUFACTURER_AND_DEVICE_ID);
tpadovani 0:9225e2aef6b3 100
tpadovani 0:9225e2aef6b3 101 /* Manufacturer ID */
tpadovani 0:9225e2aef6b3 102 id->manufacturer = spi_transfer(0xff);
tpadovani 0:9225e2aef6b3 103 /* Device ID (part 1) */
tpadovani 0:9225e2aef6b3 104 id->device[0] = spi_transfer(0xff);
tpadovani 0:9225e2aef6b3 105 /* Device ID (part 2) */
tpadovani 0:9225e2aef6b3 106 id->device[1] = spi_transfer(0xff);
tpadovani 0:9225e2aef6b3 107
tpadovani 0:9225e2aef6b3 108 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 109 }
tpadovani 0:9225e2aef6b3 110
tpadovani 0:9225e2aef6b3 111 void AT25SF041::ReadArray(uint32_t address, uint32_t length, uint8_t *buffer)
tpadovani 0:9225e2aef6b3 112 {
tpadovani 0:9225e2aef6b3 113 DF_CS_inactive; /* Make sure to toggle CS signal in order */
tpadovani 0:9225e2aef6b3 114 DF_CS_active; /* to reset Dataflash command decoder */
tpadovani 0:9225e2aef6b3 115
tpadovani 0:9225e2aef6b3 116 /* Send opcode */
tpadovani 0:9225e2aef6b3 117 spi_transfer(READ_ARRAY_HF);
tpadovani 0:9225e2aef6b3 118
tpadovani 0:9225e2aef6b3 119 /* Address (page | offset) */
tpadovani 0:9225e2aef6b3 120 spi_transfer((uint8_t)((address >> 16) & 0xff));
tpadovani 0:9225e2aef6b3 121 spi_transfer((uint8_t)((address >> 8) & 0xff));
tpadovani 0:9225e2aef6b3 122 spi_transfer((uint8_t)(address & 0xff));
tpadovani 0:9225e2aef6b3 123 spi_transfer(0x00);
tpadovani 0:9225e2aef6b3 124
tpadovani 0:9225e2aef6b3 125 for(int i=0; i < length; i++){
tpadovani 0:9225e2aef6b3 126 buffer[i] = spi_transfer(0x00);
tpadovani 0:9225e2aef6b3 127 }
tpadovani 0:9225e2aef6b3 128
tpadovani 0:9225e2aef6b3 129 }
tpadovani 0:9225e2aef6b3 130
tpadovani 0:9225e2aef6b3 131 void AT25SF041::WriteArray(uint32_t address, uint32_t length, uint8_t *buffer){
tpadovani 0:9225e2aef6b3 132 DF_CS_inactive; /* Make sure to toggle CS signal in order */
tpadovani 0:9225e2aef6b3 133 DF_CS_active; /* to reset Dataflash command decoder */
tpadovani 0:9225e2aef6b3 134
tpadovani 0:9225e2aef6b3 135 /* Send opcode */
tpadovani 0:9225e2aef6b3 136 spi_transfer(PROGRAM);
tpadovani 0:9225e2aef6b3 137
tpadovani 0:9225e2aef6b3 138 /* Address (page | offset) */
tpadovani 0:9225e2aef6b3 139 spi_transfer((uint8_t)((address >> 16) & 0xff));
tpadovani 0:9225e2aef6b3 140 spi_transfer((uint8_t)((address >> 8) & 0xff));
tpadovani 0:9225e2aef6b3 141 spi_transfer((uint8_t)(address & 0xff));
tpadovani 0:9225e2aef6b3 142
tpadovani 0:9225e2aef6b3 143 for(int i=0; i < length; i++){
tpadovani 0:9225e2aef6b3 144 spi_transfer(buffer[i]);
tpadovani 0:9225e2aef6b3 145 }
tpadovani 0:9225e2aef6b3 146
tpadovani 0:9225e2aef6b3 147 EndAndWait();
tpadovani 0:9225e2aef6b3 148 }
tpadovani 0:9225e2aef6b3 149
tpadovani 0:9225e2aef6b3 150 /**
tpadovani 0:9225e2aef6b3 151 * Erase the entire chip memory. Sectors proteced or locked down will
tpadovani 0:9225e2aef6b3 152 * not be erased.
tpadovani 0:9225e2aef6b3 153 **/
tpadovani 0:9225e2aef6b3 154 void AT25SF041::ChipErase()
tpadovani 0:9225e2aef6b3 155 {
tpadovani 0:9225e2aef6b3 156 WriteEnable();
tpadovani 0:9225e2aef6b3 157
tpadovani 0:9225e2aef6b3 158 DF_CS_inactive;
tpadovani 0:9225e2aef6b3 159 DF_CS_active;
tpadovani 0:9225e2aef6b3 160
tpadovani 0:9225e2aef6b3 161 spi_transfer(CHIP_ERASE);
tpadovani 0:9225e2aef6b3 162
tpadovani 0:9225e2aef6b3 163 EndAndWait();
tpadovani 0:9225e2aef6b3 164
tpadovani 0:9225e2aef6b3 165 WriteDisable();
tpadovani 0:9225e2aef6b3 166 }
tpadovani 0:9225e2aef6b3 167
tpadovani 0:9225e2aef6b3 168 /**
tpadovani 0:9225e2aef6b3 169 * Perform a low-to-high transition on the CS pin and then poll
tpadovani 0:9225e2aef6b3 170 * the status register to check if the dataflash is busy.
tpadovani 0:9225e2aef6b3 171 **/
tpadovani 0:9225e2aef6b3 172 void AT25SF041::EndAndWait()
tpadovani 0:9225e2aef6b3 173 {
tpadovani 0:9225e2aef6b3 174 DF_CS_inactive; /* End current operation */
tpadovani 0:9225e2aef6b3 175 DF_CS_active; /* Some internal operation may occur
tpadovani 0:9225e2aef6b3 176 * (buffer to page transfer, page erase, etc... ) */
tpadovani 0:9225e2aef6b3 177
tpadovani 0:9225e2aef6b3 178 /* Wait for the chip to be ready */
tpadovani 0:9225e2aef6b3 179 while((ReadStatusRegister(1) & READY_BUSY) > 0);
tpadovani 0:9225e2aef6b3 180
tpadovani 0:9225e2aef6b3 181 DF_CS_inactive; /* Release SPI Bus */
tpadovani 0:9225e2aef6b3 182 }