Library to use 25LCxxx chips
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(SPI *spi, PinName enable, uint32_t bytes, uint32_t pagesize) { 00031 _spi=spi; 00032 _enable=new DigitalOut(enable); 00033 _size=bytes; 00034 _pageSize=pagesize; 00035 _enable->write(1); 00036 } 00037 00038 Ser25LCxxx::~Ser25LCxxx() { 00039 delete _enable; 00040 } 00041 00042 uint8_t* Ser25LCxxx::read( uint32_t startAdr, uint32_t len) { 00043 // assertion 00044 if (startAdr+len>_size) 00045 return NULL; 00046 uint8_t* ret=(uint8_t*)malloc(len); 00047 _enable->write(0); 00048 wait_us(1); 00049 // send address 00050 if (_size<512) { // 256 and 128 bytes 00051 _spi->write(0x03); 00052 _spi->write(LOW(startAdr)); 00053 } else if (512==_size) { // 4k variant adds 9th address bit to command 00054 _spi->write(startAdr>255?0xb:0x3); 00055 _spi->write(LOW(startAdr)); 00056 } else if (_size<131072) { // everything up to 512k 00057 _spi->write(0x03); 00058 _spi->write(HIGH(startAdr)); 00059 _spi->write(LOW(startAdr)); 00060 } else { // 25xx1024, needs 3 byte address 00061 _spi->write(0x03); 00062 _spi->write(startAdr>>16); 00063 _spi->write(HIGH(startAdr)); 00064 _spi->write(LOW(startAdr)); 00065 } 00066 // read data into buffer 00067 for (uint8_t i=0;i<len;i++) { 00068 ret[i]=_spi->write(0); 00069 } 00070 wait_us(1); 00071 _enable->write(1); 00072 return ret; 00073 } 00074 00075 bool Ser25LCxxx::write( uint32_t startAdr, uint32_t len, const uint8_t* data) { 00076 if (startAdr+len>_size) 00077 return -1; 00078 00079 uint8_t ofs=0; 00080 while (ofs<len) { 00081 // calculate amount of data to write into current page 00082 uint8_t pageLen=_pageSize-((startAdr+ofs)%_pageSize); 00083 if (ofs+pageLen>len) 00084 pageLen=len-ofs; 00085 // write single page 00086 bool b=writePage(startAdr+ofs,pageLen,data+ofs); 00087 if (!b) 00088 return false; 00089 // and switch to next page 00090 ofs+=pageLen; 00091 } 00092 return true; 00093 } 00094 00095 bool Ser25LCxxx::writePage( uint32_t startAdr, uint32_t len, const uint8_t* data) { 00096 enableWrite(); 00097 00098 _enable->write(0); 00099 wait_us(1); 00100 00101 if (_size<512) { // 256 and 128 bytes 00102 _spi->write(0x02); 00103 _spi->write(LOW(startAdr)); 00104 } else if (512==_size) { // 4k variant adds 9th address bit to command 00105 _spi->write(startAdr>255?0xa:0x2); 00106 _spi->write(LOW(startAdr)); 00107 } else if (_size<131072) { // everything up to 512k 00108 _spi->write(0x02); 00109 _spi->write(HIGH(startAdr)); 00110 _spi->write(LOW(startAdr)); 00111 } else { // 25xx1024, needs 3 byte address 00112 _spi->write(0x02); 00113 _spi->write(startAdr>>16); 00114 _spi->write(HIGH(startAdr)); 00115 _spi->write(LOW(startAdr)); 00116 } 00117 00118 // do real write 00119 for (uint8_t i=0;i<len;i++) { 00120 _spi->write(data[i]); 00121 } 00122 wait_us(1); 00123 // disable to start physical write 00124 _enable->write(1); 00125 00126 waitForWrite(); 00127 00128 return true; 00129 } 00130 00131 bool Ser25LCxxx::clearPage( uint32_t pageNum) { 00132 enableWrite(); 00133 if (_size<65535) { 00134 uint8_t* s=(uint8_t*)malloc(_pageSize); 00135 for (uint8_t i=0;i<_pageSize;i++) { 00136 s[i]=0xff; 00137 } 00138 bool b=writePage(_pageSize*pageNum,_pageSize,s); 00139 delete s; 00140 return b; 00141 } else { 00142 _enable->write(0); 00143 wait_us(1); 00144 _spi->write(0x42); 00145 _spi->write(HIGH(_pageSize*pageNum)); 00146 _spi->write(LOW(_pageSize*pageNum)); 00147 wait_us(1); 00148 _enable->write(1); 00149 00150 waitForWrite(); 00151 } 00152 return true; 00153 } 00154 00155 void Ser25LCxxx::clearMem() { 00156 enableWrite(); 00157 if (_size<65535) { 00158 for (uint8_t i=0;i<_size/_pageSize;i++) { 00159 if (!clearPage(i)) 00160 break; 00161 } 00162 } 00163 else 00164 { 00165 _enable->write(0); 00166 wait_us(1); 00167 _spi->write(0xc7); 00168 wait_us(1); 00169 _enable->write(1); 00170 00171 waitForWrite(); 00172 } 00173 } 00174 00175 uint8_t Ser25LCxxx::readStatus() { 00176 _enable->write(0); 00177 wait_us(1); 00178 _spi->write(0x5); 00179 uint8_t status=_spi->write(0x00); 00180 wait_us(1); 00181 _enable->write(1); 00182 return status; 00183 } 00184 00185 void Ser25LCxxx::waitForWrite() { 00186 while (true) { 00187 if (0==readStatus()&1) 00188 break; 00189 wait_us(10); 00190 } 00191 } 00192 00193 void Ser25LCxxx::enableWrite() 00194 { 00195 _enable->write(0); 00196 wait_us(1); 00197 _spi->write(0x06); 00198 wait_us(1); 00199 _enable->write(1); 00200 }
Generated on Tue Aug 9 2022 16:22:07 by 1.7.2