4 * Copyright (C) 2013-08-25 K.Ohta <whatisthis.sowhat at gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
11 * This library / program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this library; see the file COPYING. If not, write to the
18 * Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
21 * As a special exception, if you link this(includeed from sdcc) library
22 * with other files, some of which are compiled with SDCC,
23 * to produce an executable, this library does not by itself cause
24 * the resulting executable to be covered by the GNU General Public License.
25 * This exception does not however invalidate any other reasons why
26 * the executable file might be covered by the GNU General Public License.
29 #include "i2c_eeprom.h"
31 #define I2C_ROM_PAGE_SIZE 32
34 static unsigned char i2c_eeprom_write_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
37 unsigned char *p = data;
38 unsigned char page_hi = addr >> 8;
39 unsigned char page_lo = addr & 0xff;
42 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
44 i2c_writechar(i2caddr & 0xfe);
45 i2c_writechar(page_hi);
46 i2c_writechar(page_lo);
47 for(i = 0; i < 64; i++){
53 if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
54 OpenI2C(MASTER, SLEW_ON);
58 while(SSPCON2bits.SEN);
60 WriteI2C(i2caddr & 0xfe);
61 while(SSPCON2bits.ACKSTAT);
64 while(SSPCON2bits.ACKSTAT);
67 while(SSPCON2bits.ACKSTAT);
69 if(!SSPCON2bits.ACKSTAT){
70 for(i = 0; i < size ; i++){
71 if(SSPCON1bits.SSPM3) {
73 while(SSPCON2bits.ACKSTAT);
80 while (SSPCON2bits.PEN);
84 WriteI2C(i2caddr & 0xfe);
86 } while(SSPCON2bits.ACKSTAT);
88 while (SSPCON2bits.PEN);
96 unsigned char i2c_eeprom_bytewrite(unsigned char i2caddr, unsigned int addr, unsigned char data)
98 unsigned char page_hi = addr >> 8;
99 unsigned char page_lo = addr & 0xff; // 64byte?
102 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
104 i2c_writechar(i2caddr & 0xfe);
105 i2c_writechar(page_hi);
106 i2c_writechar(page_lo);
111 OpenI2C(MASTER, SLEW_ON);
112 SSPADD = 5; // 100KHz
115 while(SSPCON2bits.SEN);
117 WriteI2C(i2caddr & 0xfe);
118 while(SSPCON2bits.ACKSTAT);
121 while(SSPCON2bits.ACKSTAT);
124 while(SSPCON2bits.ACKSTAT);
127 while(SSPCON2bits.ACKSTAT);
130 while(SSPCON2bits.PEN);
133 WriteI2C(i2caddr & 0xfe);
135 } while(SSPCON2bits.ACKSTAT);
137 while (SSPCON2bits.PEN);
139 #endif // i2c_idle();
144 unsigned char i2c_eeprom_burstwrite(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
146 unsigned int b = bytes;
150 if((addr % I2C_ROM_PAGE_SIZE) != 0) {
151 bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
153 sts = i2c_eeprom_write_1block(i2caddr, addr, data, bb);
154 if(sts == 0) return 0;
160 while(b >= I2C_ROM_PAGE_SIZE){
161 sts = i2c_eeprom_write_1block(i2caddr, addr, data, I2C_ROM_PAGE_SIZE);
163 if(sts == 0) return 0;
164 addr += I2C_ROM_PAGE_SIZE;
165 data += I2C_ROM_PAGE_SIZE;
166 b -= I2C_ROM_PAGE_SIZE;
170 sts = i2c_eeprom_write_1block(i2caddr, addr, data, b);
176 static unsigned char i2c_eeprom_read_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
179 unsigned char page_hi = addr >> 8;
180 unsigned char page_lo = addr & 0xff;
183 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
185 i2c_writechar(addr & 0xfe);
186 i2c_writechar(page_hi);
187 i2c_writechar(page_lo);
191 i2c_writechar(addr | 0x01);
192 for(i = 0; i < I2C_ROM_PAGE_SIZE - 1 ; i++){
202 if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
203 OpenI2C(MASTER, SLEW_ON);
206 while(SSPCON2bits.SEN);
207 WriteI2C(i2caddr & 0xfe);
209 while(SSPCON2bits.SEN);
211 while(SSPCON2bits.SEN);
218 WriteI2C(i2caddr | 1);
220 for(i = 0; i < size - 1 ;i++){
221 if (!SSPCON2bits.ACKSTAT){
222 SSPCON2bits.RCEN = 1;
223 while(SSPCON2bits.RCEN);
225 // while (!SSPCON2bits.ACKEN);
231 if (!SSPCON2bits.ACKSTAT){
232 SSPCON2bits.RCEN = 1;
233 while(SSPCON2bits.RCEN);
235 while (SSPCON2bits.ACKEN);
237 while (SSPCON2bits.PEN);
249 unsigned char i2c_eeprom_byteread(unsigned char i2caddr, unsigned int addr)
251 unsigned char page_hi = addr >> 8;
252 unsigned char page_lo = addr & 0xff; // 64byte?
256 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
258 i2c_writechar(i2caddr);
259 i2c_writechar(page_hi);
260 i2c_writechar(page_lo);
265 i2c_writechar(i2caddr | 1);
271 OpenI2C(MASTER, SLEW_ON);
274 while(SSPCON2bits.SEN);
276 while(SSPCON2bits.SEN);
278 while(SSPCON2bits.SEN);
284 WriteI2C(i2caddr | 1);
286 if (!SSPCON2bits.ACKSTAT){
287 SSPCON2bits.RCEN = 1;
288 while(SSPCON2bits.RCEN);
290 while (SSPCON2bits.ACKEN);
292 while (SSPCON2bits.PEN);
302 unsigned char i2c_eeprom_burstread(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
305 unsigned int b = bytes;
308 if((addr % I2C_ROM_PAGE_SIZE) != 0) {
309 bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
311 sts = i2c_eeprom_read_1block(i2caddr, addr, data, bb);
315 if(sts == 0) return 0;
318 while(b >= I2C_ROM_PAGE_SIZE){
319 sts = i2c_eeprom_read_1block(i2caddr, addr, data, I2C_ROM_PAGE_SIZE);
321 if(sts == 0) return 0;
322 addr += I2C_ROM_PAGE_SIZE;
323 data += I2C_ROM_PAGE_SIZE;
324 b -= I2C_ROM_PAGE_SIZE;
328 sts = i2c_eeprom_read_1block(i2caddr, addr, data, b);