Class to provide simple access to I2C EEPROM chiles like Microchip's 24LC range or AMTELS AT24C range. Chips up to 64Kb in size are directly supported.

Dependents:   Test_I2CEeprom Alternator2020_06

This class provides a simple read write interface for I2C EEPROMs like Microchip's 24LC range and AMTELS AT24C range. The class ensure that writes respect the page size of the chip to ensure larger blocks can be written in one call. The class uses the supplied buffer to directly write to the chip so no extra RAM is used.

Committer:
rhourahane
Date:
Sat Jun 27 13:03:49 2015 +0000
Revision:
0:f275a33797f1
Initial commit of library.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rhourahane 0:f275a33797f1 1 /* Simple access class for Microchip 24LC EEPROM chips library
rhourahane 0:f275a33797f1 2 * Copyright (c) 2015 Robin Hourahane
rhourahane 0:f275a33797f1 3 *
rhourahane 0:f275a33797f1 4 * Licensed under the Apache License, Version 2.0 (the "License");
rhourahane 0:f275a33797f1 5 * you may not use this file except in compliance with the License.
rhourahane 0:f275a33797f1 6 * You may obtain a copy of the License at
rhourahane 0:f275a33797f1 7 *
rhourahane 0:f275a33797f1 8 * http://www.apache.org/licenses/LICENSE-2.0
rhourahane 0:f275a33797f1 9 *
rhourahane 0:f275a33797f1 10 * Unless required by applicable law or agreed to in writing, software
rhourahane 0:f275a33797f1 11 * distributed under the License is distributed on an "AS IS" BASIS,
rhourahane 0:f275a33797f1 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rhourahane 0:f275a33797f1 13 * See the License for the specific language governing permissions and
rhourahane 0:f275a33797f1 14 * limitations under the License.
rhourahane 0:f275a33797f1 15 */
rhourahane 0:f275a33797f1 16 #include "Mem24LCXX.h"
rhourahane 0:f275a33797f1 17
rhourahane 0:f275a33797f1 18 const int PageSize = 64;
rhourahane 0:f275a33797f1 19
rhourahane 0:f275a33797f1 20 Mem24LCXX::Mem24LCXX(PinName sda, PinName scl, int address, size_t chipSize, int busSpeed):
rhourahane 0:f275a33797f1 21 m_i2c(sda, scl),
rhourahane 0:f275a33797f1 22 m_i2cAddress(address),
rhourahane 0:f275a33797f1 23 m_chipSize(chipSize)
rhourahane 0:f275a33797f1 24 {
rhourahane 0:f275a33797f1 25 m_i2c.frequency(busSpeed);
rhourahane 0:f275a33797f1 26 }
rhourahane 0:f275a33797f1 27
rhourahane 0:f275a33797f1 28 size_t Mem24LCXX::read(size_t address, char &value) {
rhourahane 0:f275a33797f1 29 if (!checkSpace(address, 1))
rhourahane 0:f275a33797f1 30 return 0;
rhourahane 0:f275a33797f1 31
rhourahane 0:f275a33797f1 32 char values[] = { (address >> 8), (address & 0xFF) };
rhourahane 0:f275a33797f1 33 if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
rhourahane 0:f275a33797f1 34 if (m_i2c.read(m_i2cAddress, &value, 1) == 0) {
rhourahane 0:f275a33797f1 35 return 1;
rhourahane 0:f275a33797f1 36 }
rhourahane 0:f275a33797f1 37 }
rhourahane 0:f275a33797f1 38
rhourahane 0:f275a33797f1 39 return 0;
rhourahane 0:f275a33797f1 40 }
rhourahane 0:f275a33797f1 41
rhourahane 0:f275a33797f1 42 size_t Mem24LCXX::read(size_t address, char *buffer, size_t size) {
rhourahane 0:f275a33797f1 43 if (!checkSpace(address, size))
rhourahane 0:f275a33797f1 44 return 0;
rhourahane 0:f275a33797f1 45
rhourahane 0:f275a33797f1 46 char values[] = { (address >> 8), (address & 0xFF) };
rhourahane 0:f275a33797f1 47 if (m_i2c.write(m_i2cAddress, values, 2) == 0) {
rhourahane 0:f275a33797f1 48 if (m_i2c.read(m_i2cAddress, buffer, size) == 0) {
rhourahane 0:f275a33797f1 49 return size;
rhourahane 0:f275a33797f1 50 }
rhourahane 0:f275a33797f1 51 }
rhourahane 0:f275a33797f1 52
rhourahane 0:f275a33797f1 53 return 0;
rhourahane 0:f275a33797f1 54 }
rhourahane 0:f275a33797f1 55
rhourahane 0:f275a33797f1 56 size_t Mem24LCXX::write(size_t address, char value) {
rhourahane 0:f275a33797f1 57 if (!checkSpace(address, 1))
rhourahane 0:f275a33797f1 58 return 0;
rhourahane 0:f275a33797f1 59
rhourahane 0:f275a33797f1 60 char values[] = { (address >> 8), (address & 0xFF), value };
rhourahane 0:f275a33797f1 61 if (m_i2c.write(m_i2cAddress, values, 3) != 0) {
rhourahane 0:f275a33797f1 62 return 0;
rhourahane 0:f275a33797f1 63 }
rhourahane 0:f275a33797f1 64
rhourahane 0:f275a33797f1 65 waitForWrite();
rhourahane 0:f275a33797f1 66
rhourahane 0:f275a33797f1 67 return 1;
rhourahane 0:f275a33797f1 68 }
rhourahane 0:f275a33797f1 69
rhourahane 0:f275a33797f1 70 size_t Mem24LCXX::write(size_t address, const char *buffer, size_t size) {
rhourahane 0:f275a33797f1 71 if (!checkSpace(address, size))
rhourahane 0:f275a33797f1 72 return 0;
rhourahane 0:f275a33797f1 73
rhourahane 0:f275a33797f1 74 const char *page = buffer;
rhourahane 0:f275a33797f1 75 size_t left = size;
rhourahane 0:f275a33797f1 76
rhourahane 0:f275a33797f1 77 while (left != 0) {
rhourahane 0:f275a33797f1 78 size_t toWrite;
rhourahane 0:f275a33797f1 79 if ((address % PageSize) != 0) {
rhourahane 0:f275a33797f1 80 toWrite = (((address / PageSize) + 1) * 64) - address;
rhourahane 0:f275a33797f1 81 if (toWrite > size) {
rhourahane 0:f275a33797f1 82 toWrite = size;
rhourahane 0:f275a33797f1 83 }
rhourahane 0:f275a33797f1 84 } else {
rhourahane 0:f275a33797f1 85 if (left <= PageSize) {
rhourahane 0:f275a33797f1 86 toWrite = left;
rhourahane 0:f275a33797f1 87 } else {
rhourahane 0:f275a33797f1 88 toWrite = PageSize;
rhourahane 0:f275a33797f1 89 }
rhourahane 0:f275a33797f1 90 }
rhourahane 0:f275a33797f1 91
rhourahane 0:f275a33797f1 92 printf("Writing [%.*s] at %d size %d\n\r", toWrite, page, address, toWrite);
rhourahane 0:f275a33797f1 93 char values[] = { (address >> 8), (address & 0xFF) };
rhourahane 0:f275a33797f1 94 if (m_i2c.write(m_i2cAddress, values, 2, true) != 0) {
rhourahane 0:f275a33797f1 95 return size - left;
rhourahane 0:f275a33797f1 96 }
rhourahane 0:f275a33797f1 97
rhourahane 0:f275a33797f1 98 for (int count = 0; count != toWrite; ++count) {
rhourahane 0:f275a33797f1 99 if (m_i2c.write(*page) == 0) {
rhourahane 0:f275a33797f1 100 return size - left;
rhourahane 0:f275a33797f1 101 }
rhourahane 0:f275a33797f1 102 ++page;
rhourahane 0:f275a33797f1 103 }
rhourahane 0:f275a33797f1 104
rhourahane 0:f275a33797f1 105 m_i2c.stop();
rhourahane 0:f275a33797f1 106
rhourahane 0:f275a33797f1 107 waitForWrite();
rhourahane 0:f275a33797f1 108
rhourahane 0:f275a33797f1 109 left -= toWrite;
rhourahane 0:f275a33797f1 110 address += toWrite;
rhourahane 0:f275a33797f1 111 }
rhourahane 0:f275a33797f1 112 return size;
rhourahane 0:f275a33797f1 113 }
rhourahane 0:f275a33797f1 114
rhourahane 0:f275a33797f1 115 size_t Mem24LCXX::fill(size_t address, char value, size_t size) {
rhourahane 0:f275a33797f1 116 if (!checkSpace(address, size))
rhourahane 0:f275a33797f1 117 return 0;
rhourahane 0:f275a33797f1 118
rhourahane 0:f275a33797f1 119 size_t left = size;
rhourahane 0:f275a33797f1 120
rhourahane 0:f275a33797f1 121 while (left != 0) {
rhourahane 0:f275a33797f1 122 size_t toWrite;
rhourahane 0:f275a33797f1 123 if ((address % PageSize) != 0) {
rhourahane 0:f275a33797f1 124 toWrite = (((address / PageSize) + 1) * 64) - address;
rhourahane 0:f275a33797f1 125 if (toWrite > size) {
rhourahane 0:f275a33797f1 126 toWrite = size;
rhourahane 0:f275a33797f1 127 }
rhourahane 0:f275a33797f1 128 } else {
rhourahane 0:f275a33797f1 129 if (left <= PageSize) {
rhourahane 0:f275a33797f1 130 toWrite = left;
rhourahane 0:f275a33797f1 131 } else {
rhourahane 0:f275a33797f1 132 toWrite = PageSize;
rhourahane 0:f275a33797f1 133 }
rhourahane 0:f275a33797f1 134 }
rhourahane 0:f275a33797f1 135
rhourahane 0:f275a33797f1 136 printf("Writing %d at %d size %d\n\r", value, address, toWrite);
rhourahane 0:f275a33797f1 137 char values[] = { (address >> 8), (address & 0xFF) };
rhourahane 0:f275a33797f1 138 if (m_i2c.write(m_i2cAddress, values, 2, true) != 0) {
rhourahane 0:f275a33797f1 139 return size - left;
rhourahane 0:f275a33797f1 140 }
rhourahane 0:f275a33797f1 141
rhourahane 0:f275a33797f1 142 for (int count = 0; count != toWrite; ++count) {
rhourahane 0:f275a33797f1 143 if (m_i2c.write(value) == 0)
rhourahane 0:f275a33797f1 144 return size - left;
rhourahane 0:f275a33797f1 145 }
rhourahane 0:f275a33797f1 146
rhourahane 0:f275a33797f1 147 m_i2c.stop();
rhourahane 0:f275a33797f1 148
rhourahane 0:f275a33797f1 149 waitForWrite();
rhourahane 0:f275a33797f1 150
rhourahane 0:f275a33797f1 151 left -= toWrite;
rhourahane 0:f275a33797f1 152 address += toWrite;
rhourahane 0:f275a33797f1 153 }
rhourahane 0:f275a33797f1 154 return true;
rhourahane 0:f275a33797f1 155 }
rhourahane 0:f275a33797f1 156
rhourahane 0:f275a33797f1 157 void Mem24LCXX::waitForWrite() {
rhourahane 0:f275a33797f1 158 while (m_i2c.write(m_i2cAddress, 0, 0) != 0) {
rhourahane 0:f275a33797f1 159 // Wait for ack.
rhourahane 0:f275a33797f1 160 wait_ms(1);
rhourahane 0:f275a33797f1 161 }
rhourahane 0:f275a33797f1 162 }
rhourahane 0:f275a33797f1 163
rhourahane 0:f275a33797f1 164 bool Mem24LCXX::checkSpace(size_t address, size_t size) {
rhourahane 0:f275a33797f1 165 if ((address >= m_chipSize) || ((address + size) >= m_chipSize))
rhourahane 0:f275a33797f1 166 return false;
rhourahane 0:f275a33797f1 167 else
rhourahane 0:f275a33797f1 168 return true;
rhourahane 0:f275a33797f1 169 }
rhourahane 0:f275a33797f1 170