Hotboards_eeprom.cpp - Driver to control serial (spi) eeprom memories, The memories are compatibles amount the manufactures Microchip, Atmel and ST, and of course you can control Hotboards eeprom boards (http://hotboards.org)

Dependents:   Hotboards_eeprom_write_byte Hotboards_eeprom_write_array

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Hotboards_eeprom.cpp Source File

Hotboards_eeprom.cpp

00001 /*
00002   Hotboards_eeprom.cpp - Driver to control serial (spi) eeprom memories, The memories are
00003   compatibles amount the manufactures Microchip, Atmel and ST, and of course you can control
00004   Hotboards eeprom board (http://hotboards.org)
00005   Created by Diego Perez, January 16, 2016.
00006   Released into the public domain.
00007   
00008   Density:   1Kbit   | 2Kbit   | 4Kbit   | 8Kbit   | 16Kbit  | 32Kbit  | 64Kbit  | 128Kbit | 256Kbit | 512Kbit | 1 Mbit
00009   Part:      25xx010 | 25xx020 | 25xx040 | 25xx080 | 25xx160 | 25xx320 | 25xx640 | 25xx128 | 25xx256 | 25xx512 | 25xx1024
00010   Page/Byte: 16      | 16      | 16      | 16(32)  | 16(32)  | 32      | 32      | 64      | 64      | 128     | 256
00011   Addr/Bits: 7       | 8       | 9       | 16      | 16      | 16      | 16      | 16      | 16      | 16 
00012 */
00013 #include "Hotboards_eeprom.h"
00014 
00015 #define READ     0x03
00016 #define WRITE    0x02
00017 #define WRDI     0x04
00018 #define WREN     0x06
00019 #define RDSR     0x05
00020 #define WRSR     0x01
00021 
00022 const uint16_t PageSize[ ] = { 16, 16, 16, 16, 32, 32, 64, 64, 128, 256 };
00023 const uint32_t EepromSize[ ] = { 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072 };
00024 
00025 Hotboards_eeprom::Hotboards_eeprom( SPI &spi, PinName cs, uint8_t type )
00026     : _spi(spi), _cs_pin(cs) 
00027 {
00028     _cs_pin = cs;
00029     _type = type;
00030     _page = PageSize[ type ];
00031     _density = EepromSize[ type ];
00032 }
00033 
00034 /*
00035  * just make sure the Cs pin is not clear
00036  */
00037 void Hotboards_eeprom::init( void )
00038 {
00039    _cs_pin = 1; 
00040 }
00041 
00042 /*
00043  * write a single byte in a given eeprom address, this operation will take 5ms
00044  * address: eeprom address where tha byte will be written
00045  * data: the byte that will be written at the given address 
00046  */
00047 void Hotboards_eeprom::write( uint32_t address, uint8_t data )
00048 {
00049     write( address, &data, 1 );
00050 }
00051 
00052 /*
00053  * write a given number of bytes into the eeprom atarting at a given address
00054  * address: eeprom address where tha byte will be written
00055  * data: pointer to array of bytes that need to be written
00056  * size: the number of bytes to write 
00057  */
00058 void Hotboards_eeprom::write( uint32_t address, uint8_t *data, uint16_t size )
00059 {
00060     uint16_t temp;
00061     /* just to cover your ass, check if the address is a valid direction */
00062     if( ( address < _density ) && ( size != 0 ) )
00063     {
00064         /* check if the amount of bytes to be read from the requested address do not exced the eeprom
00065         memory map if so, then only read the bytes left*/
00066         if( ( address + size ) > _density )
00067         {
00068             size = _density - address;
00069         }
00070 
00071         /* Check how many bytes are left to be written within a single page */
00072         temp = _page - ( address % _page );
00073         if( temp >= size  )
00074         {
00075             /* Data lenght can be written witihn the current page */
00076             writePage( address, data, size );
00077         }
00078         else
00079         {
00080             /* Data can not be written within the current page, so write only the bytes left */
00081             writePage( address, data, temp );
00082             /* update pointer to data, lenght and addres */
00083             data = data + temp;
00084             size = size - temp;
00085             address = address + temp;
00086                 
00087             /* Check if the remaining data is bigger than a page size */
00088             while( size > _page )
00089             {
00090                 /* Write an entire page into eeprom */
00091                 writePage( address, data, _page );
00092                 size = size - _page;
00093                 data = data + _page;
00094                 address = address + _page;
00095             }
00096             /* Write one last time if there is still data to be written */
00097             if( size != 0 )
00098             {
00099                 writePage( address, data, size );
00100             }
00101         }
00102     } 
00103 }
00104 
00105 /*
00106  * read a single byte from a given eeprom address
00107  * address: eeprom address where the byte will be read
00108  */
00109 uint8_t Hotboards_eeprom::read( uint32_t address )
00110 {
00111     uint8_t data;
00112     read( address, &data, 1 );
00113     return data;  
00114 }
00115 
00116 /*
00117  * read a given number of bytes from the eeprom starting at a given address
00118  * address: eeprom address where the bytes will be read it
00119  * data: pointer to array where data will be stored
00120  * size: the number of bytes to read 
00121  */
00122 void Hotboards_eeprom::read( uint32_t address, uint8_t *data, uint16_t size )
00123 {
00124     uint16_t i;
00125     /* just to cover your ass, check if the address is a valid direction */
00126     if( ( address < _density ) && ( size != 0 ) )
00127     {
00128         /* check if the amount of bytes to be read from the requested address do not exced the eeprom
00129         memory map if so, then only read the bytes left*/
00130         if( ( address + size ) > _density )
00131         {
00132             size = _density - address;
00133         }
00134         
00135         /* operation begins, select memory */
00136         _cs_pin = 0;
00137         
00138         /* Send command Read and address, depend on device is the number of address bytes neccesary */
00139         sendAddress( READ, address );
00140 
00141         for( i = 0 ; i<size ; i++ )
00142         {
00143             /* Read data from memory */
00144             *data = _spi.write( 0xAA );
00145             data++;
00146         };
00147         /* operation ended, unselect memory */
00148         _cs_pin = 1;
00149     }
00150 }
00151 
00152 void Hotboards_eeprom::sendAddress( uint8_t cmd, uint32_t address )
00153 {
00154     if( _type < HT_EEPROM25xx_4Kb )
00155     {
00156         /* Send the command and one byte address */
00157         _spi.write( cmd );
00158         _spi.write( address );
00159     }
00160     else if( _type == HT_EEPROM25xx_4Kb )
00161     {
00162         /* Send the command coded in the MSB of the address and one LSB address */
00163         _spi.write( cmd | ( uint8_t )( address >> 8 ) );
00164         _spi.write( ( uint8_t )address );
00165     }
00166     else if( ( _type > HT_EEPROM25xx_4Kb ) && ( _type < HT_EEPROM25xx_1Mb ) )
00167     {
00168         /* Send command plus two byte address */
00169         _spi.write( cmd );
00170         _spi.write( ( uint8_t )( address >> 8 ) );
00171         _spi.write( ( uint8_t )address );
00172     }
00173     else if( _type == HT_EEPROM25xx_1Mb )
00174     {
00175         /* Send command plus three byte address */
00176         _spi.write( cmd );
00177         _spi.write( ( uint8_t )( address >> 16 ) );
00178         _spi.write( ( uint8_t )( address >> 8 ) );
00179         _spi.write( ( uint8_t )address );
00180     }
00181 }
00182 
00183 void Hotboards_eeprom::writePage( uint32_t address, uint8_t *data, uint16_t size )
00184 {
00185     uint16_t i;
00186 
00187     /* Select memory */
00188     _cs_pin = 0;  
00189     /* write eneable latch */
00190     _spi.write( WREN );
00191     /* Unselect eeprom */
00192     _cs_pin = 1;    
00193     
00194     /* Select memory */
00195     _cs_pin = 0;  
00196     /* Send comand write and address, depend on device is the number of address bytes neccesary */
00197     sendAddress( WRITE, address );
00198     /* Send data to eeprom */
00199     for( i = 0 ; i<size ; i++ )
00200     {
00201         /* Read data from memory */
00202         _spi.write( *data );
00203         data++;
00204     };
00205     /* Unselect eeprom */
00206     _cs_pin = 1;  
00207     /* wait until data has been recorded */
00208     wait( 0.006 );  
00209 }