OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [drivers/] [i2c_master_slave/] [i2c_master_slave.c] - Blame information for rev 545

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 393 julius
/*************************************************************
2
* I2C functions for the Herveille i2c controller            *
3
*                                                           *
4
* Provides functions to read from and write to the I2C bus. *
5
* Master and slave mode are both supported                  *
6
*                                                           *
7 403 julius
* Julius Baxter, julius@opencores.org                       *
8 393 julius
*                                                           *
9
************************************************************/
10
 
11
#include "board.h"
12
#include "cpu-utils.h"
13
#include "i2c_master_slave.h"
14
 
15 486 julius
 
16
// Ensure board.h defines I2C_MASTER_SLAVE_NUM_CORES and 
17
// I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV which should be the base address values
18
// separated with commas
19
#ifdef I2C_MASTER_SLAVE_NUM_CORES
20
 
21
const int I2C_MASTER_SLAVE_BASE_ADR[I2C_MASTER_SLAVE_NUM_CORES] = {
22
        I2C_MASTER_SLAVE_BASE_ADDRESSES_CSV };
23
#else
24
 
25
const int I2C_MASTER_SLAVE_BASE_ADR[1] = {-1};
26
 
27
#endif
28
 
29 403 julius
inline unsigned char i2c_master_slave_read_reg(int core, unsigned char addr)
30 393 julius
{
31 486 julius
        return REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr));
32 393 julius
}
33 403 julius
 
34
inline void i2c_master_slave_write_reg(int core, unsigned char addr,
35
                                       unsigned char data)
36 393 julius
{
37 486 julius
        REG8((I2C_MASTER_SLAVE_BASE_ADR[core] + addr)) = data;
38 393 julius
}
39
 
40
int i2c_master_slave_wait_for_busy(int core)
41
{
42 403 julius
        while (1) {
43
                // Check for busy flag in i2c status reg
44
                if (!
45
                    (i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR) &
46
                     I2C_MASTER_SLAVE_SR_BUSY))
47
                        return 0;
48
        }
49 393 julius
}
50
 
51
int i2c_master_slave_wait_for_transfer(int core)
52
{
53 403 julius
        volatile unsigned char status;
54
        // Wait for ongoing transmission to finish
55
        while (1) {
56
                status = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_SR);
57
                // If arbitration lost
58
                if ((status & I2C_MASTER_SLAVE_SR_ARB_LOST) ==
59
                    I2C_MASTER_SLAVE_SR_ARB_LOST)
60
                        return 2;
61
                // If TIP bit = o , stop waiting
62
                else if (!(status & I2C_MASTER_SLAVE_SR_TRANSFER_IN_PRG))
63
                        return 0;
64
        }
65 393 julius
}
66
 
67
/***********************************************************
68 403 julius
* i2c_master_slave_init_core                               *
69 393 julius
*                                                          *
70
* Setup i2c core:                                          *
71
* Write prescaler register with parmeter passed, enable    *
72
* core in control register, optionally enable interrupts   *
73
************************************************************/
74 403 julius
int i2c_master_slave_init_core(int core, unsigned short prescaler,
75
                               int interrupt_enable)
76 393 julius
{
77
 
78 403 julius
        // Setup I2C prescaler,
79
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERlo,
80
                                   prescaler & 0xff);
81
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_PRERhi,
82
                                   (prescaler >> 8) & 0xff);
83 393 julius
 
84 403 julius
        // Enable I2C controller and optionally interrupts
85
        if (interrupt_enable)
86
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
87
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
88
                                           I2C_MASTER_SLAVE_CTR_INTR_ENABLE);
89
        else
90
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
91
                                           I2C_MASTER_SLAVE_CTR_CORE_ENABLE);
92 393 julius
 
93 403 julius
        return 0;
94 393 julius
 
95
}
96
 
97
/***********************************************************
98 403 julius
* i2c_master_slave_deact_core                              *
99 393 julius
*                                                          *
100 403 julius
* Deactivate i2c core:                                     *
101
* Clear core enable and interrupt enable bits              *
102
************************************************************/
103
int i2c_master_slave_deact_core(int core)
104
{
105
 
106
 
107
  i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
108
                             i2c_master_slave_read_reg(core,
109
                                                       I2C_MASTER_SLAVE_CTR) &
110
                             ~(I2C_MASTER_SLAVE_CTR_CORE_ENABLE |
111
                               I2C_MASTER_SLAVE_CTR_INTR_ENABLE));
112
 
113
 
114
        return 0;
115
 
116
}
117
 
118
/***********************************************************
119
* i2c_master_slave_init_as_slave                           *
120
*                                                          *
121
* Setup i2c core to service slave accesses                 *
122 393 julius
* OR in slave enable bit to control register               *
123
* Set slave address                                        *
124
************************************************************/
125 403 julius
int i2c_master_slave_init_as_slave(int core, char addr)
126 393 julius
{
127
 
128 403 julius
        // Set slave enable bit
129
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
130
                                   i2c_master_slave_read_reg(core,
131
                                                             I2C_MASTER_SLAVE_CTR)
132
                                   | I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
133
        // Set slave address
134
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_SLADR, addr);
135
 
136
        return 0;
137
 
138 393 julius
}
139
 
140
/***********************************************************
141 403 julius
* i2c_master_slave_deact_as_slave                          *
142 393 julius
*                                                          *
143
* Disable slave mode for this I2C core                     *
144
* Deassert slave eanble bit in control register            *
145
************************************************************/
146 403 julius
int i2c_master_slave_deact_as_slave(int core)
147 393 julius
{
148 403 julius
        // Clear slave enable bit
149
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CTR,
150
                                   i2c_master_slave_read_reg(core,
151
                                                             I2C_MASTER_SLAVE_CTR)
152
                                   & ~I2C_MASTER_SLAVE_CTR_SLAVE_ENABLE);
153
 
154
        return 0;
155 393 julius
}
156
 
157
/***********************************************************
158 403 julius
* i2c_master_slave_master_start                            *
159 393 julius
*                                                          *
160
* Get the i2c bus.                                         *
161
************************************************************/
162 403 julius
int i2c_master_slave_master_start(int core, unsigned char addr, int read)
163
{
164 393 julius
 
165 403 julius
        i2c_master_slave_wait_for_busy(core);
166 393 julius
 
167 403 julius
        // Set address in transfer register
168
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR,
169
                                   (addr << 1) | read);
170
 
171
        // Start and write the address
172
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
173
                                   I2C_MASTER_SLAVE_CR_START |
174
                                   I2C_MASTER_SLAVE_CR_WRITE);
175
 
176
        i2c_master_slave_wait_for_transfer(core);
177
 
178
        return 0;
179 393 julius
}
180
 
181
/***********************************************************
182 403 julius
* i2c_master_slave_master_write                            *
183 393 julius
*                                                          *
184
* Send 1 byte of data                                      *
185
************************************************************/
186 403 julius
int i2c_master_slave_master_write(int core, unsigned char data,
187
                                  int check_prev_ack, int stop)
188 486 julius
{
189 403 julius
        if (i2c_master_slave_wait_for_transfer(core))
190
                return 1;
191 486 julius
 
192 403 julius
        // present data
193
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_TXR, data);
194 393 julius
 
195 403 julius
        if (!stop)
196
                // set command (write)
197
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
198
                                           I2C_MASTER_SLAVE_CR_WRITE);
199
        else
200
                // set command (write) and stop
201
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
202
                                           I2C_MASTER_SLAVE_CR_WRITE |
203
                                           I2C_MASTER_SLAVE_CR_STOP);
204
 
205 486 julius
        return i2c_master_slave_wait_for_transfer(core);
206
 
207 393 julius
}
208
 
209
/***********************************************************
210 403 julius
* i2c_master_slave_master_stop                             *
211 393 julius
*                                                          *
212
* Send stop condition                                      *
213
************************************************************/
214 403 julius
int i2c_master_slave_master_stop(int core)
215
{
216
        unsigned char status;
217
        unsigned char ready = 0;
218 393 julius
 
219 403 julius
        // Make I2C controller wait at end of finished byte
220
        if (i2c_master_slave_wait_for_transfer(core))
221
                return 1;
222 393 julius
 
223 403 julius
        // Send stop condition
224
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
225
                                   I2C_MASTER_SLAVE_CR_STOP);
226
 
227
        return 0;
228 393 julius
}
229
 
230
/***********************************************************
231 403 julius
* i2c_master_slave_master_read                             *
232 393 julius
*                                                          *
233
* Read 1 byte of data                                      *
234
************************************************************/
235 403 julius
int i2c_master_slave_master_read(int core, int check_prev_ack,
236
                                 int stop, char *data)
237
{
238 393 julius
 
239 403 julius
        // Make I2C controller wait at end of finished byte
240
        if (i2c_master_slave_wait_for_transfer(core))
241
                return 1;
242 393 julius
 
243 403 julius
        if (stop)
244
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
245
                                           I2C_MASTER_SLAVE_CR_READ |
246 545 julius
                                           // Final read, so send a NAK to slave
247
                                           I2C_MASTER_SLAVE_CR_ACK |
248 403 julius
                                           I2C_MASTER_SLAVE_CR_STOP);
249
        else
250
                i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
251
                                           I2C_MASTER_SLAVE_CR_READ);
252 393 julius
 
253 403 julius
        if (i2c_master_slave_wait_for_transfer(core))
254
                return 1;
255
 
256
        *data = i2c_master_slave_read_reg(core, I2C_MASTER_SLAVE_RXR);
257
 
258 486 julius
        return i2c_master_slave_wait_for_transfer(core);
259 393 julius
}
260
 
261
/***********************************************************
262 403 julius
* i2c_master_slave_ack_interrupt                           *
263 393 julius
*                                                          *
264
* Acknowledge interrupt has been serviced                  *
265
************************************************************/
266 403 julius
int i2c_master_slave_ack_interrupt(int core)
267 393 julius
{
268 403 julius
 
269
        i2c_master_slave_write_reg(core, I2C_MASTER_SLAVE_CR,
270
                                   I2C_MASTER_SLAVE_CR_IACK);
271
 
272
        return 0;
273 393 julius
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.