Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API TMP_nrf51 mbed nRF51822
Fork of VTT_NODEV3_BMP180_Si7021 by
AT45.cpp
00001 /* mbed AT45 Library, for driving the Atmel AT45 series Dataflash with Serial Interface (SPI) 00002 * Copyright (c) 2012, Created by Steen Joergensen (stjo2809) inspired by Chris Styles AT45 library 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 #include "mbed.h" 00024 #include "AT45.h" 00025 #include "nrf_delay.h" 00026 00027 //============================================================================= 00028 // Public functions 00029 //============================================================================= 00030 00031 AT45::AT45(SPI& spi, PinName ncs) : _spi(spi), _ncs(ncs) 00032 { 00033 00034 _pages = -1; // number of pages 00035 _pagesize = -1; // size of pages 256/264, 512/528, 1024/1056 00036 _devicesize = -1; // In bytes 00037 _deep_down = true; // variable for deep power down function (awake ?) 00038 _deep_down_onoff = false; // variable for deep power down function (On/Off) 00039 00040 _initialize(); // Populate all this stuff 00041 00042 } 00043 00044 // This function returns the char 00045 char AT45::read_byte(int address) 00046 { 00047 // return byte from address 00048 return (_memread( address )); 00049 } 00050 00051 int AT45::read_page(char* data, int page) 00052 { 00053 int address = -1; 00054 00055 if(_pagesize == 256) 00056 { 00057 address = page * 256; 00058 } 00059 else if(_pagesize == 264) 00060 { 00061 address = page * 512; 00062 } 00063 else if(_pagesize == 512) 00064 { 00065 address = page * 512; 00066 } 00067 else if(_pagesize == 528) 00068 { 00069 address = page * 1024; 00070 } 00071 else if(_pagesize == 1024) 00072 { 00073 address = page * 1024; 00074 } 00075 else if(_pagesize == 1056) 00076 { 00077 address = page * 2048; 00078 } 00079 else 00080 { 00081 return (-1); // something isnt configured right 00082 } 00083 00084 _busy(); 00085 _flashread(1,address); // read the first page of the block into SRAM buffer 1 00086 _busy(); // Wait until First page has loaded into buffer 1 00087 00088 // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread 00089 _select(); 00090 _spi.write(0xd4); 00091 _sendaddr (0x0); 00092 _spi.write (0x0); // dont care byte 00093 00094 for(int i=0; i<_pagesize ;i++) 00095 { 00096 data[i] = _spi.write (0x0); 00097 } 00098 _deselect(); 00099 00100 return (0); 00101 } 00102 int AT45::read_block(char *data, int block) // under construction F�R CHECK AF MIC OG LERCHE 00103 { 00104 char temp_data[_pagesize]; 00105 int page_start; 00106 00107 if (block < _blocks || block == 0) { 00108 page_start = block * 8; 00109 00110 for (int i=0; i<8; i++) { 00111 read_page(temp_data, page_start); 00112 //printf("%d Read round, Data is: %d\r\n",i,*temp_data); 00113 page_start = page_start + 1; 00114 for (int z=0; z<_pagesize ; z++) { 00115 data[z+(_pagesize*i)] = temp_data[z]; 00116 } 00117 } 00118 } else { 00119 //do nothing 00120 } 00121 //printf("Read done, Data is: %d\r\n",*data); 00122 return (0); 00123 } 00124 00125 int AT45::read_block(char *data[], int block) // under construction F� CHECK AF MIC OG LERCHE 00126 { 00127 char temp_data[_pagesize]; 00128 int page_start; 00129 00130 if(block < _blocks || block == 0) 00131 { 00132 page_start = block * 8; 00133 00134 for(int i=0; i<8 ;i++) // 8 pages in a block 00135 { 00136 read_page(temp_data, page_start); 00137 page_start = page_start + 1; 00138 for(int z=0; z<_pagesize ;z++) 00139 { 00140 data[i][z] = temp_data[z]; 00141 } 00142 } 00143 } 00144 else 00145 { 00146 //do nothing 00147 } 00148 00149 return (0); 00150 } 00151 00152 // This function writes the char to the address supplied 00153 // Note : We pass the raw address to the underlying functions 00154 void AT45::write_byte(int address, char data) 00155 { 00156 _busy(); 00157 _flashread(1,address); // read the Flash page into SRAM buffer 00158 _busy(); // wait for the read to complete 00159 _sramwrite(1,address,data); // Write new data into SRAM 00160 _busy(); // Make sure flash isnt busy 00161 _flashwrite(1,address); // Write back to the page address 00162 } 00163 00164 int AT45::write_page(char* data, int page) 00165 { 00166 int address = -1; 00167 00168 if(_pagesize == 256) 00169 { 00170 address = page * 256; 00171 } 00172 else if(_pagesize == 264) 00173 { 00174 address = page * 512; 00175 } 00176 else if(_pagesize == 512) 00177 { 00178 address = page * 512; 00179 } 00180 else if(_pagesize == 528) 00181 { 00182 address = page * 1024; 00183 } 00184 else if(_pagesize == 1024) 00185 { 00186 address = page * 1024; 00187 } 00188 else if(_pagesize == 1056) 00189 { 00190 address = page * 2048; 00191 } 00192 else 00193 { 00194 return (-1); // something isnt configured right 00195 } 00196 00197 _select(); 00198 _spi.write(0x84); // writing to buffer #1 00199 _sendaddr (0); // we are writing to the entire buffer 00200 00201 for(int i=0; i<_pagesize ;i++) 00202 { 00203 _spi.write (data[i]); 00204 } 00205 _deselect(); 00206 00207 _busy(); // make sure the Flahs isnt busy 00208 00209 // issue command to write buffer 1 to the appropraite flash page 00210 _select(); 00211 _spi.write (0x83); 00212 _sendaddr (_getpaddr(address)); 00213 _deselect(); 00214 00215 return (0); 00216 } 00217 int AT45::write_block(char *data, int block) // under construction F�R CHECK AF MIC OG LERCHE 00218 { 00219 00220 int page_start; 00221 char page_arr[_pagesize]; 00222 00223 if (block < _blocks || block == 0) 00224 { 00225 page_start = block * 8; 00226 00227 for (int i=0; i<8 ; i++) 00228 { 00229 // Copy data from *data at 0 to 511 _ 512 - 1023, and so on every round. 00230 memcpy(page_arr, &data[_pagesize*i], _pagesize); 00231 00232 write_page(page_arr, page_start); 00233 page_start = page_start + 1; 00234 } 00235 } else { 00236 //do nothing 00237 } 00238 00239 return (0); 00240 } 00241 int AT45::write_block(char *data[], int block) // under construction F� CHECK AF MIC OG LERCHE 00242 { 00243 char temp_data[_pagesize]; 00244 int page_start; 00245 00246 if(block < _blocks || block == 0) 00247 { 00248 page_start = block * 8; 00249 00250 for(int i=0; i<8 ;i++) 00251 { 00252 for(int z=0; z<_pagesize ;z++) 00253 { 00254 temp_data[z] = data[i][z]; 00255 } 00256 write_page(temp_data, page_start); 00257 page_start = page_start + 1; 00258 } 00259 } 00260 else 00261 { 00262 //do nothing 00263 } 00264 00265 return (0); 00266 } 00267 00268 int AT45::FAT_read(char* data, int page) 00269 { 00270 // For 256 byte pages, we read two pages 00271 if((_pagesize == 256) || (_pagesize == 264)) 00272 { 00273 int address = page * 512; // This is the start address of the 512 byte block 00274 00275 _flashread(1,address); // read the first page of the block into SRAM buffer 1 00276 _busy(); // Wait until First page has loaded into buffer 1 00277 00278 // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread 00279 _select(); 00280 _spi.write(0xd4); 00281 _sendaddr (0x0); 00282 _spi.write (0x0); // dont care byte 00283 00284 for(int i=0;i<256;i++) 00285 { 00286 data[i] = _spi.write (0x0); 00287 } 00288 _deselect(); 00289 00290 _flashread(1,address+256); // read the second page of the block into SRAM buffer 2 00291 _busy(); // Wait until second page has loaded into buffer 2 00292 00293 // Now the second page is loaded, pull this out into the second half of the data buffer 00294 // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread 00295 _select(); 00296 _spi.write(0xd4); 00297 _sendaddr (0x0); 00298 _spi.write (0x0); // dont care byte 00299 00300 for(int i=0;i<256;i++) 00301 { 00302 data[256+i] = _spi.write (0x0); 00303 } 00304 _deselect(); 00305 return (0); 00306 } 00307 00308 // For 512 byte pages, we read just the single page, transfer it 00309 else if((_pagesize == 512) || (_pagesize == 528)) 00310 { 00311 int address = page * 512; // This is the start address of the 512 byte block 00312 00313 _busy(); // Wait until First page has loaded into buffer 1 00314 _flashread(1,address); // read the first page of the block into SRAM buffer 1 00315 _busy(); // Wait until First page has loaded into buffer 1 00316 00317 // Now the page has loaded, simply transfer it from the sram buffer to the data array 00318 // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread 00319 _select(); 00320 _spi.write(0xd4); 00321 _sendaddr (0x0); 00322 _spi.write (0x0); // dont care byte 00323 00324 for(int i=0;i<512;i++) 00325 { 00326 data[i] = _spi.write (0x0); 00327 } 00328 _deselect(); 00329 return (0); 00330 } 00331 00332 // For 1024 byte pages, we read just a single page, transfer half of it 00333 else if((_pagesize == 1024) || (_pagesize == 1056)) 00334 { 00335 int address = _getpaddr(page * 512); // This is the start address of the 512 byte block 00336 00337 _busy(); // Wait until First page has loaded into buffer 1 00338 00339 _flashread(1,address); // read the first page of the block into SRAM buffer 1 00340 00341 _busy(); // Wait until First page has loaded into buffer 1 00342 00343 // Now the page has loaded, simply transfer it from the sram buffer to the data array 00344 // this is done directly as we are reading back an entire buffer, and this can be done more optimally than using _sramread 00345 00346 _select(); 00347 _spi.write(0xd4); 00348 00349 if (page %2) // odd numbered block, read from adress 0x200 00350 { 00351 _sendaddr (0x200); 00352 } 00353 else // even numbered block, then we are reading from sram buffer 0x0 00354 { 00355 _sendaddr (0x0); 00356 } 00357 00358 _spi.write (0x0); // dont care byte 00359 00360 for(int i=0;i<512;i++) 00361 { 00362 data[i] = _spi.write (0x0); 00363 } 00364 _deselect(); 00365 return (0); 00366 } 00367 else 00368 { 00369 return (-1); // something isnt configured right 00370 } 00371 } 00372 00373 int AT45::FAT_write(char* data, int page) 00374 { 00375 // For 256 byte pages, we overwrite two pages 00376 if((_pagesize == 256) || (_pagesize == 264)) 00377 { 00378 00379 // fill the first buffer with the first half of the block 00380 // do this directly, for better performance 00381 _select(); 00382 _spi.write(0x84); // writing to buffer #1 00383 _sendaddr (0); // we are writing to the entire buffer 00384 00385 for(int i=0;i<256;i++) { 00386 _spi.write (data[i]); 00387 } 00388 _deselect(); 00389 00390 _flashwrite(1,(page*512)); 00391 00392 // fill the buffer with the second half of the block 00393 // do this directly, for better performance 00394 _select(); 00395 _spi.write(0x84); // writing to buffer #1 00396 _sendaddr (0); // we are writing to the entire buffer 00397 00398 for(int i=0;i<256;i++) { 00399 _spi.write (data[256+i]); 00400 } 00401 _deselect(); 00402 00403 _flashwrite(1,((page*512)+256)); 00404 } 00405 00406 // For 512 byte pages, we overwrite a single page 00407 else if((_pagesize == 512) || (_pagesize == 528)) 00408 { 00409 00410 // fill the first buffer with the block data 00411 // do this directly, for better performance 00412 _select(); 00413 _spi.write(0x84); // writing to buffer #1 00414 _sendaddr (0); // we are writing to the entire buffer 00415 00416 for(int i=0;i<512;i++) { 00417 _spi.write (data[i]); 00418 } 00419 _deselect(); 00420 00421 _busy(); // make sure the Flahs isnt busy 00422 00423 // issue command to write buffer 1 to the appropraite flash page 00424 _select(); 00425 _spi.write (0x83); 00426 _sendaddr (_getpaddr(page * 512)); 00427 _deselect(); 00428 } 00429 00430 // For 1024 byte pages, we do a read modify write 00431 // must make sure we overwrite the right half of the page! 00432 else if((_pagesize == 1024) || (_pagesize == 1056)) 00433 { 00434 00435 _busy(); // make sure the flash isnt busy 00436 00437 int address = _getpaddr(page*512); 00438 00439 // Read the page into sram 00440 _flashread(1,address); 00441 00442 // wait for this operation to complete 00443 _busy(); 00444 00445 // Overwrite the appropriate half 00446 // do this directly, for better performance 00447 _select(); 00448 _spi.write(0x84); // writing to buffer #1 00449 00450 if(page%2) // this is an odd block number, overwrite second half of buffer 00451 { 00452 _sendaddr (0x200); // we are writing to the entire buffer 00453 } 00454 else // this is an even block, overwrite the first half 00455 { 00456 _sendaddr (0x0); // we are writing to the entire buffer 00457 } 00458 00459 for(int i=0;i<512;i++) 00460 { 00461 _spi.write (data[i]); 00462 } 00463 _deselect(); 00464 00465 // Write the page back 00466 _busy(); 00467 _flashwrite(1,address); 00468 } 00469 00470 // Something has gone wrong 00471 else 00472 { 00473 return (-1); 00474 } 00475 00476 return (0); 00477 } 00478 00479 // Erase the entire chip 00480 void AT45::chip_erase() 00481 { 00482 _busy(); // make sure flash isnt already in busy. 00483 00484 _select(); 00485 // 4 byte command sequence 00486 _spi.write(0xc7); 00487 _spi.write(0x94); 00488 _spi.write(0x80); 00489 _spi.write(0x9a); 00490 _deselect(); 00491 00492 _busy(); // Make erase a blocking function 00493 } 00494 00495 // Erase one block 00496 void AT45::block_erase(int block) 00497 { 00498 int address = -1; 00499 00500 // Calculate page addresses 00501 if(block < _blocks || block == 0) 00502 { 00503 if(_pagesize == 256) 00504 { 00505 address = block * 2048; 00506 } 00507 else if(_pagesize == 264) 00508 { 00509 address = block * 4096; 00510 } 00511 else if(_pagesize == 512) 00512 { 00513 address = block * 4096; 00514 } 00515 else if(_pagesize == 528) 00516 { 00517 address = block * 8192; 00518 } 00519 else if(_pagesize == 1024) 00520 { 00521 address = block * 8192; 00522 } 00523 else if(_pagesize == 1056) 00524 { 00525 address = block * 16384; 00526 } 00527 00528 _busy(); 00529 _select(); 00530 _spi.write(0x50); 00531 _sendaddr (address); 00532 _deselect(); 00533 _busy(); 00534 } 00535 else 00536 { 00537 //do nothing 00538 } 00539 } 00540 00541 // Erase one page 00542 void AT45::page_erase(int page) 00543 { 00544 int address = -1; 00545 00546 // Calculate page addresses 00547 if(page < _pages || page == 0) 00548 { 00549 if(_pagesize == 256) 00550 { 00551 address = page * 256; 00552 } 00553 else if(_pagesize == 264) 00554 { 00555 address = page * 512; 00556 } 00557 else if(_pagesize == 512) 00558 { 00559 address = page * 512; 00560 } 00561 else if(_pagesize == 528) 00562 { 00563 address = page * 1024; 00564 } 00565 else if(_pagesize == 1024) 00566 { 00567 address = page * 1024; 00568 } 00569 else if(_pagesize == 1056) 00570 { 00571 address = page * 2048; 00572 } 00573 00574 _busy(); 00575 _select(); 00576 _spi.write(0x81); 00577 _sendaddr (address); 00578 _deselect(); 00579 _busy(); 00580 } 00581 else 00582 { 00583 //do nothing 00584 } 00585 } 00586 00587 // return the size of the part in bytes 00588 int AT45::device_size() 00589 { 00590 return _devicesize; 00591 } 00592 00593 // return the numbers of pages 00594 int AT45::pages() 00595 { 00596 return _pages; 00597 } 00598 00599 // return the page size of the part in bytes 00600 int AT45::pagesize() 00601 { 00602 return _pagesize; 00603 } 00604 00605 // A one-time programmable configuration 00606 void AT45::set_pageszie_to_binary() 00607 { 00608 _busy(); // make sure flash isnt already in busy. 00609 00610 _select(); 00611 // 4 byte command sequence 00612 _spi.write(0x3d); 00613 _spi.write(0x2a); 00614 _spi.write(0x80); 00615 _spi.write(0xa6); 00616 _deselect(); 00617 00618 _busy(); // Make erase a blocking function 00619 } 00620 00621 // Return the number of blocks in this device in accordance with the datasheet 00622 int AT45::blocks() 00623 { 00624 return _blocks; 00625 } 00626 00627 // Return the Id of the part 00628 int AT45::id() 00629 { 00630 int id = 0; 00631 _select(); 00632 _spi.write(0x9f); 00633 id = (_spi.write(0x00) << 8); 00634 id |= _spi.write(0x00); 00635 _deselect(); 00636 return id; 00637 } 00638 00639 // return the Status 00640 int AT45::status() 00641 { 00642 int status = 0; 00643 _select(); 00644 _spi.write(0xd7); 00645 status = (_spi.write(0x00)); 00646 _deselect(); 00647 return status; 00648 } 00649 00650 // Make sure the Flash isnt already doing something 00651 void AT45::busy() 00652 { 00653 _busy(); 00654 } 00655 00656 void AT45::deep_power_down(bool _deep_down_onoff) 00657 { 00658 if(_deep_down_onoff == false) // Wake up from deep power down 00659 { 00660 _select(); 00661 _spi.write(0xab); 00662 _deselect(); 00663 _deep_down = true; 00664 // remenber to want 35uS before using the device. 00665 } 00666 else if(_deep_down_onoff == true) // Go to deep power down 00667 { 00668 _busy(); 00669 _select(); 00670 _spi.write(0xb9); 00671 _deselect(); 00672 _deep_down = false; 00673 } 00674 else 00675 { 00676 //do nothing 00677 } 00678 } 00679 00680 void AT45::ultra_deep_power_down(bool _deep_down_onoff) 00681 { 00682 if(_deep_down_onoff == false) // Wake up from deep power down 00683 { 00684 _select(); 00685 //_spi.write(0xab); 00686 //wait 20ns 00687 nrf_delay_us(1); 00688 _deselect(); 00689 _deep_down = true; 00690 // remenber to want 35uS before using the device. 00691 } 00692 else if(_deep_down_onoff == true) // Go to deep power down 00693 { 00694 _busy(); 00695 _select(); 00696 _spi.write(0x79); 00697 _deselect(); 00698 _deep_down = false; 00699 } 00700 else 00701 { 00702 //do nothing 00703 } 00704 } 00705 00706 bool AT45::is_it_awake() 00707 { 00708 return _deep_down; 00709 } 00710 00711 //============================================================================= 00712 // Private functions 00713 //============================================================================= 00714 00715 void AT45::_initialize() 00716 { 00717 int _id = 0; 00718 int _status = 0; 00719 00720 _id = id(); 00721 _id = id(); 00722 _status = status(); 00723 00724 if ((_id & 0x1f) == 0x3) // 2Mbits 00725 { 00726 _devicesize = 262144; // Size in bytes 00727 _pages = 1024; // Number of pages 00728 _blocks = 128; // Number of blocks 00729 if (_status & 0x1) 00730 { 00731 _pagesize = 256; 00732 } 00733 else 00734 { 00735 _pagesize = 264; 00736 } 00737 } 00738 else if ( (_id & 0x1f) == 0x4) // 4Mbits 00739 { 00740 _devicesize = 524288; 00741 _pages = 2048; 00742 _blocks = 256; 00743 if (_status & 0x1) 00744 { 00745 _pagesize = 256; 00746 } 00747 else 00748 { 00749 _pagesize = 264; 00750 } 00751 } 00752 else if ( (_id & 0x1f) == 0x5) // 8Mbits 00753 { 00754 _devicesize = 1048576; 00755 _pages = 4096; 00756 _blocks = 512; 00757 if (_status & 0x1) 00758 { 00759 _pagesize = 256; 00760 } 00761 else 00762 { 00763 _pagesize = 264; 00764 } 00765 } 00766 else if ( (_id & 0x1f) == 0x6) // 16Mbits 00767 { 00768 _devicesize = 2097152; 00769 _pages = 4096; 00770 _blocks = 512; 00771 if (_status & 0x1) 00772 { 00773 _pagesize = 512; 00774 } 00775 else 00776 { 00777 _pagesize = 528; 00778 } 00779 } 00780 else if ( (_id & 0x1f) == 0x7) // 32Mbits 00781 { 00782 _devicesize = 4194304; 00783 _pages = 8192; 00784 _blocks = 1024; 00785 if (_status & 0x1) 00786 { 00787 _pagesize = 512; 00788 } 00789 else 00790 { 00791 _pagesize = 528; 00792 } 00793 } 00794 else if ( (_id & 0x1f) == 0x8) // 64Mbits 00795 { 00796 _devicesize = 8388608; 00797 _pages = 8192; 00798 _blocks = 1024; 00799 if (_status & 0x1) 00800 { 00801 _pagesize = 1024; 00802 } 00803 else 00804 { 00805 _pagesize = 1056; 00806 } 00807 } 00808 else 00809 { 00810 _devicesize = -1; 00811 _pages = -1; 00812 _pagesize = -1; 00813 _blocks = -1; 00814 } 00815 } 00816 00817 void AT45::_select() 00818 { 00819 _ncs = 0; 00820 } 00821 00822 void AT45::_deselect() 00823 { 00824 _ncs = 1; 00825 } 00826 00827 void AT45::_busy() { 00828 volatile int iambusy = 1; 00829 while (iambusy) { 00830 // if bit 7 is set, we can proceed 00831 if ( status() & 0x80 ) { 00832 iambusy = 0;} 00833 } 00834 } 00835 00836 // Write to an SRAM buffer 00837 // Note : We create buffer and page addresses in _sram and _flash 00838 void AT45::_sramwrite(int buffer, int address, int data) 00839 { 00840 00841 int cmd = 0; 00842 int baddr = 0; 00843 00844 baddr = _getbaddr(address); 00845 00846 _busy(); 00847 00848 _select(); 00849 00850 if (buffer == 1) 00851 {cmd = 0x84;} 00852 else 00853 {cmd = 0x87;} 00854 00855 _spi.write(cmd); 00856 _sendaddr (baddr); 00857 _spi.write (data); 00858 00859 _deselect(); 00860 } 00861 00862 // Read from an SRAM buffer 00863 // Note : We create buffer and page addresses in _sram and _flash 00864 int AT45::_sramread(int buffer, int address) 00865 { 00866 00867 int cmd = 0; 00868 int baddr = 0; 00869 int bufdata = 0; 00870 00871 baddr = _getbaddr(address); 00872 00873 _select(); 00874 00875 if(buffer == 1) 00876 {cmd = 0xd4;} 00877 else 00878 {cmd = 0xd6;} 00879 00880 _spi.write(cmd); 00881 _sendaddr (baddr); 00882 _spi.write (0x0); // dont care byte 00883 bufdata = _spi.write (0x0); 00884 00885 _deselect(); 00886 00887 return (bufdata); 00888 } 00889 00890 // Write and SRAM buffer to main memory 00891 void AT45::_flashwrite (int buffer, int address) 00892 { 00893 00894 int cmd = 0; 00895 int paddr = _getpaddr(address); 00896 00897 _busy(); // Check flash is not busy 00898 00899 _select(); 00900 00901 if (buffer == 1) 00902 {cmd = 0x83;} 00903 else 00904 {cmd = 0x86;} 00905 00906 _spi.write (cmd); 00907 _sendaddr (paddr); 00908 _deselect(); 00909 00910 _busy(); // Check flash is not busy 00911 } 00912 00913 // Read from Flash memory into SRAM buffer 00914 void AT45::_flashread (int buffer, int address) 00915 { 00916 00917 int cmd = 0; 00918 int paddr = _getpaddr(address); // calculate page address 00919 00920 _busy(); // Check flash is not busy 00921 _select(); 00922 00923 if (buffer == 1) 00924 {cmd = 0x53;} 00925 else 00926 {cmd = 0x55;} 00927 00928 _spi.write (cmd); 00929 _sendaddr (paddr); 00930 _deselect(); 00931 } 00932 00933 // Read directly from main memory 00934 int AT45::_memread (int address) 00935 { 00936 00937 int data = 0; 00938 int addr; 00939 00940 addr = _getpaddr(address) | _getbaddr(address); 00941 00942 _busy(); 00943 00944 _select(); 00945 00946 _spi.write (0xd2); // Direct read command 00947 _sendaddr (addr); 00948 00949 // 4 dont care bytes 00950 _spi.write (0x00); 00951 _spi.write (0x00); 00952 _spi.write (0x00); 00953 _spi.write (0x00); 00954 00955 // this one clocks the data 00956 data = _spi.write (0x00); 00957 _deselect(); 00958 00959 _busy(); 00960 00961 return data; 00962 } 00963 00964 // Work out the page address 00965 // If we have a 2^N page size, it is just the top N bits 00966 // If we have non-2^N, we use the shifted address 00967 int AT45::_getpaddr(int address) 00968 { 00969 00970 int paddr; 00971 00972 if (_pagesize == 256) { 00973 paddr = address & 0xffffff00;} 00974 else if (_pagesize == 264) { 00975 paddr = (address << 1) & 0xfffffe00;} 00976 else if (_pagesize == 512) { 00977 paddr = address & 0xfffffe00;} 00978 else if (_pagesize == 528 ) { 00979 paddr = (address << 1) & 0xfffffc00;} 00980 else if (_pagesize == 1024) { 00981 paddr = address & 0xfffffc00;} 00982 else if (_pagesize == 1056 ) { 00983 paddr = (address << 1) & 0xfffff800;} 00984 else { 00985 paddr = -1;} 00986 00987 return (paddr); 00988 } 00989 00990 // Clean the buffer address. This is the 8/9/10 LSBs 00991 int AT45::_getbaddr(int address) 00992 { 00993 00994 int baddr; 00995 00996 if ((_pagesize == 256) || (_pagesize == 264 )) { 00997 baddr = address & 0xff;} 00998 else if ((_pagesize == 512) || (_pagesize == 528 )) { 00999 baddr = address & 0x1ff;} 01000 else if ((_pagesize == 1024) || (_pagesize == 1056 )) { 01001 baddr = address & 0x3ff;} 01002 else { 01003 baddr = -1;} 01004 01005 return (baddr); 01006 } 01007 01008 // Sends the three lest significant bytes of the supplied address 01009 void AT45::_sendaddr (int address) 01010 { 01011 _spi.write(address >> 16); 01012 _spi.write(address >> 8); 01013 _spi.write(address); 01014 }
Generated on Fri Aug 5 2022 06:17:10 by
1.7.2
