OSDN Git Service

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