OSDN Git Service

[SCHEMATIC] Modify SW/MW/LW Preamp, insert galbanic-isolator replace of common-mode...
[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
32 #ifndef __SDCC
33 void i2c_writechar(unsigned char c)
34 {
35     WriteI2C(c);
36     while(SSPCON2bits.ACKSTAT);
37 }
38 #endif
39
40
41 static unsigned char i2c_eeprom_write_1block(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int size)
42 {
43     unsigned char i;
44     unsigned char *p = data;
45     unsigned char page_hi = addr >> 8;
46     unsigned char page_lo = addr & 0xff;
47
48 #ifdef __SDCC
49     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
50     I2C_START();
51     i2c_writechar(i2caddr & 0xfe);
52     i2c_writechar(page_hi);
53     i2c_writechar(page_lo);
54     for(i = 0; i < 64; i++){
55         i2c_writechar(*p++);
56     }
57     I2C_STOP();
58     i2c_close();
59 #else
60     if((size == 0) || (size > I2C_ROM_PAGE_SIZE)) return 0x00;
61     OpenI2C(MASTER, SLEW_ON);
62     SSPADD = 0x5;
63     IdleI2C();
64     StartI2C();
65     while(SSPCON2bits.SEN);
66
67     i2c_writechar(i2caddr & 0xfe);
68     i2c_writechar(page_hi);
69     i2c_writechar(page_lo);
70
71     if(!SSPCON2bits.ACKSTAT){
72         for(i = 0; i < size ; i++){
73             if(SSPCON1bits.SSPM3) {
74                 i2c_writechar(*p);
75                 IdleI2C();
76                 p++;
77             }
78         }
79     }
80     StopI2C();
81     while (SSPCON2bits.PEN);
82     idle_time_ms(2);
83     do {
84         StartI2C();
85         WriteI2C(i2caddr & 0xfe);
86         idle_time_ms(1);
87     } while(SSPCON2bits.ACKSTAT);
88     StopI2C();
89     while (SSPCON2bits.PEN);
90
91     CloseI2C();
92 #endif  //    i2c_idle();
93     return 0xff;
94 }
95
96
97
98 // I2C_IO
99 unsigned char i2c_eeprom_bytewrite(unsigned char i2caddr, unsigned int addr, unsigned char data)
100 {
101     unsigned char page_hi = addr >> 8;
102     unsigned char page_lo = addr & 0xff; // 64byte?
103     
104 #ifdef __SDCC
105     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
106     I2C_START();
107     i2c_writechar(i2caddr & 0xfe);
108     i2c_writechar(page_hi);
109     i2c_writechar(page_lo);
110     i2c_writechar(data);
111     I2C_STOP();
112     i2c_close();
113 #else
114     OpenI2C(MASTER, SLEW_ON);
115     SSPADD = 5; // 100KHz
116     IdleI2C();
117     StartI2C();
118     while(SSPCON2bits.SEN);
119
120     i2c_writechar(i2caddr & 0xfe);
121     i2c_writechar(page_hi);
122     i2c_writechar(page_lo);
123     i2c_writechar(data);
124
125     StopI2C();
126
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         *data = i2c_readchar();
191         data++;
192         I2C_ACK();
193     }
194     *data = 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 }