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