sliding_puzzle improvements: * Use the UI font for numerals and 'moves' display when...
[Rockbox.git] / firmware / target / coldfire / iriver / h100 / sw_i2c-h100.c
blob3b2cdc4042633cb4ce7eca39b4ed18a9465b0730
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 by Miika Pekkarinen
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "system.h"
20 #include "logf.h"
21 #include "inttypes.h"
23 #include "sw_i2c.h"
25 /**
26 * I2C-functions are copied and ported from fmradio.c.
27 * later fixed, adapted and moved to a seperate file so they can be re-used by the rtc-ds1339c code by Robert Kukla
30 /* cute little functions, atomic read-modify-write */
32 /* SCL is GPIO, 12 */
33 #define SCL ( 0x00001000 & GPIO_READ)
34 #define SCL_OUT_LO and_l(~0x00001000, &GPIO_OUT)
35 #define SCL_LO or_l( 0x00001000, &GPIO_ENABLE)
36 #define SCL_HI and_l(~0x00001000, &GPIO_ENABLE)
38 /* SDA is GPIO1, 13 */
39 #define SDA ( 0x00002000 & GPIO1_READ)
40 #define SDA_OUT_LO and_l(~0x00002000, &GPIO1_OUT)
41 #define SDA_LO or_l( 0x00002000, &GPIO1_ENABLE)
42 #define SDA_HI and_l(~0x00002000, &GPIO1_ENABLE)
44 /* delay loop to achieve 400kHz at 120MHz CPU frequency */
45 #define DELAY \
46 ({ \
47 int _x_; \
48 asm volatile ( \
49 "move.l #21, %[_x_] \r\n" \
50 "1: \r\n" \
51 "subq.l #1, %[_x_] \r\n" \
52 "bhi.b 1b \r\n" \
53 : [_x_]"=&d"(_x_) \
54 ); \
57 void sw_i2c_init(void)
59 or_l(0x00001000, &GPIO_FUNCTION);
60 or_l(0x00002000, &GPIO1_FUNCTION);
61 SDA_HI;
62 SCL_HI;
63 SDA_OUT_LO;
64 SCL_OUT_LO;
67 /* in: C=? D=?
68 * out: C=L D=L
70 static void sw_i2c_start(void)
72 SCL_LO;
73 DELAY;
74 SDA_HI;
75 DELAY;
76 SCL_HI;
77 DELAY;
78 SDA_LO;
79 DELAY;
80 SCL_LO;
83 /* in: C=L D=?
84 * out: C=H D=H
86 static void sw_i2c_stop(void)
88 SDA_LO;
89 DELAY;
90 SCL_HI;
91 DELAY;
92 SDA_HI;
95 /* in: C=L D=H
96 * out: C=L D=L
98 static void sw_i2c_ack(void)
100 SDA_LO;
101 DELAY;
103 SCL_HI;
104 DELAY;
105 SCL_LO;
108 /* in: C=L D=H
109 * out: C=L D=H
111 static void sw_i2c_nack(void)
113 SDA_HI; /* redundant */
114 DELAY;
116 SCL_HI;
117 DELAY;
118 SCL_LO;
121 /* in: C=L D=?
122 * out: C=L D=H
124 static bool sw_i2c_getack(void)
126 bool ret = true;
127 /* int count = 10; */
129 SDA_HI; /* sets to input */
130 DELAY;
131 SCL_HI;
132 DELAY;
134 /* while (SDA && count--) */
135 /* DELAY; */
137 if (SDA)
138 /* ack failed */
139 ret = false;
141 SCL_LO;
143 return ret;
146 /* in: C=L D=?
147 * out: C=L D=?
149 static void sw_i2c_outb(unsigned char byte)
151 int i;
153 /* clock out each bit, MSB first */
154 for ( i=0x80; i; i>>=1 )
156 if ( i & byte )
157 SDA_HI;
158 else
159 SDA_LO;
160 DELAY;
162 SCL_HI;
163 DELAY;
164 SCL_LO;
168 /* in: C=L D=?
169 * out: C=L D=H
171 static unsigned char sw_i2c_inb(void)
173 int i;
174 unsigned char byte = 0;
176 SDA_HI; /* sets to input */
178 /* clock in each bit, MSB first */
179 for ( i=0x80; i; i>>=1 )
181 DELAY;
182 do {
183 SCL_HI;
184 DELAY;
186 while(SCL==0); /* wait for any SCL clock stretching */
187 if ( SDA )
188 byte |= i;
189 SCL_LO;
192 return byte;
195 int sw_i2c_write(unsigned char chip, unsigned char location, const unsigned char* buf, int count)
197 int i;
199 sw_i2c_start();
200 sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE);
201 if (!sw_i2c_getack())
203 sw_i2c_stop();
204 return -1;
207 sw_i2c_outb(location);
208 if (!sw_i2c_getack())
210 sw_i2c_stop();
211 return -2;
214 for (i=0; i<count; i++)
216 sw_i2c_outb(buf[i]);
217 if (!sw_i2c_getack())
219 sw_i2c_stop();
220 return -3;
224 sw_i2c_stop();
226 return 0;
229 int sw_i2c_read(unsigned char chip, unsigned char location, unsigned char* buf, int count)
231 int i;
233 sw_i2c_start();
234 sw_i2c_outb((chip & 0xfe) | SW_I2C_WRITE);
235 if (!sw_i2c_getack())
237 sw_i2c_stop();
238 return -1;
241 sw_i2c_outb(location);
242 if (!sw_i2c_getack())
244 sw_i2c_stop();
245 return -2;
248 sw_i2c_start();
249 sw_i2c_outb((chip & 0xfe) | SW_I2C_READ);
250 if (!sw_i2c_getack())
252 sw_i2c_stop();
253 return -3;
256 for (i=0; i<count-1; i++)
258 buf[i] = sw_i2c_inb();
259 sw_i2c_ack();
262 /* 1byte min */
263 buf[i] = sw_i2c_inb();
264 sw_i2c_nack();
266 sw_i2c_stop();
268 return 0;