OSDN Git Service

[I2C][EEPROM] Set I2CEEPROM_ADDR in i2c_eeprom.h as ROM's ADDR.
[openi2cradio/OpenI2CRadio.git] / i2c_eeprom.c
1 /*
2  * OpenI2CRADIO
3  * I2C EEPROM Handler
4  * Copyright (C) 2013-08-25 K.Ohta <whatisthis.sowhat at gmail.com>
5  * License: GPL2+LE
6  *
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.
15  *
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,
19  *  MA 02110-1301, USA.
20  *
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.
27  */
28
29 #include "i2c_eeprom.h"
30
31 static unsigned char i2c_eeprom_write_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
32 {
33     unsigned char i;
34     unsigned char *p = data;
35     unsigned char page_hi = addr >> 8;
36     unsigned char page_lo = addr & 0xff;
37
38 #ifdef __SDCC
39     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
40     I2C_START();
41     i2c_writechar(i2caddr & 0xfe);
42     i2c_writechar(page_hi);
43     i2c_writechar(page_lo);
44     for(i = 0; i < 64; i++){
45         i2c_writechar(*p++);
46     }
47     I2C_STOP();
48     i2c_close();
49 #else
50     if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
51     OpenI2C(MASTER, SLEW_ON);
52     SSPADD = 0x5;
53     IdleI2C();
54     StartI2C();
55     while(SSPCON2bits.SEN);
56
57     WriteI2C(i2caddr & 0xfe);
58     while(SSPCON2bits.ACKSTAT);
59
60     WriteI2C(page_hi);
61     while(SSPCON2bits.ACKSTAT);
62
63     WriteI2C(page_lo);
64     while(SSPCON2bits.ACKSTAT);
65
66     if(!SSPCON2bits.ACKSTAT){
67         for(i = 0; i < size ; i++){
68             if(SSPCON1bits.SSPM3) {
69                 WriteI2C(*p);
70                 while(SSPCON2bits.ACKSTAT);
71             IdleI2C();
72             p++;
73             }
74         }
75     }
76     StopI2C();
77     while (SSPCON2bits.PEN);
78     idle_time_ms(2);
79     do {
80         StartI2C();
81         WriteI2C(i2caddr & 0xfe);
82         idle_time_ms(1);
83     } while(SSPCON2bits.ACKSTAT);
84     StopI2C();
85     while (SSPCON2bits.PEN);
86
87     CloseI2C();
88 #endif  //    i2c_idle();
89     return 0xff;
90 }
91
92 // I2C_IO
93 unsigned char i2c_eeprom_bytewrite(unsigned char i2caddr, unsigned int addr, unsigned char data)
94 {
95     unsigned char page_hi = addr >> 8;
96     unsigned char page_lo = addr & 0xff; // 64byte?
97     
98 #ifdef __SDCC
99     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
100     I2C_START();
101     i2c_writechar(i2caddr & 0xfe);
102     i2c_writechar(page_hi);
103     i2c_writechar(page_lo);
104     i2c_writechar(data);
105     I2C_STOP();
106     i2c_close();
107 #else
108     OpenI2C(MASTER, SLEW_ON);
109     SSPADD = 5; // 100KHz
110     IdleI2C();
111     StartI2C();
112     while(SSPCON2bits.SEN);
113
114     WriteI2C(i2caddr & 0xfe);
115     while(SSPCON2bits.ACKSTAT);
116
117     WriteI2C(page_hi);
118     while(SSPCON2bits.ACKSTAT);
119
120     WriteI2C(page_lo);
121     while(SSPCON2bits.ACKSTAT);
122
123     WriteI2C(data);
124     while(SSPCON2bits.ACKSTAT);
125
126     StopI2C();
127     while(SSPCON2bits.PEN);
128     do {
129         StartI2C();
130         WriteI2C(i2caddr & 0xfe);
131         idle_time_ms(1);
132     } while(SSPCON2bits.ACKSTAT);
133     StopI2C();
134     while (SSPCON2bits.PEN);
135     CloseI2C();
136 #endif  //    i2c_idle();
137     return 0xff;
138 }
139
140
141 unsigned char i2c_eeprom_burstwrite(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
142 {
143     unsigned int b = bytes;
144     unsigned int bb;
145     unsigned char sts;
146
147     if((addr % I2C_ROM_PAGE_SIZE) != 0) {
148         bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
149         if(b <= bb) bb = b;
150         sts = i2c_eeprom_write_1block(i2caddr, addr, data, bb);
151         if(sts == 0) return 0;
152         b -= bb;
153         addr += bb;
154         data += bb;
155     }
156
157     while(b >= I2C_ROM_PAGE_SIZE){
158         sts = i2c_eeprom_write_1block(i2caddr,  addr, data, I2C_ROM_PAGE_SIZE);
159 //        idle_time_ms(15);
160         if(sts == 0) return 0;
161         addr += I2C_ROM_PAGE_SIZE;
162         data += I2C_ROM_PAGE_SIZE;
163         b -= I2C_ROM_PAGE_SIZE;
164     }
165
166     if(b != 0){
167         sts = i2c_eeprom_write_1block(i2caddr,  addr, data, b);
168     }
169     return sts;
170 }
171
172
173 static unsigned char i2c_eeprom_read_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
174 {
175     unsigned char i;
176     unsigned char page_hi = addr >> 8;
177     unsigned char page_lo = addr & 0xff;
178
179   #ifdef __SDCC
180     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
181     I2C_START();
182     i2c_writechar(addr & 0xfe);
183     i2c_writechar(page_hi);
184     i2c_writechar(page_lo);
185
186 //   delay100tcy(2);
187     I2C_START();
188     i2c_writechar(addr | 0x01);
189     for(i = 0; i < I2C_ROM_PAGE_SIZE - 1 ; i++){
190         *p = i2c_readchar();
191         p++;
192         I2C_ACK();
193     }
194     *p = i2c_readchar();
195     I2C_NACK();
196     I2C_STOP();
197     i2c_close();
198 #else
199     if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
200     OpenI2C(MASTER, SLEW_ON);
201     SSPADD = 0x5;
202     StartI2C();
203     while(SSPCON2bits.SEN);
204     WriteI2C(i2caddr & 0xfe);
205   //  delay1ktcy(8);
206     while(SSPCON2bits.SEN);
207     WriteI2C(page_hi);
208     while(SSPCON2bits.SEN);
209     WriteI2C(page_lo);
210   //  delay1ktcy(8);
211     StopI2C();
212
213     IdleI2C();
214     StartI2C();
215     WriteI2C(i2caddr | 1);
216
217     for(i = 0; i < size - 1 ;i++){
218        if (!SSPCON2bits.ACKSTAT){
219         SSPCON2bits.RCEN = 1;
220         while(SSPCON2bits.RCEN);
221          AckI2C();
222 //          while (!SSPCON2bits.ACKEN);
223         *data = SSPBUF;
224          data++;
225         }
226     }
227
228     if (!SSPCON2bits.ACKSTAT){
229       SSPCON2bits.RCEN = 1;
230       while(SSPCON2bits.RCEN);
231       NotAckI2C();
232       while (SSPCON2bits.ACKEN);
233       StopI2C();
234       while (SSPCON2bits.PEN);
235     }
236     *data = SSPBUF;
237
238     CloseI2C();
239 #endif
240     //    CLOSEASMASTER();
241     return 0xff;
242 }
243
244
245 // I2C_IO
246 unsigned char i2c_eeprom_byteread(unsigned char i2caddr, unsigned int addr)
247 {
248     unsigned char page_hi = addr >> 8;
249     unsigned char page_lo = addr & 0xff; // 64byte?
250     unsigned char c;
251
252   #ifdef __SDCC
253     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
254     I2C_START();
255     i2c_writechar(i2caddr);
256     i2c_writechar(page_hi);
257     i2c_writechar(page_lo);
258     I2C_STOP();
259     i2c_idle();
260 //   delay100tcy(2);
261     I2C_START();
262     i2c_writechar(i2caddr | 1);
263     c = i2c_readchar();
264     I2C_ACK();
265     I2C_STOP();
266     i2c_close();
267 #else
268     OpenI2C(MASTER, SLEW_ON);
269     SSPADD = 0x5;
270     StartI2C();
271     while(SSPCON2bits.SEN);
272     WriteI2C(i2caddr);
273     while(SSPCON2bits.SEN);
274     WriteI2C(page_hi);
275     while(SSPCON2bits.SEN);
276     WriteI2C(page_lo);
277     StopI2C();
278
279     IdleI2C();
280     StartI2C();
281     WriteI2C(i2caddr | 1);
282
283     if (!SSPCON2bits.ACKSTAT){
284       SSPCON2bits.RCEN = 1;
285       while(SSPCON2bits.RCEN);
286       NotAckI2C();
287       while (SSPCON2bits.ACKEN);
288       StopI2C();
289       while (SSPCON2bits.PEN);
290     }
291     c = SSPBUF;
292     CloseI2C();
293 #endif
294     //    CLOSEASMASTER();
295     return c;
296 }
297
298
299 unsigned char i2c_eeprom_burstread(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
300 {
301     unsigned char sts;
302     unsigned int b = bytes;
303     unsigned int bb;
304
305     if((addr % I2C_ROM_PAGE_SIZE) != 0) {
306         bb = I2C_ROM_PAGE_SIZE - (addr % I2C_ROM_PAGE_SIZE);
307         if(b <= bb) bb = b;
308         sts = i2c_eeprom_read_1block(i2caddr, addr, data, bb);
309         b -= bb;
310         addr += bb;
311         data += bb;
312         if(sts == 0) return 0;
313     }
314
315     while(b >= I2C_ROM_PAGE_SIZE){
316         sts = i2c_eeprom_read_1block(i2caddr,  addr, data, I2C_ROM_PAGE_SIZE);
317 //        idle_time_ms(15);
318         if(sts == 0) return 0;
319         addr += I2C_ROM_PAGE_SIZE;
320         data += I2C_ROM_PAGE_SIZE;
321         b -= I2C_ROM_PAGE_SIZE;
322     }
323
324     if(b != 0){
325         sts = i2c_eeprom_read_1block(i2caddr,  addr, data, b);
326     }
327     return sts;
328 }