OSDN Git Service

[I2CEEPROM] Byte read/write is okay, but blockread/write is not tested yet.
[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 char page_hi, unsigned char page_lo, unsigned char *data)
32 {
33     unsigned char i;
34     unsigned char *p = data;
35
36 #ifdef __SDCC
37     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
38     I2C_START();
39     i2c_writechar(i2caddr & 0xfe);
40     i2c_writechar(page_hi);
41     i2c_writechar(page_lo);
42     for(i = 0; i < 64; i++){
43         i2c_writechar(*p++);
44     }
45     I2C_STOP();
46     i2c_close();
47 #else
48     OpenI2C(MASTER, SLEW_ON);
49     SSPADD = 0x5;
50     IdleI2C();
51     StartI2C();
52  //   while (SSPCON2bits.SEN);
53     WriteI2C(i2caddr & 0xfe);
54 //    while(SSPCON2bits.SEN);
55     WriteI2C(page_hi);
56 //    while(SSPCON2bits.SEN);
57     WriteI2C(page_lo);
58
59 //   IdleI2C();
60    for(i = 0; i < 32; i++){
61         WriteI2C(*p);
62         IdleI2C();
63         p++;
64     }
65     StopI2C();
66     do {
67         StartI2C();
68         WriteI2C(i2caddr & 0xfe);
69         idle_time_ms(1);
70     } while(SSPCON2bits.ACKSTAT);
71 //    StopI2C();
72 //    while (SSPCON2bits.PEN);
73     CloseI2C();
74 #endif  //    i2c_idle();
75     return 0xff;
76 }
77
78 // I2C_IO
79 unsigned char i2c_eeprom_bytewrite(unsigned char i2caddr, unsigned int addr, unsigned char data)
80 {
81     unsigned char page_hi = addr >> 8;
82     unsigned char page_lo = addr & 0xff; // 64byte?
83     
84 #ifdef __SDCC
85     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
86     I2C_START();
87     i2c_writechar(i2caddr & 0xfe);
88     i2c_writechar(page_hi);
89     i2c_writechar(page_lo);
90     i2c_writechar(data);
91     I2C_STOP();
92     i2c_close();
93 #else
94     OpenI2C(MASTER, SLEW_ON);
95     SSPADD = 5; // 100KHz
96     IdleI2C();
97 //    StartI2C();
98 //    do {
99 //        idle_time_ms(1);
100         StartI2C();
101         while(SSPCON2bits.SEN);
102         WriteI2C(i2caddr & 0xfe);
103         while(SSPCON2bits.ACKSTAT);
104 //    WriteI2C(i2caddr & 0xfe);
105     WriteI2C(page_hi);
106     while(SSPCON2bits.ACKSTAT);
107     WriteI2C(page_lo);
108     while(SSPCON2bits.ACKSTAT);
109     WriteI2C(data);
110     while(SSPCON2bits.ACKSTAT);
111     StopI2C();
112     while(SSPCON2bits.PEN);
113    // idle_time_ms(1);
114     CloseI2C();
115 #endif  //    i2c_idle();
116     return 0xff;
117 }
118
119
120 unsigned char i2c_eeprom_burstwrite(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
121 {
122     unsigned char page_hi;
123     unsigned char page_lo;
124     int b = bytes;
125
126     while(b > 0){
127 //        page_hi = addr >> 8;
128 //        page_lo = addr & 0xff;
129 //        i2c_eeprom_write_1block(i2caddr,  page_hi, page_lo, data);
130         i2c_eeprom_bytewrite(i2caddr,  addr, *data);
131         idle_time_ms(15);
132
133         addr += 1;
134         data += 1;
135         b -= 1;
136     }
137 }
138
139
140 static unsigned char i2c_eeprom_read_1block(unsigned char addr, unsigned char page_hi, unsigned char page_lo, unsigned char *data)
141 {
142     unsigned char c;
143     unsigned char i;
144     unsigned char *p = data;
145
146   #ifdef __SDCC
147     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
148     I2C_START();
149     i2c_writechar(addr & 0xfe);
150     i2c_writechar(page_hi);
151     i2c_writechar(page_lo);
152
153 //   delay100tcy(2);
154     I2C_START();
155     i2c_writechar(addr | 0x01);
156     for(i = 0; i < 64; i++){
157         *p = i2c_readchar();
158         p++;
159         I2C_ACK();
160     }
161     I2C_STOP();
162     i2c_close();
163 #else
164     OpenI2C(MASTER, SLEW_ON);
165     SSPADD = 0x5;
166     StartI2C();
167     WriteI2C(addr & 0xfe);
168   //  delay1ktcy(8);
169     WriteI2C(page_hi);
170     WriteI2C(page_lo);
171     IdleI2C();
172     RestartI2C();
173     WriteI2C(addr | 0x01);
174 //    IdleI2C();
175     for(i = 0; i < 32; i++){
176         if(!SSPCON2bits.ACKSTAT){
177               SSPCON2bits.RCEN = 1;
178               while(SSPCON2bits.RCEN);
179                NotAckI2C();
180                while (SSPCON2bits.ACKEN);
181                StopI2C();
182                while (SSPCON2bits.PEN);
183           }
184         *p = SSPBUF;
185         p++;
186         if(i < 31) AckI2C();
187     }
188     NotAckI2C();
189 //    IdleI2C();
190     StopI2C();
191     CloseI2C();
192 #endif
193     //    CLOSEASMASTER();
194     return 0xff;
195 }
196
197
198 // I2C_IO
199 unsigned char i2c_eeprom_byteread(unsigned char i2caddr, unsigned int addr)
200 {
201     unsigned char page_hi = addr >> 8;
202     unsigned char page_lo = addr & 0xff; // 64byte?
203     unsigned char c;
204
205   #ifdef __SDCC
206     i2c_open(I2C_MASTER, I2C_SLEW_ON, 5);
207     I2C_START();
208     i2c_writechar(i2caddr);
209     i2c_writechar(page_hi);
210     i2c_writechar(page_lo);
211     I2C_STOP();
212     i2c_idle();
213 //   delay100tcy(2);
214     I2C_START();
215     i2c_writechar(i2caddr | 1);
216     c = i2c_readchar();
217     I2C_ACK();
218     I2C_STOP();
219     i2c_close();
220 #else
221     OpenI2C(MASTER, SLEW_ON);
222     SSPADD = 0x5;
223     StartI2C();
224     while(SSPCON2bits.SEN);
225     WriteI2C(i2caddr);
226   //  delay1ktcy(8);
227     while(SSPCON2bits.SEN);
228     WriteI2C(page_hi);
229     while(SSPCON2bits.SEN);
230     WriteI2C(page_lo);
231   //  delay1ktcy(8);
232     StopI2C();
233     IdleI2C();
234     StartI2C();
235     WriteI2C(i2caddr | 1);
236     if (!SSPCON2bits.ACKSTAT){
237       SSPCON2bits.RCEN = 1;
238       while(SSPCON2bits.RCEN);
239       NotAckI2C();
240       while (SSPCON2bits.ACKEN);
241       StopI2C();
242       while (SSPCON2bits.PEN);
243     }
244     c = SSPBUF;
245   //  delay1ktcy(8);
246  //   delay1ktcy(8);
247     CloseI2C();
248 #endif
249     //    CLOSEASMASTER();
250     return c;
251 }
252
253
254 unsigned char i2c_eeprom_burstread(unsigned char i2caddr, unsigned int addr, unsigned char *data, unsigned int bytes)
255 {
256     unsigned char page_hi;
257     unsigned char page_lo;
258     int b = bytes;
259
260     while(b > 0){
261  //       page_hi = addr >> 8;
262  //       page_lo = addr & 0xff;
263         *data = i2c_eeprom_byteread(i2caddr,  addr);
264 //        i2c_eeprom_read_1block(i2caddr, page_hi, page_lo, data);
265         idle_time_ms(1);
266
267         addr += 1;
268         data += 1;
269         b -= 1;
270     }
271
272     return 0xff;
273 }