Enhanced EEPROM 25LCxxx driver

Dependents:   eeprom_test

Fork of 25LCxxx_SPI by Hendrik Lipka

Committer:
mariob
Date:
Fri Jul 17 09:47:32 2015 +0000
Revision:
3:be69a9f6f738
Parent:
2:3a3404dbd3eb
added fix in writing function; fixed write check; added features (protection bits); changed interfaces

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hlipka 2:3a3404dbd3eb 1 /*
hlipka 2:3a3404dbd3eb 2 * Ser25lcxxx library
hlipka 2:3a3404dbd3eb 3 * Copyright (c) 2010 Hendrik Lipka
hlipka 2:3a3404dbd3eb 4 *
hlipka 2:3a3404dbd3eb 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
hlipka 2:3a3404dbd3eb 6 * of this software and associated documentation files (the "Software"), to deal
hlipka 2:3a3404dbd3eb 7 * in the Software without restriction, including without limitation the rights
hlipka 2:3a3404dbd3eb 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
hlipka 2:3a3404dbd3eb 9 * copies of the Software, and to permit persons to whom the Software is
hlipka 2:3a3404dbd3eb 10 * furnished to do so, subject to the following conditions:
hlipka 2:3a3404dbd3eb 11 *
hlipka 2:3a3404dbd3eb 12 * The above copyright notice and this permission notice shall be included in
hlipka 2:3a3404dbd3eb 13 * all copies or substantial portions of the Software.
hlipka 2:3a3404dbd3eb 14 *
hlipka 2:3a3404dbd3eb 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
hlipka 2:3a3404dbd3eb 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
hlipka 2:3a3404dbd3eb 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
hlipka 2:3a3404dbd3eb 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
hlipka 2:3a3404dbd3eb 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
hlipka 2:3a3404dbd3eb 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
hlipka 2:3a3404dbd3eb 21 * THE SOFTWARE.
hlipka 2:3a3404dbd3eb 22 */
hlipka 2:3a3404dbd3eb 23
hlipka 0:238ca4fdef8c 24 #include "Ser25lcxxx.h"
hlipka 0:238ca4fdef8c 25 #include "wait_api.h"
hlipka 0:238ca4fdef8c 26
mariob 3:be69a9f6f738 27 #define HIGH(x) ((x&0xff00)>>8)
mariob 3:be69a9f6f738 28 #define LOW(x) (x&0xff)
hlipka 0:238ca4fdef8c 29
mariob 3:be69a9f6f738 30 Ser25LCxxx::Ser25LCxxx (PinName sck, PinName si, PinName so, PinName enable,
mariob 3:be69a9f6f738 31 int pagenumber, int pagesize):
mariob 3:be69a9f6f738 32 spi(si, so, sck), cs(enable) {
mariob 3:be69a9f6f738 33 spi.format(8,3);
mariob 3:be69a9f6f738 34 spi.frequency(EEPROM_SPI_SPEED);
mariob 3:be69a9f6f738 35 size = pagesize*pagesize;
mariob 3:be69a9f6f738 36 pageSize = pagesize;
mariob 3:be69a9f6f738 37 pageNumber = pagenumber;
mariob 3:be69a9f6f738 38 cs.write(1);
hlipka 0:238ca4fdef8c 39 }
hlipka 0:238ca4fdef8c 40
mariob 3:be69a9f6f738 41 unsigned int Ser25LCxxx::read (unsigned int startAdr, unsigned int len,
mariob 3:be69a9f6f738 42 unsigned char* buf) {
mariob 3:be69a9f6f738 43 // assertion
mariob 3:be69a9f6f738 44 if ((startAdr+len) > size)
mariob 3:be69a9f6f738 45 return 0;
mariob 3:be69a9f6f738 46
mariob 3:be69a9f6f738 47 //active the device
mariob 3:be69a9f6f738 48 cs = 0;
mariob 3:be69a9f6f738 49 wait_us(1);
mariob 3:be69a9f6f738 50
mariob 3:be69a9f6f738 51 //send command and address
mariob 3:be69a9f6f738 52 if (size<512) { // 256 and 128 bytes
mariob 3:be69a9f6f738 53 spi.write(EEPROM_CMD_READ);
mariob 3:be69a9f6f738 54 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 55 } else if (512==size) { // 4k variant adds 9th address bit to command
mariob 3:be69a9f6f738 56 spi.write(startAdr>255?0xb:EEPROM_CMD_READ);
mariob 3:be69a9f6f738 57 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 58 } else if (size<131072) { // everything up to 512k
mariob 3:be69a9f6f738 59 spi.write(EEPROM_CMD_READ);
mariob 3:be69a9f6f738 60 spi.write(HIGH(startAdr));
mariob 3:be69a9f6f738 61 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 62 } else { // 25xx1024, needs 3 byte address
mariob 3:be69a9f6f738 63 spi.write(EEPROM_CMD_READ);
mariob 3:be69a9f6f738 64 spi.write(startAdr>>16);
mariob 3:be69a9f6f738 65 spi.write(HIGH(startAdr));
mariob 3:be69a9f6f738 66 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 67 }
mariob 3:be69a9f6f738 68
mariob 3:be69a9f6f738 69 //read data into buffer
mariob 3:be69a9f6f738 70 for (int i=0; i<len; i++)
mariob 3:be69a9f6f738 71 buf[i] = spi.write(0);
mariob 3:be69a9f6f738 72 wait_us(1);
mariob 3:be69a9f6f738 73
mariob 3:be69a9f6f738 74 cs = 1;
mariob 3:be69a9f6f738 75
mariob 3:be69a9f6f738 76 return len;
mariob 3:be69a9f6f738 77 }
mariob 3:be69a9f6f738 78
mariob 3:be69a9f6f738 79 unsigned int Ser25LCxxx::write (unsigned int startAdr, unsigned int len,
mariob 3:be69a9f6f738 80 const unsigned char* data) {
mariob 3:be69a9f6f738 81 if ((startAdr+len) > size)
mariob 3:be69a9f6f738 82 return 0;
mariob 3:be69a9f6f738 83
mariob 3:be69a9f6f738 84 unsigned int remaining = len;
mariob 3:be69a9f6f738 85 unsigned int count = 0;
mariob 3:be69a9f6f738 86
mariob 3:be69a9f6f738 87 while (remaining > 0) {
mariob 3:be69a9f6f738 88 // calculate amount of data to write into current page
mariob 3:be69a9f6f738 89 int page_left = pageSize - (startAdr % pageSize);
mariob 3:be69a9f6f738 90 int to_be_written = (remaining > page_left)? page_left : remaining;
mariob 3:be69a9f6f738 91 if (writePage(startAdr, to_be_written, data+count) != to_be_written)
mariob 3:be69a9f6f738 92 return count;
mariob 3:be69a9f6f738 93 // and switch to next page
mariob 3:be69a9f6f738 94 count += to_be_written;
mariob 3:be69a9f6f738 95 remaining -= to_be_written;
mariob 3:be69a9f6f738 96 startAdr += to_be_written;
mariob 3:be69a9f6f738 97 }
mariob 3:be69a9f6f738 98 return count;
hlipka 0:238ca4fdef8c 99 }
hlipka 0:238ca4fdef8c 100
mariob 3:be69a9f6f738 101 unsigned int Ser25LCxxx::writePage (unsigned int startAdr, unsigned int len,
mariob 3:be69a9f6f738 102 const unsigned char* data) {
mariob 3:be69a9f6f738 103 //deactivate write-protection latch
mariob 3:be69a9f6f738 104 enableWrite();
mariob 3:be69a9f6f738 105
mariob 3:be69a9f6f738 106 //activate eeprom
mariob 3:be69a9f6f738 107 cs = 0;
hlipka 0:238ca4fdef8c 108 wait_us(1);
mariob 3:be69a9f6f738 109
mariob 3:be69a9f6f738 110 //send command and address
mariob 3:be69a9f6f738 111 if (size<512) { // 256 and 128 bytes
mariob 3:be69a9f6f738 112 spi.write(EEPROM_CMD_WRITE);
mariob 3:be69a9f6f738 113 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 114 } else if (512==size) { // 4k variant adds 9th address bit to command
mariob 3:be69a9f6f738 115 spi.write(startAdr>255?0xa:EEPROM_CMD_WRITE);
mariob 3:be69a9f6f738 116 spi.write(LOW(startAdr));
mariob 3:be69a9f6f738 117 } else if (size<131072) { // everything up to 512k
mariob 3:be69a9f6f738 118 spi.write(EEPROM_CMD_WRITE);
mariob 3:be69a9f6f738 119 spi.write(HIGH(startAdr));
mariob 3:be69a9f6f738 120 spi.write(LOW(startAdr));
hlipka 0:238ca4fdef8c 121 } else { // 25xx1024, needs 3 byte address
mariob 3:be69a9f6f738 122 spi.write(EEPROM_CMD_WRITE);
mariob 3:be69a9f6f738 123 spi.write(startAdr>>16);
mariob 3:be69a9f6f738 124 spi.write(HIGH(startAdr));
mariob 3:be69a9f6f738 125 spi.write(LOW(startAdr));
hlipka 0:238ca4fdef8c 126 }
mariob 3:be69a9f6f738 127
mariob 3:be69a9f6f738 128 //write data
mariob 3:be69a9f6f738 129 for (int i=0; i<len; i++)
mariob 3:be69a9f6f738 130 spi.write(data[i]);
hlipka 0:238ca4fdef8c 131 wait_us(1);
mariob 3:be69a9f6f738 132
mariob 3:be69a9f6f738 133 //disable eeprom
mariob 3:be69a9f6f738 134 cs = 1;
mariob 3:be69a9f6f738 135
mariob 3:be69a9f6f738 136 //wait until write operation ends
mariob 3:be69a9f6f738 137 if (!waitForWrite())
mariob 3:be69a9f6f738 138 return 0;
mariob 3:be69a9f6f738 139
mariob 3:be69a9f6f738 140 return len;
hlipka 0:238ca4fdef8c 141 }
hlipka 0:238ca4fdef8c 142
mariob 3:be69a9f6f738 143 unsigned int Ser25LCxxx::clearPage (unsigned int pageNum) {
mariob 3:be69a9f6f738 144 unsigned char s[pageSize];
mariob 3:be69a9f6f738 145 memset(s, EEPROM_CLEAN_BYTE, pageSize);
mariob 3:be69a9f6f738 146
mariob 3:be69a9f6f738 147 return writePage(pageSize*pageNum, pageSize, s);
mariob 3:be69a9f6f738 148 }
mariob 3:be69a9f6f738 149
mariob 3:be69a9f6f738 150 unsigned int Ser25LCxxx::clearMem () {
mariob 3:be69a9f6f738 151 /* the implementation does not exploit clearPage to optimize the use
mariob 3:be69a9f6f738 152 of the buffer s - it is not set for each page but just once for the
mariob 3:be69a9f6f738 153 whole eeprom memory */
mariob 3:be69a9f6f738 154 unsigned char s[pageSize];
mariob 3:be69a9f6f738 155 unsigned int counter = 0;
mariob 3:be69a9f6f738 156
mariob 3:be69a9f6f738 157 memset(s, EEPROM_CLEAN_BYTE, pageSize);
mariob 3:be69a9f6f738 158
mariob 3:be69a9f6f738 159 for (int i=0; i<pageNumber; i++) {
mariob 3:be69a9f6f738 160 if (writePage(pageSize*i, pageSize, s) != pageSize)
mariob 3:be69a9f6f738 161 return counter;
mariob 3:be69a9f6f738 162 counter += pageSize;
mariob 3:be69a9f6f738 163 }
mariob 3:be69a9f6f738 164
mariob 3:be69a9f6f738 165 return counter;
mariob 3:be69a9f6f738 166 }
hlipka 0:238ca4fdef8c 167
mariob 3:be69a9f6f738 168 int Ser25LCxxx::readStatus() {
mariob 3:be69a9f6f738 169 //activate eeprom
mariob 3:be69a9f6f738 170 cs = 0;
mariob 3:be69a9f6f738 171 wait_us(1);
mariob 3:be69a9f6f738 172
mariob 3:be69a9f6f738 173 //send command
mariob 3:be69a9f6f738 174 spi.write(EEPROM_CMD_RDSR);
mariob 3:be69a9f6f738 175
mariob 3:be69a9f6f738 176 //read value
mariob 3:be69a9f6f738 177 int status = spi.write(0x00);
mariob 3:be69a9f6f738 178 wait_us(1);
mariob 3:be69a9f6f738 179
mariob 3:be69a9f6f738 180 //deactivate eeprom
mariob 3:be69a9f6f738 181 cs = 1;
mariob 3:be69a9f6f738 182
mariob 3:be69a9f6f738 183 return status;
mariob 3:be69a9f6f738 184 }
mariob 3:be69a9f6f738 185
mariob 3:be69a9f6f738 186 bool Ser25LCxxx::waitForWrite() {
mariob 3:be69a9f6f738 187 unsigned int counter = 0;
mariob 3:be69a9f6f738 188
mariob 3:be69a9f6f738 189 while (isWriteInProgress()) {
mariob 3:be69a9f6f738 190 wait_us(10);
mariob 3:be69a9f6f738 191 if ((++counter) > 500)
hlipka 0:238ca4fdef8c 192 return false;
hlipka 0:238ca4fdef8c 193 }
mariob 3:be69a9f6f738 194
hlipka 0:238ca4fdef8c 195 return true;
hlipka 0:238ca4fdef8c 196 }
hlipka 0:238ca4fdef8c 197
mariob 3:be69a9f6f738 198 void Ser25LCxxx::enableWrite () {
mariob 3:be69a9f6f738 199 //enable eeprom
mariob 3:be69a9f6f738 200 cs = 0;
hlipka 0:238ca4fdef8c 201 wait_us(1);
hlipka 0:238ca4fdef8c 202
mariob 3:be69a9f6f738 203 //send command
mariob 3:be69a9f6f738 204 spi.write(EEPROM_CMD_WREN);
hlipka 0:238ca4fdef8c 205 wait_us(1);
hlipka 0:238ca4fdef8c 206
mariob 3:be69a9f6f738 207 //disable eeprom
mariob 3:be69a9f6f738 208 cs = 1;
hlipka 0:238ca4fdef8c 209 }
hlipka 0:238ca4fdef8c 210
mariob 3:be69a9f6f738 211 void Ser25LCxxx::writeStatus (unsigned char val) {
hlipka 0:238ca4fdef8c 212 enableWrite();
hlipka 0:238ca4fdef8c 213
mariob 3:be69a9f6f738 214 //enable eeprom
mariob 3:be69a9f6f738 215 cs = 0;
hlipka 0:238ca4fdef8c 216 wait_us(1);
hlipka 0:238ca4fdef8c 217
mariob 3:be69a9f6f738 218 //send command
mariob 3:be69a9f6f738 219 spi.write(EEPROM_CMD_WRSR);
mariob 3:be69a9f6f738 220
mariob 3:be69a9f6f738 221 //write stautus
mariob 3:be69a9f6f738 222 spi.write(val);
mariob 3:be69a9f6f738 223 wait_us(1);
hlipka 0:238ca4fdef8c 224
mariob 3:be69a9f6f738 225 //disable eeprom
mariob 3:be69a9f6f738 226 cs = 1;
hlipka 0:238ca4fdef8c 227 }