SPI Flash memory

Dependents:   AT45DB161D SPIFLASH_AT45DB n-bed_AT45DB161E AT45DB161D

Committer:
okini3939
Date:
Thu Sep 15 15:09:56 2011 +0000
Revision:
1:b379e16fdf6f
Parent:
0:2e953bbaf3a5
SPI Flash memory

AT45DB081D, AT45DB161D, AT45DB321D

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:2e953bbaf3a5 1 /**
okini3939 0:2e953bbaf3a5 2 * @file at45db161d.h
okini3939 0:2e953bbaf3a5 3 * @brief AT45DB161D module
okini3939 0:2e953bbaf3a5 4 **/
okini3939 0:2e953bbaf3a5 5 #ifndef AT45DB161D_H
okini3939 0:2e953bbaf3a5 6 #define AT45DB161D_H
okini3939 0:2e953bbaf3a5 7
okini3939 0:2e953bbaf3a5 8 #include "mbed.h"
okini3939 0:2e953bbaf3a5 9
okini3939 0:2e953bbaf3a5 10 extern "C" {
okini3939 0:2e953bbaf3a5 11
okini3939 0:2e953bbaf3a5 12 //#include <avr/pgmspace.h>
okini3939 0:2e953bbaf3a5 13 #include <inttypes.h>
okini3939 0:2e953bbaf3a5 14 //#include "WConstants.h"
okini3939 0:2e953bbaf3a5 15
okini3939 0:2e953bbaf3a5 16 };
okini3939 0:2e953bbaf3a5 17
okini3939 0:2e953bbaf3a5 18 #include "at45db161d_commands.h"
okini3939 0:2e953bbaf3a5 19
okini3939 0:2e953bbaf3a5 20 /**
okini3939 0:2e953bbaf3a5 21 * @defgroup AT45DB161D AT45DB161D module
okini3939 0:2e953bbaf3a5 22 * @{
okini3939 0:2e953bbaf3a5 23 **/
okini3939 0:2e953bbaf3a5 24
okini3939 0:2e953bbaf3a5 25 /**
okini3939 0:2e953bbaf3a5 26 * @defgroup SPI SPI pinout and transfert function
okini3939 0:2e953bbaf3a5 27 * @{
okini3939 0:2e953bbaf3a5 28 **/
okini3939 0:2e953bbaf3a5 29 #ifndef SPI
okini3939 0:2e953bbaf3a5 30 /**
okini3939 0:2e953bbaf3a5 31 * @defgroup SPI_Pinout SPI pinout
okini3939 0:2e953bbaf3a5 32 * @{
okini3939 0:2e953bbaf3a5 33 **/
okini3939 0:2e953bbaf3a5 34 /** Serial input (SI) **/
okini3939 0:2e953bbaf3a5 35 #define DATAOUT 11
okini3939 0:2e953bbaf3a5 36 /** Serial output (SO) **/
okini3939 0:2e953bbaf3a5 37 #define DATAIN 12
okini3939 0:2e953bbaf3a5 38 /** Serial clock (SCK) **/
okini3939 0:2e953bbaf3a5 39 #define SPICLOCK 13
okini3939 0:2e953bbaf3a5 40 /** Chip select (CS) **/
okini3939 0:2e953bbaf3a5 41 #define SLAVESELECT 10
okini3939 0:2e953bbaf3a5 42 /** Reset (Reset) **/
okini3939 0:2e953bbaf3a5 43 #define RESET 8
okini3939 0:2e953bbaf3a5 44 /** Write protect (WP) **/
okini3939 0:2e953bbaf3a5 45 #define WP 7
okini3939 0:2e953bbaf3a5 46 /**
okini3939 0:2e953bbaf3a5 47 * @}
okini3939 0:2e953bbaf3a5 48 **/
okini3939 0:2e953bbaf3a5 49
okini3939 0:2e953bbaf3a5 50 /**
okini3939 0:2e953bbaf3a5 51 * @fn inline uint8_t spi_transfer(uint8_t data)
okini3939 0:2e953bbaf3a5 52 * @brief Transfer a byte via spi
okini3939 0:2e953bbaf3a5 53 * @param data Data to transfer via SPI
okini3939 0:2e953bbaf3a5 54 * @return The content of the SPI data register (SPDR)
okini3939 0:2e953bbaf3a5 55 **/
okini3939 0:2e953bbaf3a5 56 /*
okini3939 0:2e953bbaf3a5 57 inline uint8_t spi_transfer(uint8_t data)
okini3939 0:2e953bbaf3a5 58 {
okini3939 0:2e953bbaf3a5 59 SPDR = data;
okini3939 0:2e953bbaf3a5 60 while(!(SPSR & (1 << SPIF))) ;
okini3939 0:2e953bbaf3a5 61 return SPDR;
okini3939 0:2e953bbaf3a5 62 }
okini3939 0:2e953bbaf3a5 63 */
okini3939 0:2e953bbaf3a5 64 #define spi_transfer(data) _spi.write(data)
okini3939 0:2e953bbaf3a5 65
okini3939 0:2e953bbaf3a5 66 /** De-assert CS **/
okini3939 0:2e953bbaf3a5 67 //#define DF_CS_inactive digitalWrite(SLAVESELECT,HIGH)
okini3939 0:2e953bbaf3a5 68 #define DF_CS_inactive _cs = 1
okini3939 0:2e953bbaf3a5 69 /** Assert CS **/
okini3939 0:2e953bbaf3a5 70 //#define DF_CS_active digitalWrite(SLAVESELECT,LOW)
okini3939 0:2e953bbaf3a5 71 #define DF_CS_active _cs = 0
okini3939 0:2e953bbaf3a5 72
okini3939 0:2e953bbaf3a5 73 #endif /* SPI */
okini3939 0:2e953bbaf3a5 74 /**
okini3939 0:2e953bbaf3a5 75 * @}
okini3939 0:2e953bbaf3a5 76 **/
okini3939 0:2e953bbaf3a5 77
okini3939 0:2e953bbaf3a5 78 /**
okini3939 0:2e953bbaf3a5 79 * @defgroup STATUS_REGISTER_FORMAT Status register format
okini3939 0:2e953bbaf3a5 80 * @{
okini3939 0:2e953bbaf3a5 81 **/
okini3939 0:2e953bbaf3a5 82 /**
okini3939 0:2e953bbaf3a5 83 * Ready/busy status is indicated using bit 7 of the status register.
okini3939 0:2e953bbaf3a5 84 * If bit 7 is a 1, then the device is not busy and is ready to accept
okini3939 0:2e953bbaf3a5 85 * the next command. If bit 7 is a 0, then the device is in a busy
okini3939 0:2e953bbaf3a5 86 * state.
okini3939 0:2e953bbaf3a5 87 **/
okini3939 0:2e953bbaf3a5 88 #define READY_BUSY 0x80
okini3939 0:2e953bbaf3a5 89 /**
okini3939 0:2e953bbaf3a5 90 * Result of the most recent Memory Page to Buffer Compare operation.
okini3939 0:2e953bbaf3a5 91 * If this bit is equal to 0, then the data in the main memory page
okini3939 0:2e953bbaf3a5 92 * matches the data in the buffer. If it's 1 then at least 1 byte in
okini3939 0:2e953bbaf3a5 93 * the main memory page does not match the data in the buffer.
okini3939 0:2e953bbaf3a5 94 **/
okini3939 0:2e953bbaf3a5 95 #define COMPARE 0x40
okini3939 0:2e953bbaf3a5 96 /**
okini3939 0:2e953bbaf3a5 97 * Bit 1 in the Status Register is used to provide information to the
okini3939 0:2e953bbaf3a5 98 * user whether or not the sector protection has been enabled or
okini3939 0:2e953bbaf3a5 99 * disabled, either by software-controlled method or
okini3939 0:2e953bbaf3a5 100 * hardware-controlled method. 1 means that the sector protection has
okini3939 0:2e953bbaf3a5 101 * been enabled and 0 that it has been disabled.
okini3939 0:2e953bbaf3a5 102 **/
okini3939 0:2e953bbaf3a5 103 #define PROTECT 0x02
okini3939 0:2e953bbaf3a5 104 /**
okini3939 0:2e953bbaf3a5 105 * Bit 0 indicates wether the page size of the main memory array is
okini3939 0:2e953bbaf3a5 106 * configured for "power of 2" binary page size (512 bytes) (bit=1) or
okini3939 0:2e953bbaf3a5 107 * standard DataFlash page size (528 bytes) (bit=0).
okini3939 0:2e953bbaf3a5 108 **/
okini3939 0:2e953bbaf3a5 109 #define PAGE_SIZE 0x01
okini3939 0:2e953bbaf3a5 110 /**
okini3939 0:2e953bbaf3a5 111 * Bits 5, 4, 3 and 2 indicates the device density. The decimal value
okini3939 0:2e953bbaf3a5 112 * of these four binary bits does not equate to the device density; the
okini3939 0:2e953bbaf3a5 113 * four bits represent a combinational code relating to differing
okini3939 0:2e953bbaf3a5 114 * densities of DataFlash devices. The device density is not the same
okini3939 0:2e953bbaf3a5 115 * as the density code indicated in the JEDEC device ID information.
okini3939 0:2e953bbaf3a5 116 * The device density is provided only for backward compatibility.
okini3939 0:2e953bbaf3a5 117 **/
okini3939 0:2e953bbaf3a5 118 #define DEVICE_DENSITY 0x2C
okini3939 0:2e953bbaf3a5 119 /**
okini3939 0:2e953bbaf3a5 120 * @}
okini3939 0:2e953bbaf3a5 121 **/
okini3939 0:2e953bbaf3a5 122
okini3939 0:2e953bbaf3a5 123 /**
okini3939 0:2e953bbaf3a5 124 * @brief at45db161d module
okini3939 0:2e953bbaf3a5 125 * @todo
okini3939 0:2e953bbaf3a5 126 * - TESTS!
okini3939 0:2e953bbaf3a5 127 * - Protection and Security Commands
okini3939 0:2e953bbaf3a5 128 * - Auto Page Rewrite through Buffer 1
okini3939 0:2e953bbaf3a5 129 * - Auto Page Rewrite through Buffer 2
okini3939 0:2e953bbaf3a5 130 **/
okini3939 0:2e953bbaf3a5 131 class ATD45DB161D
okini3939 0:2e953bbaf3a5 132 {
okini3939 0:2e953bbaf3a5 133 public:
okini3939 0:2e953bbaf3a5 134 /**
okini3939 0:2e953bbaf3a5 135 * @brief ID structure
okini3939 0:2e953bbaf3a5 136 * This structure contains various informations about the
okini3939 0:2e953bbaf3a5 137 * dataflash chip being used.
okini3939 0:2e953bbaf3a5 138 **/
okini3939 0:2e953bbaf3a5 139 struct ID
okini3939 0:2e953bbaf3a5 140 {
okini3939 0:2e953bbaf3a5 141 uint8_t manufacturer; /**< Manufacturer id **/
okini3939 0:2e953bbaf3a5 142 uint8_t device[2]; /**< Device id **/
okini3939 0:2e953bbaf3a5 143 uint8_t extendedInfoLength; /**< Extended device information string length **/
okini3939 0:2e953bbaf3a5 144 };
okini3939 0:2e953bbaf3a5 145
okini3939 0:2e953bbaf3a5 146 public:
okini3939 0:2e953bbaf3a5 147 /** CTOR **/
okini3939 0:2e953bbaf3a5 148 ATD45DB161D(PinName mosi, PinName miso, PinName sclk, PinName cs);
okini3939 0:2e953bbaf3a5 149 ATD45DB161D(SPI &spi, PinName cs);
okini3939 0:2e953bbaf3a5 150 /** DTOR **/
okini3939 0:2e953bbaf3a5 151 ~ATD45DB161D();
okini3939 0:2e953bbaf3a5 152
okini3939 0:2e953bbaf3a5 153 /** Setup SPI and pinout **/
okini3939 0:2e953bbaf3a5 154 void Init();
okini3939 0:2e953bbaf3a5 155
okini3939 0:2e953bbaf3a5 156 /**
okini3939 0:2e953bbaf3a5 157 * Read status register
okini3939 0:2e953bbaf3a5 158 * @return The content of the status register
okini3939 0:2e953bbaf3a5 159 * **/
okini3939 0:2e953bbaf3a5 160 uint8_t ReadStatusRegister();
okini3939 0:2e953bbaf3a5 161
okini3939 0:2e953bbaf3a5 162 /**
okini3939 0:2e953bbaf3a5 163 * Read Manufacturer and Device ID
okini3939 0:2e953bbaf3a5 164 * @note if id.extendedInfoLength is not equal to zero,
okini3939 0:2e953bbaf3a5 165 * successive calls to spi_transfer(0xff) will return
okini3939 0:2e953bbaf3a5 166 * the extended device information string bytes.
okini3939 0:2e953bbaf3a5 167 * @param id Pointer to the ID structure to initialize
okini3939 0:2e953bbaf3a5 168 **/
okini3939 0:2e953bbaf3a5 169 void ReadManufacturerAndDeviceID(struct ATD45DB161D::ID *id);
okini3939 0:2e953bbaf3a5 170
okini3939 0:2e953bbaf3a5 171 /**
okini3939 0:2e953bbaf3a5 172 * A main memory page read allows the user to read data directly from
okini3939 0:2e953bbaf3a5 173 * any one of the 4096 pages in the main memory, bypassing both of the
okini3939 0:2e953bbaf3a5 174 * data buffers and leaving the contents of the buffers unchanged.
okini3939 0:2e953bbaf3a5 175 * @param page Page of the main memory to read
okini3939 0:2e953bbaf3a5 176 * @param offset Starting byte address within the page
okini3939 0:2e953bbaf3a5 177 **/
okini3939 0:2e953bbaf3a5 178 void ReadMainMemoryPage(uint16_t page, uint16_t offset);
okini3939 0:2e953bbaf3a5 179
okini3939 0:2e953bbaf3a5 180 /**
okini3939 0:2e953bbaf3a5 181 * Sequentially read a continuous stream of data.
okini3939 0:2e953bbaf3a5 182 * @param page Page of the main memory where the sequential read will start
okini3939 0:2e953bbaf3a5 183 * @param offset Starting byte address within the page
okini3939 0:2e953bbaf3a5 184 * @param low If true the read operation will be performed in low speed mode (and in high speed mode if it's false).
okini3939 0:2e953bbaf3a5 185 * @note The legacy mode is not currently supported
okini3939 0:2e953bbaf3a5 186 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 187 **/
okini3939 0:2e953bbaf3a5 188 void ContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low);
okini3939 0:2e953bbaf3a5 189
okini3939 0:2e953bbaf3a5 190 /**
okini3939 0:2e953bbaf3a5 191 * Read the content of one of the SRAM data buffers (in low or high speed mode).
okini3939 0:2e953bbaf3a5 192 * @param bufferNum Buffer to read (1 or 2)
okini3939 0:2e953bbaf3a5 193 * @param offset Starting byte within the buffer
okini3939 0:2e953bbaf3a5 194 * @param low If true the read operation will be performed in low speed mode (and in high speed mode if it's false).
okini3939 0:2e953bbaf3a5 195 **/
okini3939 0:2e953bbaf3a5 196 void BufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low);
okini3939 0:2e953bbaf3a5 197
okini3939 0:2e953bbaf3a5 198 /**
okini3939 0:2e953bbaf3a5 199 * Write data to one of the SRAM data buffers. Any further call to
okini3939 0:2e953bbaf3a5 200 * spi_tranfer will return bytes contained in the data buffer until
okini3939 0:2e953bbaf3a5 201 * a low-to-high transition is detected on the CS pin. If the end of
okini3939 0:2e953bbaf3a5 202 * the data buffer is reached, the device will wrap around back to the
okini3939 0:2e953bbaf3a5 203 * beginning of the buffer.
okini3939 0:2e953bbaf3a5 204 * @param bufferNum Buffer to read (1 or 2)
okini3939 0:2e953bbaf3a5 205 * @param offset Starting byte within the buffer
okini3939 0:2e953bbaf3a5 206 **/
okini3939 0:2e953bbaf3a5 207 void BufferWrite(uint8_t bufferNum, uint16_t offset);
okini3939 0:2e953bbaf3a5 208
okini3939 0:2e953bbaf3a5 209 /**
okini3939 0:2e953bbaf3a5 210 * Transfer data from buffer 1 or 2 to main memory page.
okini3939 0:2e953bbaf3a5 211 * @param bufferNum Buffer to use (1 or 2)
okini3939 0:2e953bbaf3a5 212 * @param page Page where the content of the buffer will transfered
okini3939 0:2e953bbaf3a5 213 * @param erase If set the page will be first erased before the buffer transfer.
okini3939 0:2e953bbaf3a5 214 * @note If erase is equal to zero, the page must have been previously erased using one of the erase command (Page or Block Erase).
okini3939 0:2e953bbaf3a5 215 **/
okini3939 0:2e953bbaf3a5 216 void BufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase);
okini3939 0:2e953bbaf3a5 217
okini3939 0:2e953bbaf3a5 218 /**
okini3939 0:2e953bbaf3a5 219 * Transfer a page of data from main memory to buffer 1 or 2.
okini3939 0:2e953bbaf3a5 220 * @param page Main memory page to transfer
okini3939 0:2e953bbaf3a5 221 * @param buffer Buffer (1 or 2) where the data will be written
okini3939 0:2e953bbaf3a5 222 **/
okini3939 0:2e953bbaf3a5 223 void PageToBuffer(uint16_t page, uint8_t bufferNum);
okini3939 0:2e953bbaf3a5 224
okini3939 0:2e953bbaf3a5 225 /**
okini3939 0:2e953bbaf3a5 226 * Erase a page in the main memory array.
okini3939 0:2e953bbaf3a5 227 * @param page Page to erase
okini3939 0:2e953bbaf3a5 228 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 229 **/
okini3939 0:2e953bbaf3a5 230 void PageErase(uint16_t page);
okini3939 0:2e953bbaf3a5 231
okini3939 0:2e953bbaf3a5 232 /**
okini3939 0:2e953bbaf3a5 233 * Erase a block of eight pages at one time.
okini3939 0:2e953bbaf3a5 234 * @param block Index of the block to erase
okini3939 0:2e953bbaf3a5 235 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 236 **/
okini3939 0:2e953bbaf3a5 237 void BlockErase(uint16_t block);
okini3939 0:2e953bbaf3a5 238
okini3939 0:2e953bbaf3a5 239 /**
okini3939 0:2e953bbaf3a5 240 * Erase a sector in main memory. There are 16 sector on the
okini3939 0:2e953bbaf3a5 241 * at45db161d and only one can be erased at one time.
okini3939 0:2e953bbaf3a5 242 * @param sector Sector to erase
okini3939 0:2e953bbaf3a5 243 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 244 **/
okini3939 0:2e953bbaf3a5 245 void SectoreErase(uint8_t sector);
okini3939 0:2e953bbaf3a5 246
okini3939 0:2e953bbaf3a5 247 /**
okini3939 0:2e953bbaf3a5 248 * Erase the entire chip memory. Sectors proteced or locked down will
okini3939 0:2e953bbaf3a5 249 * not be erased.
okini3939 0:2e953bbaf3a5 250 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 251 **/
okini3939 0:2e953bbaf3a5 252 void ChipErase();
okini3939 0:2e953bbaf3a5 253
okini3939 0:2e953bbaf3a5 254 /**
okini3939 0:2e953bbaf3a5 255 * This a combination of Buffer Write and Buffer to Page with
okini3939 0:2e953bbaf3a5 256 * Built-in Erase.
okini3939 0:2e953bbaf3a5 257 * @note You must call EndAndWait in order to start transfering data from buffer to page
okini3939 0:2e953bbaf3a5 258 * @param page Page where the content of the buffer will transfered
okini3939 0:2e953bbaf3a5 259 * @param offset Starting byte address within the buffer
okini3939 0:2e953bbaf3a5 260 * @param bufferNum Buffer to use (1 or 2)
okini3939 0:2e953bbaf3a5 261 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 262 **/
okini3939 0:2e953bbaf3a5 263 void BeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum);
okini3939 0:2e953bbaf3a5 264
okini3939 0:2e953bbaf3a5 265 /**
okini3939 0:2e953bbaf3a5 266 * Perform a low-to-high transition on the CS pin and then poll
okini3939 0:2e953bbaf3a5 267 * the status register to check if the dataflash is busy.
okini3939 0:2e953bbaf3a5 268 **/
okini3939 0:2e953bbaf3a5 269 void EndAndWait();
okini3939 0:2e953bbaf3a5 270
okini3939 0:2e953bbaf3a5 271 /**
okini3939 0:2e953bbaf3a5 272 * Compare a page of data in main memory to the data in buffer 1 or 2.
okini3939 0:2e953bbaf3a5 273 * @param page Page to test
okini3939 0:2e953bbaf3a5 274 * @param bufferNum Buffer number
okini3939 0:2e953bbaf3a5 275 * @return
okini3939 0:2e953bbaf3a5 276 * - 1 if the page and the buffer contains the same data
okini3939 0:2e953bbaf3a5 277 * - 0 else
okini3939 0:2e953bbaf3a5 278 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 279 **/
okini3939 0:2e953bbaf3a5 280 int8_t ComparePageToBuffer(uint16_t page, uint8_t bufferNum);
okini3939 0:2e953bbaf3a5 281
okini3939 0:2e953bbaf3a5 282 /**
okini3939 0:2e953bbaf3a5 283 * Put the device into the lowest power consumption mode.
okini3939 0:2e953bbaf3a5 284 * Once the device has entered the Deep Power-down mode, all
okini3939 0:2e953bbaf3a5 285 * instructions are ignored except the Resume from Deep
okini3939 0:2e953bbaf3a5 286 * Power-down command.
okini3939 0:2e953bbaf3a5 287 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 288 **/
okini3939 0:2e953bbaf3a5 289 void DeepPowerDown();
okini3939 0:2e953bbaf3a5 290
okini3939 0:2e953bbaf3a5 291 /**
okini3939 0:2e953bbaf3a5 292 * Takes the device out of Deep Power-down mode.
okini3939 0:2e953bbaf3a5 293 * @warning UNTESTED
okini3939 0:2e953bbaf3a5 294 **/
okini3939 0:2e953bbaf3a5 295 void ResumeFromDeepPowerDown();
okini3939 0:2e953bbaf3a5 296
okini3939 0:2e953bbaf3a5 297 private:
okini3939 0:2e953bbaf3a5 298 /* Nothing atm but who knows... */
okini3939 0:2e953bbaf3a5 299
okini3939 0:2e953bbaf3a5 300 SPI _spi;
okini3939 0:2e953bbaf3a5 301 DigitalOut _cs;
okini3939 0:2e953bbaf3a5 302 };
okini3939 0:2e953bbaf3a5 303
okini3939 0:2e953bbaf3a5 304 /**
okini3939 0:2e953bbaf3a5 305 * @}
okini3939 0:2e953bbaf3a5 306 **/
okini3939 0:2e953bbaf3a5 307
okini3939 0:2e953bbaf3a5 308 #endif /* AT45DB161D_H */