source: umon/ports/beagleboneblack/cpu_i2c.h @ dee5246

Last change on this file since dee5246 was dee5246, checked in by Jarielle Catbagan <jcatbagan93@…>, on 06/19/15 at 18:53:54

Duplicated csb740 directory to beagleboneblack directory for BBB port

  • Property mode set to 100644
File size: 5.8 KB
Line 
1//==========================================================================
2//
3//      cpu_i2c.c
4//
5// Author(s):   Michael Kelly - Cogent Computer Systems, Inc.
6// Date:        03/30/2002
7// Description: CSB272 - 405GP Single Board IIC Routines
8//
9//==========================================================================
10
11#include "config.h"
12#include "cpuio.h"
13#include "genlib.h"
14#include "stddefs.h"
15
16//--------------------------------------------------------------------------
17// some 405GP I2C register and bit defines
18//
19#define I2C_XCTL                                *(vulong *)(0xef60050f) // extended control register
20#define I2C_XCTL_SRST                   0x01000000      // Soft Reset Bit - must be set
21                                                                                        // to 1 to use direct control
22
23#define I2C_DCTL                                *(vulong *)(0xef600510) // direct control of IIC bits
24#define I2C_DCTL_SDA_OUT                0x08000000      // SDA Out, 0 = drive low, 1 = tri-state
25#define I2C_DCTL_SCL_OUT                0x04000000      // SCL Out, 0 = drive low, 1 = tri-state
26#define I2C_DCTL_SDA_IN                 0x02000000      // SDA In, Direct Read
27#define I2C_DCTL_SCL_IN                 0x01000000      // SCL In, Direct Read
28
29//--------------------------------------------------------------------------
30// Low level I2C Macros
31//
32#define I2C_SCL_CLR                             I2C_DCTL &= ~(I2C_DCTL_SCL_OUT)
33#define I2C_SCL_SET                             I2C_DCTL |= (I2C_DCTL_SCL_OUT) 
34
35#define I2C_SDA_CLR                             I2C_DCTL &= ~(I2C_DCTL_SDA_OUT)         
36#define I2C_SDA_SET                             I2C_DCTL |= (I2C_DCTL_SDA_OUT)         
37
38#define I2C_SDA_RD                              I2C_DCTL & I2C_DCTL_SDA_IN
39#define I2C_SCL_RD                              I2C_DCTL & I2C_DCTL_SCL_IN
40
41#define I2C_DELAY                               udelay(100)
42
43//--------------------------------------------------------------------------
44// function prototypes
45//
46ulong i2c_init(void);
47ulong i2c_wr_device(uchar dev, uchar reg, uchar data);
48ulong i2c_rd_device(uchar dev, uchar reg, uchar *data);
49ulong i2c_wr_byte(uchar data);
50uchar i2c_rd_byte(void);
51void i2c_start(void);
52void i2c_stop(void);
53
54extern void udelay(int delay);
55
56extern ulong sed_disp_mode;
57
58//--------------------------------------------------------------------------
59// i2c_init()
60//
61// Initialize the I2C registers for direct I2C control
62ulong i2c_init()
63{
64        // place the automatic I2C logic in reset
65        I2C_XCTL |= I2C_XCTL_SRST;
66
67        // Set the SCL and SDA outputs into tristate
68        I2C_DCTL |= (I2C_DCTL_SDA_OUT | I2C_DCTL_SCL_OUT);
69
70        return 0;
71
72}
73
74//--------------------------------------------------------------------------
75// i2c_wr_device()
76//
77// This function writes an 8-bit value to the I2C device at the requested
78// register.
79//
80ulong i2c_wr_device(uchar dev, uchar reg, uchar data)
81{
82
83        // issue a start command
84        i2c_start();
85
86        // write the 7-bit device address with write = 0
87        if(i2c_wr_byte((dev << 1) & 0xfe)){
88                return -1;
89        }
90        // Write the 8-bit register address
91        if(i2c_wr_byte(reg)){
92                return -1;
93        }
94        // Write the 8-bit data value
95        if(i2c_wr_byte(data)){
96                return -1;
97        }
98
99        // issue a stop
100        i2c_stop();
101       
102        return 0;
103}
104
105//--------------------------------------------------------------------------
106// i2c_rd_device()
107//
108// This function reads an 8-bit value from the I2C device at the requested
109// register.
110//
111ulong i2c_rd_device(uchar dev, uchar reg, uchar *data)
112{
113
114        // issue a start command
115        i2c_start();
116
117        // write the 7-bit device address with write = 0
118        if(i2c_wr_byte((dev << 1) & 0xfe)){
119                return -1;
120        }
121        // Write the 8-bit register address
122        if(i2c_wr_byte(reg)){
123                return -1;
124        }
125        // repeat the start command
126        i2c_start();
127        // write the 7-bit device address again plus data direction (read = 1)
128        if(i2c_wr_byte((dev << 1) | 0x01)){
129                return -1;
130        }
131        *data = i2c_rd_byte();
132
133        // issue a stop
134        i2c_stop();
135
136        return 0;
137}
138
139//--------------------------------------------------------------------------
140// i2c_wr_byte()
141//
142// This function writes an 8-bit value to the I2C bus, MSB first.
143// Data is written by changing SDA during SCL low, then bringing
144// SCL high.  SCL is returned low to setup for the next transition.
145//
146ulong i2c_wr_byte(uchar data)
147{
148
149        int i;
150
151        for (i = 0; i < 8; i++){
152                if (data & 0x80) {
153                        // write a 1 bit
154                        I2C_SDA_SET;
155                        I2C_DELAY;
156                        I2C_SCL_SET;
157                        I2C_DELAY;
158                        I2C_SCL_CLR;
159                        I2C_DELAY;
160                }
161                else {
162                        // write a 0 bit
163                        I2C_SDA_CLR;
164                        I2C_DELAY;
165                        I2C_SCL_SET;
166                        I2C_DELAY;
167                        I2C_SCL_CLR;
168                        I2C_DELAY;
169                }
170                data = data << 1;
171        }
172        // Release SDA, bring SCL high, then read SDA.
173        // A low indicates an acknowledge.
174        I2C_SDA_SET;
175        I2C_DELAY;
176        I2C_SCL_SET;
177        I2C_DELAY;
178        if(I2C_SDA_RD){ // a high means no ack
179                // re-enable SDA for output
180                I2C_SCL_CLR;
181                I2C_DELAY;
182                return -1;
183        }
184
185        I2C_SCL_CLR;
186        I2C_DELAY;
187
188        return 0;
189}
190
191//--------------------------------------------------------------------------
192// i2c_rd_byte()
193//
194// This function reads an 8-bit data value from the I2C bus, MSB first.
195// Data is read from SDA after each low to high SCL transition.
196//
197uchar i2c_rd_byte()
198{
199
200        int i;
201        uchar volatile data;
202
203        data = 0;
204
205        for (i = 0; i < 8; i++){
206                data = data << 1;
207                data = data & 0xfe;
208                // clock the data out of the slave
209                I2C_SCL_SET;
210                I2C_DELAY;
211                // check it
212                if (I2C_SDA_RD){
213                        data = data | 0x01;
214                }
215                I2C_SCL_CLR;
216                I2C_DELAY;
217        }
218        // generate an extra SCL transition
219        // The slave generates no acknowledge for reads.
220        I2C_SCL_SET;
221        I2C_DELAY;
222        I2C_SCL_CLR;
223        I2C_DELAY;
224
225        return data;
226}
227
228
229//--------------------------------------------------------------------------
230// i2c_start()
231//
232// This function issues an I2C start command which is a high to low
233// transition on SDA while SCL is high.
234//
235void i2c_start()
236{
237
238        I2C_SDA_SET;
239        I2C_DELAY;
240        I2C_SCL_SET;
241        I2C_DELAY;
242        I2C_SDA_CLR;
243        I2C_DELAY;
244        I2C_SCL_CLR;
245        I2C_DELAY;
246        I2C_SDA_SET;
247        I2C_DELAY;
248}
249
250//--------------------------------------------------------------------------
251// i2c_stop()
252//
253// This function issues an I2C stop command which is a low to high
254// transition on SDA while SCL is high.
255//
256void i2c_stop()
257{
258
259        I2C_SDA_CLR;
260        I2C_DELAY;
261        I2C_SCL_SET;
262        I2C_DELAY;
263        I2C_SDA_SET;
264        I2C_DELAY;
265        I2C_SCL_CLR;
266        I2C_DELAY;
267}
268
269
Note: See TracBrowser for help on using the repository browser.