Library to use 25LCxxx chips
Fork of 25LCxxx_SPI by
Diff: Ser25lcxxx.cpp
- Revision:
- 0:238ca4fdef8c
- Child:
- 1:c29a67c7034d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Ser25lcxxx.cpp Wed Jan 26 22:14:41 2011 +0000 @@ -0,0 +1,177 @@ +#include "Ser25lcxxx.h" +#include "wait_api.h" + +#define HIGH(x) ((x&0xff00)>>8) +#define LOW(x) (x&0xff) + +Ser25LCxxx::Ser25LCxxx(SPI *spi, PinName enable, int bytes, int pagesize) { + _spi=spi; + _enable=new DigitalOut(enable); + _size=bytes; + _pageSize=pagesize; + _enable->write(1); +} + +Ser25LCxxx::~Ser25LCxxx() { + delete _enable; +} + +char* Ser25LCxxx::read(unsigned int startAdr, unsigned int len) { + // assertion + if (startAdr+len>_size) + return NULL; + char* ret=(char*)malloc(len); + _enable->write(0); + wait_us(1); + // send address + if (_size<512) { // 256 and 128 bytes + _spi->write(0x03); + _spi->write(LOW(startAdr)); + } else if (512==_size) { // 4k variant adds 9th address bit to command + _spi->write(startAdr>255?0xb:0x3); + _spi->write(LOW(startAdr)); + } else if (_size<131072) { // everything up to 512k + _spi->write(0x03); + _spi->write(HIGH(startAdr)); + _spi->write(LOW(startAdr)); + } else { // 25xx1024, needs 3 byte address + _spi->write(0x03); + _spi->write(startAdr>>16); + _spi->write(HIGH(startAdr)); + _spi->write(LOW(startAdr)); + } + // read data into buffer + for (int i=0;i<len;i++) { + ret[i]=_spi->write(0); + } + wait_us(1); + _enable->write(1); + return ret; +} + +bool Ser25LCxxx::write(unsigned int startAdr, unsigned int len, const char* data) { + if (startAdr+len>_size) + return -1; + + int ofs=0; + while (ofs<len) { + // calculate amount of data to write into current page + int pageLen=_pageSize-((startAdr+ofs)%_pageSize); + if (ofs+pageLen>len) + pageLen=len-ofs; + // write single page + bool b=writePage(startAdr+ofs,pageLen,data+ofs); + if (!b) + return false; + // and switch to next page + ofs+=pageLen; + } + return true; +} + +bool Ser25LCxxx::writePage(unsigned int startAdr, unsigned int len, const char* data) { + enableWrite(); + + _enable->write(0); + wait_us(1); + + if (_size<512) { // 256 and 128 bytes + _spi->write(0x02); + _spi->write(LOW(startAdr)); + } else if (512==_size) { // 4k variant adds 9th address bit to command + _spi->write(startAdr>255?0xa:0x2); + _spi->write(LOW(startAdr)); + } else if (_size<131072) { // everything up to 512k + _spi->write(0x02); + _spi->write(HIGH(startAdr)); + _spi->write(LOW(startAdr)); + } else { // 25xx1024, needs 3 byte address + _spi->write(0x02); + _spi->write(startAdr>>16); + _spi->write(HIGH(startAdr)); + _spi->write(LOW(startAdr)); + } + + // do real write + for (int i=0;i<len;i++) { + _spi->write(data[i]); + } + wait_us(1); + // disable to start physical write + _enable->write(1); + + waitForWrite(); + + return true; +} + +bool Ser25LCxxx::clearPage(unsigned int pageNum) { + enableWrite(); + if (_size<65535) { + char* s=(char*)malloc(_pageSize); + for (int i=0;i<_pageSize;i++) { + s[i]=0xff; + } + bool b=writePage(_pageSize*pageNum,_pageSize,s); + delete s; + return b; + } else { + _enable->write(0); + wait_us(1); + _spi->write(0x42); + _spi->write(HIGH(_pageSize*pageNum)); + _spi->write(LOW(_pageSize*pageNum)); + wait_us(1); + _enable->write(1); + + waitForWrite(); + } + return true; +} + +void Ser25LCxxx::clearMem() { + enableWrite(); + if (_size<65535) { + for (int i=0;i<_size/_pageSize;i++) { + if (!clearPage(i)) + break; + } + } + else + { + _enable->write(0); + wait_us(1); + _spi->write(0xc7); + wait_us(1); + _enable->write(1); + + waitForWrite(); + } +} + +int Ser25LCxxx::readStatus() { + _enable->write(0); + wait_us(1); + _spi->write(0x5); + int status=_spi->write(0x00); + wait_us(1); + _enable->write(1); + return status; +} + +void Ser25LCxxx::waitForWrite() { + while (true) { + if (0==readStatus()&1) + break; + wait_us(10); + } +} + +void Ser25LCxxx::enableWrite() +{ + _enable->write(0); + wait_us(1); + _spi->write(0x06); + wait_us(1); + _enable->write(1); +}