Jarkko Säkkinen / Mbed 2 deprecated TEMP_YM2

Dependencies:   BLE_API TMP_nrf51 mbed nRF51822

Fork of VTT_NODEV3_BMP180_Si7021 by Juho Eskeli

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AT45.cpp Source File

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&#65533;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&#65533; 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&#65533;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&#65533; 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 }