Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: Ser25lcxxx.cpp
- Revision:
- 3:be69a9f6f738
- Parent:
- 2:3a3404dbd3eb
- Child:
- 4:9ac3c5c3a4c6
--- a/Ser25lcxxx.cpp Sat Feb 19 18:29:20 2011 +0000
+++ b/Ser25lcxxx.cpp Fri Jul 17 09:47:32 2015 +0000
@@ -24,177 +24,204 @@
#include "Ser25lcxxx.h"
#include "wait_api.h"
-#define HIGH(x) ((x&0xff00)>>8)
-#define LOW(x) (x&0xff)
+#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 (PinName sck, PinName si, PinName so, PinName enable,
+ int pagenumber, int pagesize):
+ spi(si, so, sck), cs(enable) {
+ spi.format(8,3);
+ spi.frequency(EEPROM_SPI_SPEED);
+ size = pagesize*pagesize;
+ pageSize = pagesize;
+ pageNumber = pagenumber;
+ cs.write(1);
}
-Ser25LCxxx::~Ser25LCxxx() {
- delete _enable;
+unsigned int Ser25LCxxx::read (unsigned int startAdr, unsigned int len,
+ unsigned char* buf) {
+ // assertion
+ if ((startAdr+len) > size)
+ return 0;
+
+ //active the device
+ cs = 0;
+ wait_us(1);
+
+ //send command and address
+ if (size<512) { // 256 and 128 bytes
+ spi.write(EEPROM_CMD_READ);
+ spi.write(LOW(startAdr));
+ } else if (512==size) { // 4k variant adds 9th address bit to command
+ spi.write(startAdr>255?0xb:EEPROM_CMD_READ);
+ spi.write(LOW(startAdr));
+ } else if (size<131072) { // everything up to 512k
+ spi.write(EEPROM_CMD_READ);
+ spi.write(HIGH(startAdr));
+ spi.write(LOW(startAdr));
+ } else { // 25xx1024, needs 3 byte address
+ spi.write(EEPROM_CMD_READ);
+ spi.write(startAdr>>16);
+ spi.write(HIGH(startAdr));
+ spi.write(LOW(startAdr));
+ }
+
+ //read data into buffer
+ for (int i=0; i<len; i++)
+ buf[i] = spi.write(0);
+ wait_us(1);
+
+ cs = 1;
+
+ return len;
+}
+
+unsigned int Ser25LCxxx::write (unsigned int startAdr, unsigned int len,
+ const unsigned char* data) {
+ if ((startAdr+len) > size)
+ return 0;
+
+ unsigned int remaining = len;
+ unsigned int count = 0;
+
+ while (remaining > 0) {
+ // calculate amount of data to write into current page
+ int page_left = pageSize - (startAdr % pageSize);
+ int to_be_written = (remaining > page_left)? page_left : remaining;
+ if (writePage(startAdr, to_be_written, data+count) != to_be_written)
+ return count;
+ // and switch to next page
+ count += to_be_written;
+ remaining -= to_be_written;
+ startAdr += to_be_written;
+ }
+ return count;
}
-char* Ser25LCxxx::read(unsigned int startAdr, unsigned int len) {
- // assertion
- if (startAdr+len>_size)
- return NULL;
- char* ret=(char*)malloc(len);
- _enable->write(0);
+unsigned int Ser25LCxxx::writePage (unsigned int startAdr, unsigned int len,
+ const unsigned char* data) {
+ //deactivate write-protection latch
+ enableWrite();
+
+ //activate eeprom
+ cs = 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));
+
+ //send command and address
+ if (size<512) { // 256 and 128 bytes
+ spi.write(EEPROM_CMD_WRITE);
+ spi.write(LOW(startAdr));
+ } else if (512==size) { // 4k variant adds 9th address bit to command
+ spi.write(startAdr>255?0xa:EEPROM_CMD_WRITE);
+ spi.write(LOW(startAdr));
+ } else if (size<131072) { // everything up to 512k
+ spi.write(EEPROM_CMD_WRITE);
+ 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));
+ spi.write(EEPROM_CMD_WRITE);
+ 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);
- }
+
+ //write data
+ for (int i=0; i<len; i++)
+ spi.write(data[i]);
wait_us(1);
- _enable->write(1);
- return ret;
+
+ //disable eeprom
+ cs = 1;
+
+ //wait until write operation ends
+ if (!waitForWrite())
+ return 0;
+
+ return len;
}
-bool Ser25LCxxx::write(unsigned int startAdr, unsigned int len, const char* data) {
- if (startAdr+len>_size)
- return -1;
+unsigned int Ser25LCxxx::clearPage (unsigned int pageNum) {
+ unsigned char s[pageSize];
+ memset(s, EEPROM_CLEAN_BYTE, pageSize);
+
+ return writePage(pageSize*pageNum, pageSize, s);
+}
+
+unsigned int Ser25LCxxx::clearMem () {
+ /* the implementation does not exploit clearPage to optimize the use
+ of the buffer s - it is not set for each page but just once for the
+ whole eeprom memory */
+ unsigned char s[pageSize];
+ unsigned int counter = 0;
+
+ memset(s, EEPROM_CLEAN_BYTE, pageSize);
+
+ for (int i=0; i<pageNumber; i++) {
+ if (writePage(pageSize*i, pageSize, s) != pageSize)
+ return counter;
+ counter += pageSize;
+ }
+
+ return counter;
+}
- 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)
+int Ser25LCxxx::readStatus() {
+ //activate eeprom
+ cs = 0;
+ wait_us(1);
+
+ //send command
+ spi.write(EEPROM_CMD_RDSR);
+
+ //read value
+ int status = spi.write(0x00);
+ wait_us(1);
+
+ //deactivate eeprom
+ cs = 1;
+
+ return status;
+}
+
+bool Ser25LCxxx::waitForWrite() {
+ unsigned int counter = 0;
+
+ while (isWriteInProgress()) {
+ wait_us(10);
+ if ((++counter) > 500)
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);
+void Ser25LCxxx::enableWrite () {
+ //enable eeprom
+ cs = 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]);
- }
+ //send command
+ spi.write(EEPROM_CMD_WREN);
wait_us(1);
- // disable to start physical write
- _enable->write(1);
- waitForWrite();
-
- return true;
+ //disable eeprom
+ cs = 1;
}
-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() {
+void Ser25LCxxx::writeStatus (unsigned char val) {
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);
+ //enable eeprom
+ cs = 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);
- }
-}
+ //send command
+ spi.write(EEPROM_CMD_WRSR);
+
+ //write stautus
+ spi.write(val);
+ wait_us(1);
-void Ser25LCxxx::enableWrite()
-{
- _enable->write(0);
- wait_us(1);
- _spi->write(0x06);
- wait_us(1);
- _enable->write(1);
+ //disable eeprom
+ cs = 1;
}