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.
Ser25lcxxx.cpp
- Committer:
- mariob
- Date:
- 2015-07-17
- Revision:
- 3:be69a9f6f738
- Parent:
- 2:3a3404dbd3eb
- Child:
- 4:9ac3c5c3a4c6
File content as of revision 3:be69a9f6f738:
/*
* Ser25lcxxx library
* Copyright (c) 2010 Hendrik Lipka
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "Ser25lcxxx.h"
#include "wait_api.h"
#define HIGH(x) ((x&0xff00)>>8)
#define LOW(x) (x&0xff)
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);
}
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;
}
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 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(EEPROM_CMD_WRITE);
spi.write(startAdr>>16);
spi.write(HIGH(startAdr));
spi.write(LOW(startAdr));
}
//write data
for (int i=0; i<len; i++)
spi.write(data[i]);
wait_us(1);
//disable eeprom
cs = 1;
//wait until write operation ends
if (!waitForWrite())
return 0;
return len;
}
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 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;
}
return true;
}
void Ser25LCxxx::enableWrite () {
//enable eeprom
cs = 0;
wait_us(1);
//send command
spi.write(EEPROM_CMD_WREN);
wait_us(1);
//disable eeprom
cs = 1;
}
void Ser25LCxxx::writeStatus (unsigned char val) {
enableWrite();
//enable eeprom
cs = 0;
wait_us(1);
//send command
spi.write(EEPROM_CMD_WRSR);
//write stautus
spi.write(val);
wait_us(1);
//disable eeprom
cs = 1;
}