Enhanced EEPROM 25LCxxx driver
Fork of 25LCxxx_SPI by
Embed:
(wiki syntax)
Show/hide line numbers
Ser25lcxxx.cpp
00001 /* 00002 * Ser25lcxxx library 00003 * Copyright (c) 2010 Hendrik Lipka 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a copy 00006 * of this software and associated documentation files (the "Software"), to deal 00007 * in the Software without restriction, including without limitation the rights 00008 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 * copies of the Software, and to permit persons to whom the Software is 00010 * furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included in 00013 * all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 * THE SOFTWARE. 00022 */ 00023 00024 #include "Ser25lcxxx.h" 00025 #include "wait_api.h" 00026 00027 #define HIGH(x) ((x&0xff00)>>8) 00028 #define LOW(x) (x&0xff) 00029 00030 Ser25LCxxx::Ser25LCxxx (PinName sck, PinName si, PinName so, PinName enable, 00031 int pagenumber, int pagesize): 00032 spi(si, so, sck), cs(enable) { 00033 spi.format(8,3); 00034 spi.frequency(EEPROM_SPI_SPEED); 00035 size = pagesize*pagesize; 00036 pageSize = pagesize; 00037 pageNumber = pagenumber; 00038 cs.write(1); 00039 } 00040 00041 unsigned int Ser25LCxxx::read (unsigned int startAdr, unsigned int len, 00042 unsigned char* buf) { 00043 // assertion 00044 if ((startAdr+len) > size) 00045 return 0; 00046 00047 //active the device 00048 cs = 0; 00049 wait_us(1); 00050 00051 //send command and address 00052 if (size<512) { // 256 and 128 bytes 00053 spi.write(EEPROM_CMD_READ); 00054 spi.write(LOW(startAdr)); 00055 } else if (512==size) { // 4k variant adds 9th address bit to command 00056 spi.write(startAdr>255?0xb:EEPROM_CMD_READ); 00057 spi.write(LOW(startAdr)); 00058 } else if (size<131072) { // everything up to 512k 00059 spi.write(EEPROM_CMD_READ); 00060 spi.write(HIGH(startAdr)); 00061 spi.write(LOW(startAdr)); 00062 } else { // 25xx1024, needs 3 byte address 00063 spi.write(EEPROM_CMD_READ); 00064 spi.write(startAdr>>16); 00065 spi.write(HIGH(startAdr)); 00066 spi.write(LOW(startAdr)); 00067 } 00068 00069 //read data into buffer 00070 for (int i=0; i<len; i++) 00071 buf[i] = spi.write(0); 00072 wait_us(1); 00073 00074 cs = 1; 00075 00076 return len; 00077 } 00078 00079 unsigned int Ser25LCxxx::write (unsigned int startAdr, unsigned int len, 00080 const unsigned char* data) { 00081 if ((startAdr+len) > size) 00082 return 0; 00083 00084 unsigned int remaining = len; 00085 unsigned int count = 0; 00086 00087 while (remaining > 0) { 00088 // calculate amount of data to write into current page 00089 int page_left = pageSize - (startAdr % pageSize); 00090 int to_be_written = (remaining > page_left)? page_left : remaining; 00091 if (writePage(startAdr, to_be_written, data+count) != to_be_written) 00092 return count; 00093 // and switch to next page 00094 count += to_be_written; 00095 remaining -= to_be_written; 00096 startAdr += to_be_written; 00097 } 00098 return count; 00099 } 00100 00101 unsigned int Ser25LCxxx::writePage (unsigned int startAdr, unsigned int len, 00102 const unsigned char* data) { 00103 //deactivate write-protection latch 00104 enableWrite(); 00105 00106 //activate eeprom 00107 cs = 0; 00108 wait_us(1); 00109 00110 //send command and address 00111 if (size<512) { // 256 and 128 bytes 00112 spi.write(EEPROM_CMD_WRITE); 00113 spi.write(LOW(startAdr)); 00114 } else if (512==size) { // 4k variant adds 9th address bit to command 00115 spi.write(startAdr>255?0xa:EEPROM_CMD_WRITE); 00116 spi.write(LOW(startAdr)); 00117 } else if (size<131072) { // everything up to 512k 00118 spi.write(EEPROM_CMD_WRITE); 00119 spi.write(HIGH(startAdr)); 00120 spi.write(LOW(startAdr)); 00121 } else { // 25xx1024, needs 3 byte address 00122 spi.write(EEPROM_CMD_WRITE); 00123 spi.write(startAdr>>16); 00124 spi.write(HIGH(startAdr)); 00125 spi.write(LOW(startAdr)); 00126 } 00127 00128 //write data 00129 for (int i=0; i<len; i++) 00130 spi.write(data[i]); 00131 wait_us(1); 00132 00133 //disable eeprom 00134 cs = 1; 00135 00136 //wait until write operation ends 00137 if (!waitForWrite()) 00138 return 0; 00139 00140 return len; 00141 } 00142 00143 unsigned int Ser25LCxxx::clearPage (unsigned int pageNum) { 00144 unsigned char s[pageSize]; 00145 memset(s, EEPROM_CLEAN_BYTE, pageSize); 00146 00147 return writePage(pageSize*pageNum, pageSize, s); 00148 } 00149 00150 unsigned int Ser25LCxxx::clearMem () { 00151 /* the implementation does not exploit clearPage to optimize the use 00152 of the buffer s - it is not set for each page but just once for the 00153 whole eeprom memory */ 00154 unsigned char s[pageSize]; 00155 unsigned int counter = 0; 00156 00157 memset(s, EEPROM_CLEAN_BYTE, pageSize); 00158 00159 for (int i=0; i<pageNumber; i++) { 00160 if (writePage(pageSize*i, pageSize, s) != pageSize) 00161 return counter; 00162 counter += pageSize; 00163 } 00164 00165 return counter; 00166 } 00167 00168 int Ser25LCxxx::readStatus() { 00169 //activate eeprom 00170 cs = 0; 00171 wait_us(1); 00172 00173 //send command 00174 spi.write(EEPROM_CMD_RDSR); 00175 00176 //read value 00177 int status = spi.write(0x00); 00178 wait_us(1); 00179 00180 //deactivate eeprom 00181 cs = 1; 00182 00183 return status; 00184 } 00185 00186 bool Ser25LCxxx::waitForWrite() { 00187 unsigned int counter = 0; 00188 00189 while (isWriteInProgress()) { 00190 wait_us(10); 00191 if ((++counter) > 500) 00192 return false; 00193 } 00194 00195 return true; 00196 } 00197 00198 void Ser25LCxxx::enableWrite () { 00199 //enable eeprom 00200 cs = 0; 00201 wait_us(1); 00202 00203 //send command 00204 spi.write(EEPROM_CMD_WREN); 00205 wait_us(1); 00206 00207 //disable eeprom 00208 cs = 1; 00209 } 00210 00211 void Ser25LCxxx::writeStatus (unsigned char val) { 00212 enableWrite(); 00213 00214 //enable eeprom 00215 cs = 0; 00216 wait_us(1); 00217 00218 //send command 00219 spi.write(EEPROM_CMD_WRSR); 00220 00221 //write stautus 00222 spi.write(val); 00223 wait_us(1); 00224 00225 //disable eeprom 00226 cs = 1; 00227 }
Generated on Sun Jul 24 2022 01:34:27 by
