J L / Mbed 2 deprecated Neptune_170620

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Ser25lcxxx.cpp Source File

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 "mbed.h"
00025 #include "Definitions.h"
00026 #include "Ser25lcxxx.h"
00027 #include "wait_api.h"
00028 #include "NVM.h"
00029 
00030 #define HIGH(x) ((x&0xff00)>>8)
00031 #define LOW(x) (x&0xff)
00032 
00033 extern Serial pc;//Debug Port via USB
00034 extern char ramNVM[];//NVM value store
00035 
00036 Ser25LCxxx::Ser25LCxxx(SPI *spi, PinName enable, int bytes, int pagesize) {
00037     _spi=spi;
00038     _enable=new DigitalOut(enable);
00039     _size=bytes;
00040     _pageSize=pagesize;
00041     _enable->write(1);
00042 }
00043 
00044 Ser25LCxxx::~Ser25LCxxx() {
00045     delete _enable;
00046 }
00047 
00048 char* Ser25LCxxx::read(unsigned int startAdr, unsigned int len) {
00049     // assertion
00050     if (startAdr+len>_size)
00051         return NULL;
00052     char* ret=(char*)malloc(len);
00053     _enable->write(0);
00054     wait_us(1);
00055     // send address
00056     if (_size<512) { // 256 and 128 bytes
00057         _spi->write(0x03);
00058         _spi->write(LOW(startAdr));
00059     } else if (512==_size) { // 4k variant adds 9th address bit to command
00060         _spi->write(startAdr>255?0xb:0x3);
00061         _spi->write(LOW(startAdr));
00062     } else if (_size<131072) { // everything up to 512k
00063         _spi->write(0x03);
00064         _spi->write(HIGH(startAdr));
00065         _spi->write(LOW(startAdr));
00066     } else { // 25xx1024, needs 3 byte address
00067         _spi->write(0x03);
00068         _spi->write(startAdr>>16);
00069         _spi->write(HIGH(startAdr));
00070         _spi->write(LOW(startAdr));
00071     }
00072     // read data into buffer
00073     for (int i=0;i<len;i++) {
00074         ret[i]=_spi->write(0);
00075     }
00076     wait_us(1);
00077     _enable->write(1);
00078     return ret;
00079 }
00080 
00081 bool Ser25LCxxx::write(unsigned int startAdr, unsigned int len, const char* data) {
00082     if (startAdr+len>_size)
00083         return -1;
00084 
00085     int ofs=0;
00086     while (ofs<len) {
00087         // calculate amount of data to write into current page
00088         int pageLen=_pageSize-((startAdr+ofs)%_pageSize);
00089         if (ofs+pageLen>len)
00090             pageLen=len-ofs;
00091         // write single page
00092         bool b=writePage(startAdr+ofs,pageLen,data+ofs);
00093         if (!b)
00094             return false;
00095         // and switch to next page
00096         ofs+=pageLen;
00097     }
00098     return true;
00099 }
00100 
00101 bool Ser25LCxxx::writePage(unsigned int startAdr, unsigned int len, const char* data) {
00102     enableWrite();
00103 
00104     _enable->write(0);
00105     wait_us(1);
00106 
00107     if (_size<512) { // 256 and 128 bytes
00108         _spi->write(0x02);
00109         _spi->write(LOW(startAdr));
00110     } else if (512==_size) { // 4k variant adds 9th address bit to command
00111         _spi->write(startAdr>255?0xa:0x2);
00112         _spi->write(LOW(startAdr));
00113     } else if (_size<131072) { // everything up to 512k
00114         _spi->write(0x02);
00115         _spi->write(HIGH(startAdr));
00116         _spi->write(LOW(startAdr));
00117     } else { // 25xx1024, needs 3 byte address
00118         _spi->write(0x02);
00119         _spi->write(startAdr>>16);
00120         _spi->write(HIGH(startAdr));
00121         _spi->write(LOW(startAdr));
00122     }
00123 
00124     // do real write
00125     for (int i=0;i<len;i++) {
00126         _spi->write(data[i]);
00127     }
00128     wait_us(1);
00129     // disable to start physical write
00130     _enable->write(1);
00131     
00132     waitForWrite();
00133 
00134     return true;
00135 }
00136 
00137 bool Ser25LCxxx::clearPage(unsigned int pageNum) {
00138     enableWrite();
00139     if (_size<65535) {
00140         char* s=(char*)malloc(_pageSize);
00141         for (int i=0;i<_pageSize;i++) {
00142             s[i]=0xff;
00143         }
00144         bool b=writePage(_pageSize*pageNum,_pageSize,s);
00145         delete s;
00146         return b;
00147     } else {
00148         _enable->write(0);
00149         wait_us(1);
00150         _spi->write(0x42);
00151         _spi->write(HIGH(_pageSize*pageNum));
00152         _spi->write(LOW(_pageSize*pageNum));
00153         wait_us(1);
00154         _enable->write(1);
00155 
00156         waitForWrite();
00157     }
00158     return true;
00159 }
00160 
00161 void Ser25LCxxx::clearMem() {
00162     enableWrite();
00163     if (_size<65535) {
00164         for (int i=0;i<_size/_pageSize;i++) {
00165             if (!clearPage(i))
00166                 break;
00167         }
00168     }
00169     else
00170     {
00171         _enable->write(0);
00172         wait_us(1);
00173         _spi->write(0xc7);
00174         wait_us(1);
00175         _enable->write(1);
00176 
00177         waitForWrite();
00178     }
00179 }
00180 
00181 int Ser25LCxxx::readStatus() {
00182     _enable->write(0);
00183     wait_us(1);
00184     _spi->write(0x5);
00185     int status=_spi->write(0x00);
00186     wait_us(1);
00187     _enable->write(1);
00188     return status;
00189 }
00190 
00191 void Ser25LCxxx::waitForWrite() {
00192     while (true) {
00193         if (0==readStatus()&1)
00194             break;
00195         wait_us(10);
00196     }
00197 }
00198 
00199 void Ser25LCxxx::enableWrite()
00200 {
00201     _enable->write(0);
00202     wait_us(1);
00203     _spi->write(0x06);
00204     wait_us(1);
00205     _enable->write(1);
00206 }
00207 
00208 void dumpLine(char* s, int len,int disp)
00209 {
00210     for (int i=0;i<len;i++)
00211     {
00212         //ramNVM[i]=s[i];
00213 
00214         switch(disp)
00215         {
00216             case HEX:    pc.printf("\r\n|(%d) \t 0x%02X |",i,s[i]); break;
00217             //case STR:    pc.printf("%s ",s[i]); break;
00218             case CHR:    pc.printf("%c ",s[i]); break;
00219         }           
00220     }
00221 }
00222 
00223 void dump(char *s, int len,int disp)
00224 {
00225     int i=0;
00226     while (i<len)
00227     {
00228         if (i+16<len)
00229             dumpLine(s+i,16,disp);
00230         else
00231             dumpLine(s+i,len-i,disp);
00232         i+=16;
00233     }
00234 }