TRC 630401

Committer:
supawat
Date:
Thu Apr 02 03:41:57 2020 +0000
Revision:
0:0b6c94a21953
VMS3GTRC vers. 630401

Who changed what in which revision?

UserRevisionLine numberNew contents of line
supawat 0:0b6c94a21953 1 #include "at45db161e.h"
supawat 0:0b6c94a21953 2
supawat 0:0b6c94a21953 3 //extern Serial debug_pc;
supawat 0:0b6c94a21953 4
supawat 0:0b6c94a21953 5 ATD45DB161E::ATD45DB161E(PinName mosi, PinName miso, PinName clk, PinName cs)
supawat 0:0b6c94a21953 6 : _spi(mosi, miso, clk), _cs(cs) {}
supawat 0:0b6c94a21953 7
supawat 0:0b6c94a21953 8 ATD45DB161E::ATD45DB161E(SPI &spi, PinName cs)
supawat 0:0b6c94a21953 9 : _spi(spi), _cs(cs) {}
supawat 0:0b6c94a21953 10 /** Setup SPI **/
supawat 0:0b6c94a21953 11 void ATD45DB161E::initial_chip(void)
supawat 0:0b6c94a21953 12 {
supawat 0:0b6c94a21953 13 _spi.format(8,0);
supawat 0:0b6c94a21953 14 _spi.frequency(16000000);
supawat 0:0b6c94a21953 15 _set_pageszie_to_binary();
supawat 0:0b6c94a21953 16 _wake_flag = true;
supawat 0:0b6c94a21953 17 _deepsleep_flag = false;
supawat 0:0b6c94a21953 18 _udeepsleep_flag = false;
supawat 0:0b6c94a21953 19 }
supawat 0:0b6c94a21953 20
supawat 0:0b6c94a21953 21 void ATD45DB161E::_select() {
supawat 0:0b6c94a21953 22 // ensure that the SPI port is set up correctly still
supawat 0:0b6c94a21953 23 // This allows SPI channel sharing
supawat 0:0b6c94a21953 24 _spi.format(8,0);
supawat 0:0b6c94a21953 25 _spi.frequency(16000000);
supawat 0:0b6c94a21953 26 _cs = 0;
supawat 0:0b6c94a21953 27 }
supawat 0:0b6c94a21953 28
supawat 0:0b6c94a21953 29 /*
supawat 0:0b6c94a21953 30 * Deselect simply returns nCS to high
supawat 0:0b6c94a21953 31 */
supawat 0:0b6c94a21953 32 void ATD45DB161E::_deselect() {
supawat 0:0b6c94a21953 33 _cs = 1;
supawat 0:0b6c94a21953 34 }
supawat 0:0b6c94a21953 35
supawat 0:0b6c94a21953 36 /*
supawat 0:0b6c94a21953 37 * Sends the three lest significant bytes of the supplied address
supawat 0:0b6c94a21953 38 */
supawat 0:0b6c94a21953 39
supawat 0:0b6c94a21953 40 void ATD45DB161E::_sendaddr (unsigned int address) {
supawat 0:0b6c94a21953 41 _spi.write(address >> 16);
supawat 0:0b6c94a21953 42 _spi.write(address >> 8);
supawat 0:0b6c94a21953 43 _spi.write(address);
supawat 0:0b6c94a21953 44 }
supawat 0:0b6c94a21953 45
supawat 0:0b6c94a21953 46 /**
supawat 0:0b6c94a21953 47 * Set page size of the flash chip into deep power down mode.
supawat 0:0b6c94a21953 48 **/
supawat 0:0b6c94a21953 49 void ATD45DB161E::_set_pageszie_to_binary(void)
supawat 0:0b6c94a21953 50 {
supawat 0:0b6c94a21953 51 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 52 _select();
supawat 0:0b6c94a21953 53 _spi.write(0x3d);
supawat 0:0b6c94a21953 54 _spi.write(0x2a);
supawat 0:0b6c94a21953 55 _spi.write(0x80);
supawat 0:0b6c94a21953 56 _spi.write(0xa6);
supawat 0:0b6c94a21953 57 _deselect();
supawat 0:0b6c94a21953 58 _pollbusy(); // waitting for the operation complete.
supawat 0:0b6c94a21953 59 }
supawat 0:0b6c94a21953 60
supawat 0:0b6c94a21953 61
supawat 0:0b6c94a21953 62 /*
supawat 0:0b6c94a21953 63 * return the Status
supawat 0:0b6c94a21953 64 */
supawat 0:0b6c94a21953 65
supawat 0:0b6c94a21953 66 int ATD45DB161E::ReadStatusRegister(void) {
supawat 0:0b6c94a21953 67 int status = 0;
supawat 0:0b6c94a21953 68 _select();
supawat 0:0b6c94a21953 69 _spi.write(0xd7);
supawat 0:0b6c94a21953 70 status = _spi.write(0x00);
supawat 0:0b6c94a21953 71 _deselect();
supawat 0:0b6c94a21953 72 return status;
supawat 0:0b6c94a21953 73 }
supawat 0:0b6c94a21953 74
supawat 0:0b6c94a21953 75 /*
supawat 0:0b6c94a21953 76 * Make sure the Flash isnt already doing something
supawat 0:0b6c94a21953 77 */
supawat 0:0b6c94a21953 78 void ATD45DB161E::_pollbusy() {
supawat 0:0b6c94a21953 79 volatile int busy = 1;
supawat 0:0b6c94a21953 80 while (busy) {
supawat 0:0b6c94a21953 81 if(!_wake_flag)
supawat 0:0b6c94a21953 82 {
supawat 0:0b6c94a21953 83 if(_deepsleep_flag) DeepPowerDown(false);
supawat 0:0b6c94a21953 84 else if(_udeepsleep_flag) UltraDeepPowerDown(false);
supawat 0:0b6c94a21953 85 }
supawat 0:0b6c94a21953 86 // if bit 7 is set, we can proceed
supawat 0:0b6c94a21953 87 if ( ReadStatusRegister() & 0x80 ) {
supawat 0:0b6c94a21953 88 busy = 0;}
supawat 0:0b6c94a21953 89 }
supawat 0:0b6c94a21953 90 }
supawat 0:0b6c94a21953 91
supawat 0:0b6c94a21953 92 void ATD45DB161E::pollbusy() {
supawat 0:0b6c94a21953 93 _pollbusy();
supawat 0:0b6c94a21953 94 }
supawat 0:0b6c94a21953 95
supawat 0:0b6c94a21953 96 /**
supawat 0:0b6c94a21953 97 * Read Manufacturer and Device ID
supawat 0:0b6c94a21953 98 * @note if id.extendedInfoLength is not equal to zero,
supawat 0:0b6c94a21953 99 * successive calls to spi_transfer(0xff) will return
supawat 0:0b6c94a21953 100 * the extended device information string bytes.
supawat 0:0b6c94a21953 101 * @param id Pointer to the ID structure to initialize
supawat 0:0b6c94a21953 102 **/
supawat 0:0b6c94a21953 103 void ATD45DB161E::ReadManufacturerAndDeviceID(struct flash_id *id)
supawat 0:0b6c94a21953 104 {
supawat 0:0b6c94a21953 105 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 106 _select();
supawat 0:0b6c94a21953 107 /* Send status read command */
supawat 0:0b6c94a21953 108 _spi.write(0x9f);
supawat 0:0b6c94a21953 109 /* Manufacturer ID */
supawat 0:0b6c94a21953 110 id->manufacturer = _spi.write(0x00);
supawat 0:0b6c94a21953 111 /* Device ID (part 1) */
supawat 0:0b6c94a21953 112 id->device[0] = _spi.write(0x00);
supawat 0:0b6c94a21953 113 /* Device ID (part 2) */
supawat 0:0b6c94a21953 114 id->device[1] = _spi.write(0x00);
supawat 0:0b6c94a21953 115 /* Extended Device Information String Length */
supawat 0:0b6c94a21953 116 id->extendedInfoLength = _spi.write(0x00);
supawat 0:0b6c94a21953 117 _deselect();
supawat 0:0b6c94a21953 118 }
supawat 0:0b6c94a21953 119
supawat 0:0b6c94a21953 120 /**
supawat 0:0b6c94a21953 121 * Main Memory Page Read.
supawat 0:0b6c94a21953 122 * A main memory page read allows the user to read data directly from
supawat 0:0b6c94a21953 123 * any one of the 4096 pages in the main memory, bypassing both of the
supawat 0:0b6c94a21953 124 * data buffers and leaving the contents of the buffers unchanged.
supawat 0:0b6c94a21953 125 *
supawat 0:0b6c94a21953 126 * @param page: Page of the main memory to read
supawat 0:0b6c94a21953 127 * @param offset: Starting byte address within the page
supawat 0:0b6c94a21953 128 * @param *data: Data buffer to be return the value in flash memory
supawat 0:0b6c94a21953 129 * @param len: Lenght of data that you want to read
supawat 0:0b6c94a21953 130 * Note: When the end of a page in main memory is reached,
supawat 0:0b6c94a21953 131 the device will continue reading back at the beginning
supawat 0:0b6c94a21953 132 of the same page.
supawat 0:0b6c94a21953 133 **/
supawat 0:0b6c94a21953 134 void ATD45DB161E::PageRead(unsigned int page,unsigned int offset,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 135 {
supawat 0:0b6c94a21953 136 unsigned int address,i;
supawat 0:0b6c94a21953 137
supawat 0:0b6c94a21953 138 address = (page<<9)|offset;
supawat 0:0b6c94a21953 139
supawat 0:0b6c94a21953 140 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 141 _select();
supawat 0:0b6c94a21953 142
supawat 0:0b6c94a21953 143 /* Send opcode */
supawat 0:0b6c94a21953 144 _spi.write(0xd2);
supawat 0:0b6c94a21953 145
supawat 0:0b6c94a21953 146 _sendaddr(address); // send three address byte
supawat 0:0b6c94a21953 147
supawat 0:0b6c94a21953 148 /* 4 "don't care" bytes */
supawat 0:0b6c94a21953 149 _spi.write(0x00);
supawat 0:0b6c94a21953 150 _spi.write(0x00);
supawat 0:0b6c94a21953 151 _spi.write(0x00);
supawat 0:0b6c94a21953 152 _spi.write(0x00);
supawat 0:0b6c94a21953 153
supawat 0:0b6c94a21953 154 for(i=0;i<len;i++)
supawat 0:0b6c94a21953 155 {
supawat 0:0b6c94a21953 156 *data++ = _spi.write(0x00);
supawat 0:0b6c94a21953 157 }
supawat 0:0b6c94a21953 158 _deselect();
supawat 0:0b6c94a21953 159 }
supawat 0:0b6c94a21953 160
supawat 0:0b6c94a21953 161 /**
supawat 0:0b6c94a21953 162 * Continuous Array Read in low power mode.
supawat 0:0b6c94a21953 163 * Continuous Array Read in low power mode allows the user to read data
supawat 0:0b6c94a21953 164 * directly from any address in the main memory, bypassing both of the
supawat 0:0b6c94a21953 165 * data buffers and leaving the contents of the buffers unchanged.
supawat 0:0b6c94a21953 166 *
supawat 0:0b6c94a21953 167 * @param page: Page of the main memory to read
supawat 0:0b6c94a21953 168 * @param addr_st: Starting byte address within the main memory
supawat 0:0b6c94a21953 169 * @param *data: Data buffer to be return the value in flash memory
supawat 0:0b6c94a21953 170 * @param len: Lenght of data that you want to read
supawat 0:0b6c94a21953 171 * Note: When the end of a page in main memory is reached, the device will
supawat 0:0b6c94a21953 172 continue reading at the beginning of the next page with no delays
supawat 0:0b6c94a21953 173 incurred during the page boundary crossover.
supawat 0:0b6c94a21953 174 **/
supawat 0:0b6c94a21953 175 void ATD45DB161E::ContinuousArrayRead(unsigned int addr_st,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 176 {
supawat 0:0b6c94a21953 177 unsigned int i;
supawat 0:0b6c94a21953 178
supawat 0:0b6c94a21953 179 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 180 _select();
supawat 0:0b6c94a21953 181
supawat 0:0b6c94a21953 182 /* Send opcode */
supawat 0:0b6c94a21953 183 _spi.write(0x01);
supawat 0:0b6c94a21953 184
supawat 0:0b6c94a21953 185 _sendaddr(addr_st); // send three address byte
supawat 0:0b6c94a21953 186
supawat 0:0b6c94a21953 187 for(i=0;i<len;i++)
supawat 0:0b6c94a21953 188 {
supawat 0:0b6c94a21953 189 *data++ = _spi.write(0x00);
supawat 0:0b6c94a21953 190 }
supawat 0:0b6c94a21953 191 _deselect();
supawat 0:0b6c94a21953 192 }
supawat 0:0b6c94a21953 193
supawat 0:0b6c94a21953 194 /**
supawat 0:0b6c94a21953 195 * Erase the entire chip memory. Sectors proteced or locked down will
supawat 0:0b6c94a21953 196 * not be erased.
supawat 0:0b6c94a21953 197 **/
supawat 0:0b6c94a21953 198 void ATD45DB161E::ChipErase(void)
supawat 0:0b6c94a21953 199 {
supawat 0:0b6c94a21953 200 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 201
supawat 0:0b6c94a21953 202 // There are errata on this. For now, do itthe long way :-(
supawat 0:0b6c94a21953 203 _select();
supawat 0:0b6c94a21953 204 // 4 byte command sequence
supawat 0:0b6c94a21953 205 _spi.write(0xc7);
supawat 0:0b6c94a21953 206 _spi.write(0x94);
supawat 0:0b6c94a21953 207 _spi.write(0x80);
supawat 0:0b6c94a21953 208 _spi.write(0x9a);
supawat 0:0b6c94a21953 209 _deselect();
supawat 0:0b6c94a21953 210
supawat 0:0b6c94a21953 211 _pollbusy(); // waiting for chip erase
supawat 0:0b6c94a21953 212 }
supawat 0:0b6c94a21953 213
supawat 0:0b6c94a21953 214 /**
supawat 0:0b6c94a21953 215 * Erase a page in the main memory array.
supawat 0:0b6c94a21953 216 * @param page: Number of page that you want to erase
supawat 0:0b6c94a21953 217 **/
supawat 0:0b6c94a21953 218 void ATD45DB161E::PageErase(unsigned int page)
supawat 0:0b6c94a21953 219 {
supawat 0:0b6c94a21953 220 unsigned int address;
supawat 0:0b6c94a21953 221
supawat 0:0b6c94a21953 222 address = page<<9;
supawat 0:0b6c94a21953 223
supawat 0:0b6c94a21953 224 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 225
supawat 0:0b6c94a21953 226 // There are errata on this. For now, do itthe long way :-(
supawat 0:0b6c94a21953 227 _select();
supawat 0:0b6c94a21953 228 _spi.write(0x81); // Command for page erase
supawat 0:0b6c94a21953 229 _sendaddr(address); // Send 3 address bytes
supawat 0:0b6c94a21953 230 _deselect();
supawat 0:0b6c94a21953 231
supawat 0:0b6c94a21953 232 _pollbusy(); // waiting for page erase
supawat 0:0b6c94a21953 233 }
supawat 0:0b6c94a21953 234
supawat 0:0b6c94a21953 235 /**
supawat 0:0b6c94a21953 236 * This is a combination of Buffer Write and Buffer to Page with
supawat 0:0b6c94a21953 237 * Built-in Erase.
supawat 0:0b6c94a21953 238 * @param page Page where the content of the buffer will transfered
supawat 0:0b6c94a21953 239 * @param offset Starting byte address within the buffer
supawat 0:0b6c94a21953 240 * @param bufferNum Buffer to use (1 or 2)
supawat 0:0b6c94a21953 241 * @param *data: Data that you want to write into flash memory
supawat 0:0b6c94a21953 242 * @param len: Lenght of data that you want to write
supawat 0:0b6c94a21953 243 * Note: If the end of the buffer is reached, the device will
supawat 0:0b6c94a21953 244 wrap around back to the beginning of the buffer.
supawat 0:0b6c94a21953 245 **/
supawat 0:0b6c94a21953 246 void ATD45DB161E::PageWriteThroughBuffer(unsigned int page, unsigned int offset, unsigned char bufferNum,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 247 {
supawat 0:0b6c94a21953 248 unsigned int address,i;
supawat 0:0b6c94a21953 249 unsigned char opcode;
supawat 0:0b6c94a21953 250
supawat 0:0b6c94a21953 251 address = (page<<9)|offset;
supawat 0:0b6c94a21953 252 // select opcode which buffer have been used
supawat 0:0b6c94a21953 253 if (bufferNum == 1)
supawat 0:0b6c94a21953 254 opcode = 0x82;
supawat 0:0b6c94a21953 255 else
supawat 0:0b6c94a21953 256 opcode = 0x85;
supawat 0:0b6c94a21953 257
supawat 0:0b6c94a21953 258 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 259 _select();
supawat 0:0b6c94a21953 260
supawat 0:0b6c94a21953 261 /* Send opcode */
supawat 0:0b6c94a21953 262 _spi.write(opcode);
supawat 0:0b6c94a21953 263
supawat 0:0b6c94a21953 264 /* Address */
supawat 0:0b6c94a21953 265 _sendaddr(address); // send three address byte
supawat 0:0b6c94a21953 266 for(i=0;i<len;i++)
supawat 0:0b6c94a21953 267 {
supawat 0:0b6c94a21953 268 _spi.write(*data++);
supawat 0:0b6c94a21953 269 }
supawat 0:0b6c94a21953 270 _deselect();
supawat 0:0b6c94a21953 271 _pollbusy(); // waiting for programming from buffer into main memory
supawat 0:0b6c94a21953 272 }
supawat 0:0b6c94a21953 273
supawat 0:0b6c94a21953 274 /**
supawat 0:0b6c94a21953 275 * This is a combination of the Main Memory Page to Buffer Transfer, Buffer Write,
supawat 0:0b6c94a21953 276 * and Buffer to Main Memory Page Program with Built-in Erase commands.
supawat 0:0b6c94a21953 277 * @param addr_st Starting byte address of the flash chip
supawat 0:0b6c94a21953 278 * @param bufferNum Buffer to use (1 or 2)
supawat 0:0b6c94a21953 279 * @param *data: Data that you want to write into flash memory
supawat 0:0b6c94a21953 280 * @param len: Lenght of data that you want to write
supawat 0:0b6c94a21953 281 * Note: If the end of the buffer is reached, the device will
supawat 0:0b6c94a21953 282 wrap around back to the beginning of the buffer.
supawat 0:0b6c94a21953 283 **/
supawat 0:0b6c94a21953 284 void ATD45DB161E::ContinuousWriteThroughBuffer(unsigned int addr_st, unsigned char bufferNum,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 285 {
supawat 0:0b6c94a21953 286 unsigned int i,data_len;
supawat 0:0b6c94a21953 287 unsigned int page_start,page_end;
supawat 0:0b6c94a21953 288 unsigned int page_count,dif_page;
supawat 0:0b6c94a21953 289 unsigned char opcode;
supawat 0:0b6c94a21953 290
supawat 0:0b6c94a21953 291 page_start = addr_st>>9;
supawat 0:0b6c94a21953 292 page_end = (addr_st+len)>>9;
supawat 0:0b6c94a21953 293 dif_page = page_end - page_start;
supawat 0:0b6c94a21953 294
supawat 0:0b6c94a21953 295 // select opcode which buffer have been used
supawat 0:0b6c94a21953 296 if (bufferNum == 1)
supawat 0:0b6c94a21953 297 opcode = 0x58;
supawat 0:0b6c94a21953 298 else
supawat 0:0b6c94a21953 299 opcode = 0x59;
supawat 0:0b6c94a21953 300
supawat 0:0b6c94a21953 301 for(page_count=0;page_count<=dif_page;page_count++)
supawat 0:0b6c94a21953 302 {
supawat 0:0b6c94a21953 303 if(512-(addr_st&0x1ff)<len) data_len = 512-(addr_st&0x1ff);
supawat 0:0b6c94a21953 304 else data_len = len;
supawat 0:0b6c94a21953 305 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 306 _select();
supawat 0:0b6c94a21953 307 _spi.write(opcode); /* Send opcode */
supawat 0:0b6c94a21953 308 _sendaddr(addr_st); // send three address byte
supawat 0:0b6c94a21953 309 for(i=0;i<data_len;i++)
supawat 0:0b6c94a21953 310 {
supawat 0:0b6c94a21953 311 _spi.write(*data++);
supawat 0:0b6c94a21953 312 }
supawat 0:0b6c94a21953 313 _deselect();
supawat 0:0b6c94a21953 314 _pollbusy(); // waiting for programming from buffer into main memory
supawat 0:0b6c94a21953 315 addr_st = addr_st + data_len;
supawat 0:0b6c94a21953 316 len = len - data_len;
supawat 0:0b6c94a21953 317 }
supawat 0:0b6c94a21953 318 }
supawat 0:0b6c94a21953 319
supawat 0:0b6c94a21953 320 /**
supawat 0:0b6c94a21953 321 * Read the content of one of the SRAM data buffers (in low or high speed mode).
supawat 0:0b6c94a21953 322 * @param bufferNum Buffer to read (1 or 2)
supawat 0:0b6c94a21953 323 * @param offset Starting byte within the buffer
supawat 0:0b6c94a21953 324 * @param low If true the read operation will be performed in low speed mode (and in high speed mode if it's false).
supawat 0:0b6c94a21953 325 * @param *data: Data that you want to read from flash memory
supawat 0:0b6c94a21953 326 * @param len: Lenght of data that you want to read
supawat 0:0b6c94a21953 327 **/
supawat 0:0b6c94a21953 328 void ATD45DB161E::BufferRead(unsigned char bufferNum, unsigned int offset, unsigned char low,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 329 {
supawat 0:0b6c94a21953 330 unsigned int i;
supawat 0:0b6c94a21953 331 unsigned char opcode;
supawat 0:0b6c94a21953 332
supawat 0:0b6c94a21953 333 /* Send opcode */
supawat 0:0b6c94a21953 334 if(bufferNum == 1)
supawat 0:0b6c94a21953 335 {
supawat 0:0b6c94a21953 336 if(low)
supawat 0:0b6c94a21953 337 opcode = 0xd1; // opcode for read buffer 1 in low speed
supawat 0:0b6c94a21953 338 else
supawat 0:0b6c94a21953 339 opcode = 0xd4; // opcode for read buffer 1
supawat 0:0b6c94a21953 340 }
supawat 0:0b6c94a21953 341 else
supawat 0:0b6c94a21953 342 {
supawat 0:0b6c94a21953 343 if(low)
supawat 0:0b6c94a21953 344 opcode = 0xd3; // opcode for read buffer 1 in low speed
supawat 0:0b6c94a21953 345 else
supawat 0:0b6c94a21953 346 opcode = 0xd6; // opcode for read buffer 2
supawat 0:0b6c94a21953 347 }
supawat 0:0b6c94a21953 348 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 349 _select();
supawat 0:0b6c94a21953 350 /* Send opcode */
supawat 0:0b6c94a21953 351 _spi.write(opcode);
supawat 0:0b6c94a21953 352 _sendaddr(offset); // send three address byte
supawat 0:0b6c94a21953 353 if(!low)
supawat 0:0b6c94a21953 354 _spi.write(0x00); // send dummy byte
supawat 0:0b6c94a21953 355 for(i=0;i<len;i++)
supawat 0:0b6c94a21953 356 {
supawat 0:0b6c94a21953 357 *data++ = _spi.write(0x00);
supawat 0:0b6c94a21953 358 }
supawat 0:0b6c94a21953 359 _deselect();
supawat 0:0b6c94a21953 360 }
supawat 0:0b6c94a21953 361
supawat 0:0b6c94a21953 362 /**
supawat 0:0b6c94a21953 363 * Write data to one of the SRAM data buffers. Any further call to
supawat 0:0b6c94a21953 364 * spi_tranfer will return bytes contained in the data buffer until
supawat 0:0b6c94a21953 365 * a low-to-high transition is detected on the CS pin. If the end of
supawat 0:0b6c94a21953 366 * the data buffer is reached, the device will wrap around back to the
supawat 0:0b6c94a21953 367 * beginning of the buffer.
supawat 0:0b6c94a21953 368 * @param bufferNum Buffer to read (1 or 2)
supawat 0:0b6c94a21953 369 * @param offset Starting byte within the buffer
supawat 0:0b6c94a21953 370 * @param *data: Data that you want to write into flash memory
supawat 0:0b6c94a21953 371 * @param len: Lenght of data that you want to write
supawat 0:0b6c94a21953 372 **/
supawat 0:0b6c94a21953 373 void ATD45DB161E::BufferWrite(unsigned char bufferNum, unsigned int offset,unsigned char *data,unsigned int len)
supawat 0:0b6c94a21953 374 {
supawat 0:0b6c94a21953 375 unsigned int i;
supawat 0:0b6c94a21953 376 unsigned char opcode;
supawat 0:0b6c94a21953 377
supawat 0:0b6c94a21953 378 if (bufferNum == 1)
supawat 0:0b6c94a21953 379 opcode = 0x84;
supawat 0:0b6c94a21953 380 else
supawat 0:0b6c94a21953 381 opcode = 0x87;
supawat 0:0b6c94a21953 382 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 383 _select();
supawat 0:0b6c94a21953 384
supawat 0:0b6c94a21953 385 /* Send opcode */
supawat 0:0b6c94a21953 386 _spi.write(opcode);
supawat 0:0b6c94a21953 387 _sendaddr(offset); // send three address byte
supawat 0:0b6c94a21953 388 for(i=0;i<len;i++)
supawat 0:0b6c94a21953 389 {
supawat 0:0b6c94a21953 390 _spi.write(*data++);
supawat 0:0b6c94a21953 391 }
supawat 0:0b6c94a21953 392 _deselect();
supawat 0:0b6c94a21953 393 _pollbusy(); // waiting for operation complete.
supawat 0:0b6c94a21953 394 }
supawat 0:0b6c94a21953 395
supawat 0:0b6c94a21953 396 /**
supawat 0:0b6c94a21953 397 * Transfer data from buffer 1 or 2 to main memory page.
supawat 0:0b6c94a21953 398 * @param bufferNum Buffer to use (1 or 2)
supawat 0:0b6c94a21953 399 * @param page Page where the content of the buffer will transfered
supawat 0:0b6c94a21953 400 * @param erase If set the page will be first erased before the buffer transfer.
supawat 0:0b6c94a21953 401 * @note If erase is equal to zero, the page must have been previously erased using one of the erase command (Page or Block Erase).
supawat 0:0b6c94a21953 402 **/
supawat 0:0b6c94a21953 403 void ATD45DB161E::BufferToPage(unsigned char bufferNum, unsigned int page, unsigned char erase)
supawat 0:0b6c94a21953 404 {
supawat 0:0b6c94a21953 405 unsigned int address;
supawat 0:0b6c94a21953 406 unsigned char opcode;
supawat 0:0b6c94a21953 407
supawat 0:0b6c94a21953 408 address = page<<9;
supawat 0:0b6c94a21953 409 if(erase)
supawat 0:0b6c94a21953 410 {
supawat 0:0b6c94a21953 411 if (bufferNum == 1)
supawat 0:0b6c94a21953 412 opcode = 0x83;
supawat 0:0b6c94a21953 413 else
supawat 0:0b6c94a21953 414 opcode = 0x86;
supawat 0:0b6c94a21953 415 }
supawat 0:0b6c94a21953 416 else
supawat 0:0b6c94a21953 417 {
supawat 0:0b6c94a21953 418 if (bufferNum == 1)
supawat 0:0b6c94a21953 419 opcode = 0x88;
supawat 0:0b6c94a21953 420 else
supawat 0:0b6c94a21953 421 opcode = 0x89;
supawat 0:0b6c94a21953 422 }
supawat 0:0b6c94a21953 423
supawat 0:0b6c94a21953 424 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 425 _select();
supawat 0:0b6c94a21953 426
supawat 0:0b6c94a21953 427 /* Send opcode */
supawat 0:0b6c94a21953 428 _spi.write(opcode);
supawat 0:0b6c94a21953 429 _sendaddr(address); // send three address byte
supawat 0:0b6c94a21953 430 _deselect();
supawat 0:0b6c94a21953 431
supawat 0:0b6c94a21953 432 _pollbusy(); // Wait for buffer write to main memory page
supawat 0:0b6c94a21953 433 }
supawat 0:0b6c94a21953 434
supawat 0:0b6c94a21953 435 /**
supawat 0:0b6c94a21953 436 * Transfer data from main memory page to buffer 1 or 2.
supawat 0:0b6c94a21953 437 * @param page Page where the content of the main memory page will transfered
supawat 0:0b6c94a21953 438 * @param bufferNum Buffer to use (1 or 2)
supawat 0:0b6c94a21953 439 **/
supawat 0:0b6c94a21953 440 void ATD45DB161E::PageToBuffer(unsigned int page, unsigned char bufferNum)
supawat 0:0b6c94a21953 441 {
supawat 0:0b6c94a21953 442 unsigned int address;
supawat 0:0b6c94a21953 443 unsigned char opcode;
supawat 0:0b6c94a21953 444
supawat 0:0b6c94a21953 445 address = page<<9;
supawat 0:0b6c94a21953 446
supawat 0:0b6c94a21953 447 if (bufferNum == 1) opcode = 0x53;
supawat 0:0b6c94a21953 448 else opcode = 0x55;
supawat 0:0b6c94a21953 449
supawat 0:0b6c94a21953 450 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 451 _select();
supawat 0:0b6c94a21953 452
supawat 0:0b6c94a21953 453 /* Send opcode */
supawat 0:0b6c94a21953 454 _spi.write(opcode);
supawat 0:0b6c94a21953 455 _sendaddr(address); // send three address byte
supawat 0:0b6c94a21953 456 _deselect();
supawat 0:0b6c94a21953 457
supawat 0:0b6c94a21953 458 _pollbusy(); // Wait for buffer write to main memory page
supawat 0:0b6c94a21953 459 }
supawat 0:0b6c94a21953 460
supawat 0:0b6c94a21953 461 /**
supawat 0:0b6c94a21953 462 * Enter the chip into deep power down mode.
supawat 0:0b6c94a21953 463 * @param deep_down_onoff: If set the chip will be entered into deep power down mode. Otherwise, wake up command will be sent to the chip.
supawat 0:0b6c94a21953 464 **/
supawat 0:0b6c94a21953 465 void ATD45DB161E::DeepPowerDown(unsigned char deep_down_onoff)
supawat 0:0b6c94a21953 466 {
supawat 0:0b6c94a21953 467 if(deep_down_onoff)
supawat 0:0b6c94a21953 468 {
supawat 0:0b6c94a21953 469 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 470 _select();
supawat 0:0b6c94a21953 471 _spi.write(0xb9);
supawat 0:0b6c94a21953 472 _deselect();
supawat 0:0b6c94a21953 473 _wake_flag = false;
supawat 0:0b6c94a21953 474 _deepsleep_flag = true;
supawat 0:0b6c94a21953 475 wait_us(2);
supawat 0:0b6c94a21953 476 }
supawat 0:0b6c94a21953 477 else
supawat 0:0b6c94a21953 478 {
supawat 0:0b6c94a21953 479 _select();
supawat 0:0b6c94a21953 480 _spi.write(0xab);
supawat 0:0b6c94a21953 481 _deselect();
supawat 0:0b6c94a21953 482 _wake_flag = true;
supawat 0:0b6c94a21953 483 _deepsleep_flag = false;
supawat 0:0b6c94a21953 484 wait_us(35);
supawat 0:0b6c94a21953 485 }
supawat 0:0b6c94a21953 486 }
supawat 0:0b6c94a21953 487
supawat 0:0b6c94a21953 488 /**
supawat 0:0b6c94a21953 489 * Enter the chip into ultra deep power down mode.
supawat 0:0b6c94a21953 490 * @param ultra_deep_down_onoff: If set the chip will be entered into ultra deep power down mode. Otherwise, CS pin will be asseeted for wake up the chip.
supawat 0:0b6c94a21953 491 **/
supawat 0:0b6c94a21953 492 void ATD45DB161E::UltraDeepPowerDown(unsigned char ultra_deep_down_onoff)
supawat 0:0b6c94a21953 493 {
supawat 0:0b6c94a21953 494 if(ultra_deep_down_onoff)
supawat 0:0b6c94a21953 495 {
supawat 0:0b6c94a21953 496 _pollbusy(); // make sure flash isn't already in busy.
supawat 0:0b6c94a21953 497 _select();
supawat 0:0b6c94a21953 498 _spi.write(0x79);
supawat 0:0b6c94a21953 499 _deselect();
supawat 0:0b6c94a21953 500 _wake_flag = false;
supawat 0:0b6c94a21953 501 _udeepsleep_flag = true;
supawat 0:0b6c94a21953 502 wait_us(4);
supawat 0:0b6c94a21953 503 }
supawat 0:0b6c94a21953 504 else
supawat 0:0b6c94a21953 505 {
supawat 0:0b6c94a21953 506 _select();
supawat 0:0b6c94a21953 507 wait_us(1);
supawat 0:0b6c94a21953 508 _deselect();
supawat 0:0b6c94a21953 509 wait_us(180);
supawat 0:0b6c94a21953 510 _wake_flag = true;
supawat 0:0b6c94a21953 511 _udeepsleep_flag = false;
supawat 0:0b6c94a21953 512 }
supawat 0:0b6c94a21953 513 }
supawat 0:0b6c94a21953 514
supawat 0:0b6c94a21953 515 /**
supawat 0:0b6c94a21953 516 * Check the chip is wake up.
supawat 0:0b6c94a21953 517 * Return true if the chip is wake up. Otherwise, the chip is entered in deep power down or ultra deep power down mode mode.
supawat 0:0b6c94a21953 518 **/
supawat 0:0b6c94a21953 519 bool ATD45DB161E::is_it_awake(void)
supawat 0:0b6c94a21953 520 {
supawat 0:0b6c94a21953 521 return _wake_flag;
supawat 0:0b6c94a21953 522 }