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 static unsigned char i2c_eeprom_write_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
34 unsigned char *p = data;
35 unsigned char page_hi = addr >> 8;
36 unsigned char page_lo = addr & 0xff;
39 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
41 i2c_writechar(i2caddr & 0xfe);
42 i2c_writechar(page_hi);
43 i2c_writechar(page_lo);
44 for(i = 0; i < 64; i++){
50 if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
51 OpenI2C(MASTER, SLEW_ON);
55 while(SSPCON2bits.SEN);
57 WriteI2C(i2caddr & 0xfe);
58 while(SSPCON2bits.ACKSTAT);
61 while(SSPCON2bits.ACKSTAT);
64 while(SSPCON2bits.ACKSTAT);
66 if(!SSPCON2bits.ACKSTAT){
67 for(i = 0; i < size ; i++){
68 if(SSPCON1bits.SSPM3) {
70 while(SSPCON2bits.ACKSTAT);
77 while (SSPCON2bits.PEN);
81 WriteI2C(i2caddr & 0xfe);
83 } while(SSPCON2bits.ACKSTAT);
85 while (SSPCON2bits.PEN);
93 unsigned char i2c_eeprom_bytewrite(unsigned char i2caddr, unsigned int addr, unsigned char data)
95 unsigned char page_hi = addr >> 8;
96 unsigned char page_lo = addr & 0xff; // 64byte?
99 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
101 i2c_writechar(i2caddr & 0xfe);
102 i2c_writechar(page_hi);
103 i2c_writechar(page_lo);
108 OpenI2C(MASTER, SLEW_ON);
109 SSPADD = 5; // 100KHz
112 while(SSPCON2bits.SEN);
114 WriteI2C(i2caddr & 0xfe);
115 while(SSPCON2bits.ACKSTAT);
118 while(SSPCON2bits.ACKSTAT);
121 while(SSPCON2bits.ACKSTAT);
124 while(SSPCON2bits.ACKSTAT);
127 while(SSPCON2bits.PEN);
130 WriteI2C(i2caddr & 0xfe);
132 } while(SSPCON2bits.ACKSTAT);
134 while (SSPCON2bits.PEN);
136 #endif // i2c_idle();
141 unsigned char i2c_eeprom_burstwrite(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
143 unsigned int b = bytes;
147 if((addr % I2C_ROM_PAGE_SIZE) != 0) {
148 bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
150 sts = i2c_eeprom_write_1block(i2caddr, addr, data, bb);
151 if(sts == 0) return 0;
157 while(b >= I2C_ROM_PAGE_SIZE){
158 sts = i2c_eeprom_write_1block(i2caddr, addr, data, I2C_ROM_PAGE_SIZE);
160 if(sts == 0) return 0;
161 addr += I2C_ROM_PAGE_SIZE;
162 data += I2C_ROM_PAGE_SIZE;
163 b -= I2C_ROM_PAGE_SIZE;
167 sts = i2c_eeprom_write_1block(i2caddr, addr, data, b);
173 static unsigned char i2c_eeprom_read_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
176 unsigned char page_hi = addr >> 8;
177 unsigned char page_lo = addr & 0xff;
180 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
182 i2c_writechar(addr & 0xfe);
183 i2c_writechar(page_hi);
184 i2c_writechar(page_lo);
188 i2c_writechar(addr | 0x01);
189 for(i = 0; i < I2C_ROM_PAGE_SIZE - 1 ; i++){
199 if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
200 OpenI2C(MASTER, SLEW_ON);
203 while(SSPCON2bits.SEN);
204 WriteI2C(i2caddr & 0xfe);
206 while(SSPCON2bits.SEN);
208 while(SSPCON2bits.SEN);
215 WriteI2C(i2caddr | 1);
217 for(i = 0; i < size - 1 ;i++){
218 if (!SSPCON2bits.ACKSTAT){
219 SSPCON2bits.RCEN = 1;
220 while(SSPCON2bits.RCEN);
222 // while (!SSPCON2bits.ACKEN);
228 if (!SSPCON2bits.ACKSTAT){
229 SSPCON2bits.RCEN = 1;
230 while(SSPCON2bits.RCEN);
232 while (SSPCON2bits.ACKEN);
234 while (SSPCON2bits.PEN);
246 unsigned char i2c_eeprom_byteread(unsigned char i2caddr, unsigned int addr)
248 unsigned char page_hi = addr >> 8;
249 unsigned char page_lo = addr & 0xff; // 64byte?
253 i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
255 i2c_writechar(i2caddr);
256 i2c_writechar(page_hi);
257 i2c_writechar(page_lo);
262 i2c_writechar(i2caddr | 1);
268 OpenI2C(MASTER, SLEW_ON);
271 while(SSPCON2bits.SEN);
273 while(SSPCON2bits.SEN);
275 while(SSPCON2bits.SEN);
281 WriteI2C(i2caddr | 1);
283 if (!SSPCON2bits.ACKSTAT){
284 SSPCON2bits.RCEN = 1;
285 while(SSPCON2bits.RCEN);
287 while (SSPCON2bits.ACKEN);
289 while (SSPCON2bits.PEN);
299 unsigned char i2c_eeprom_burstread(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
302 unsigned int b = bytes;
305 if((addr % I2C_ROM_PAGE_SIZE) != 0) {
306 bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
308 sts = i2c_eeprom_read_1block(i2caddr, addr, data, bb);
312 if(sts == 0) return 0;
315 while(b >= I2C_ROM_PAGE_SIZE){
316 sts = i2c_eeprom_read_1block(i2caddr, addr, data, I2C_ROM_PAGE_SIZE);
318 if(sts == 0) return 0;
319 addr += I2C_ROM_PAGE_SIZE;
320 data += I2C_ROM_PAGE_SIZE;
321 b -= I2C_ROM_PAGE_SIZE;
325 sts = i2c_eeprom_read_1block(i2caddr, addr, data, b);