LPCOpen Platform
v1.03
LPCOpen Platform for NXP LPC Microcontrollers
Main Page
Modules
Data Structures
Files
Related Pages
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
i2c_11xx.c
Go to the documentation of this file.
1
/*
2
* @brief LPC11xx I2C driver
3
*
4
* @note
5
* Copyright(C) NXP Semiconductors, 2012
6
* All rights reserved.
7
*
8
* @par
9
* Software that is described herein is for illustrative purposes only
10
* which provides customers with programming information regarding the
11
* LPC products. This software is supplied "AS IS" without any warranties of
12
* any kind, and NXP Semiconductors and its licensor disclaim any and
13
* all warranties, express or implied, including all implied warranties of
14
* merchantability, fitness for a particular purpose and non-infringement of
15
* intellectual property rights. NXP Semiconductors assumes no responsibility
16
* or liability for the use of the software, conveys no license or rights under any
17
* patent, copyright, mask work right, or any other intellectual property rights in
18
* or to any products. NXP Semiconductors reserves the right to make changes
19
* in the software without notification. NXP Semiconductors also makes no
20
* representation or warranty that such application will be suitable for the
21
* specified use without further testing or modification.
22
*
23
* @par
24
* Permission to use, copy, modify, and distribute this software and its
25
* documentation is hereby granted, under NXP Semiconductors' and its
26
* licensor's relevant copyrights in the software, without fee, provided that it
27
* is used in conjunction with NXP Semiconductors microcontrollers. This
28
* copyright, permission, and disclaimer notice must appear in all copies of
29
* this code.
30
*/
31
32
#if !defined(CHIP_LPC110X)
/* Chip 110x does not have I2C IP in it */
33
34
#include "
chip.h
"
35
36
/*****************************************************************************
37
* Private types/enumerations/variables
38
****************************************************************************/
39
#define SLAVE_ACTIVE(iic) (((iic)->flags & 0xFF00) != 0)
40
41
/* I2C common interface structure */
42
struct
i2c_interface
{
43
LPC_I2C_T
*
ip
;
/* IP base address of the I2C device */
44
CHIP_SYSCTL_CLOCK_T
clk
;
/* Clock used by I2C */
45
I2C_EVENTHANDLER_T
mEvent
;
/* Current active Master event handler */
46
I2C_EVENTHANDLER_T
sEvent
;
/* Slave transfer events */
47
I2C_XFER_T
*
mXfer
;
/* Current active xfer pointer */
48
I2C_XFER_T
*
sXfer
;
/* Pointer to store xfer when bus is busy */
49
uint32_t
flags
;
/* Flags used by I2C master and slave */
50
};
51
52
/* Slave interface structure */
53
struct
i2c_slave_interface
{
54
I2C_XFER_T
*
xfer
;
55
I2C_EVENTHANDLER_T
event
;
56
};
57
58
/* I2C interfaces */
59
static
struct
i2c_interface
i2c
[
I2C_NUM_INTERFACE
] = {
60
{
LPC_I2C
,
SYSCTL_CLOCK_I2C
,
Chip_I2C_EventHandler
,
NULL
,
NULL
,
NULL
, 0}
61
};
62
63
static
struct
i2c_slave_interface
i2c_slave
[
I2C_NUM_INTERFACE
][
I2C_SLAVE_NUM_INTERFACE
];
64
65
/*****************************************************************************
66
* Public types/enumerations/variables
67
****************************************************************************/
68
69
/*****************************************************************************
70
* Private functions
71
****************************************************************************/
72
73
/*****************************************************************************
74
* Public functions
75
****************************************************************************/
76
/* Chip event handler interrupt based */
77
void
Chip_I2C_EventHandler
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
78
{
79
struct
i2c_interface
*iic = &i2c[id];
80
volatile
I2C_STATUS_T
*stat;
81
82
/* Only WAIT event needs to be handled */
83
if
(event !=
I2C_EVENT_WAIT
) {
84
return
;
85
}
86
87
stat = &iic->
mXfer
->
status
;
88
/* Wait for the status to change */
89
while
(*stat ==
I2C_STATUS_BUSY
) {}
90
}
91
92
/* Chip polling event handler */
93
void
Chip_I2C_EventHandlerPolling
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
94
{
95
struct
i2c_interface
*iic = &i2c[id];
96
volatile
I2C_STATUS_T
*stat;
97
98
/* Only WAIT event needs to be handled */
99
if
(event !=
I2C_EVENT_WAIT
) {
100
return
;
101
}
102
103
stat = &iic->
mXfer
->
status
;
104
/* Call the state change handler till xfer is done */
105
while
(*stat ==
I2C_STATUS_BUSY
) {
106
if
(
IP_I2C_IsStateChanged
(iic->
ip
)) {
107
Chip_I2C_MasterStateHandler
(
id
);
108
}
109
}
110
}
111
112
/* Initializes the LPC_I2C peripheral with specified parameter */
113
void
Chip_I2C_Init
(
I2C_ID_T
id
)
114
{
115
/* Enable I2C Clocking */
116
Chip_Clock_EnablePeriphClock
(i2c[
id
].
clk
);
117
118
IP_I2C_Init
(i2c[
id
].
ip
);
119
}
120
121
/* De-initializes the I2C peripheral registers to their default reset values */
122
void
Chip_I2C_DeInit
(
I2C_ID_T
id
)
123
{
124
IP_I2C_DeInit
(i2c[
id
].
ip
);
125
126
/* Disable I2C clocking */
127
Chip_Clock_DisablePeriphClock
(i2c[
id
].
clk
);
128
}
129
130
/* Set up clock rate for LPC_I2C peripheral */
131
void
Chip_I2C_SetClockRate
(
I2C_ID_T
id
,
uint32_t
clockrate)
132
{
133
IP_I2C_SetClockRate
(i2c[
id
].
ip
, (
Chip_Clock_GetMainClockRate
() / clockrate));
134
}
135
136
/* Get current clock rate for LPC_I2C peripheral */
137
uint32_t
Chip_I2C_GetClockRate
(
I2C_ID_T
id
)
138
{
139
return
Chip_Clock_GetMainClockRate
() /
IP_I2C_GetClockDiv
(i2c[
id
].
ip
);
140
}
141
142
/* Set the master event handler */
143
int
Chip_I2C_SetMasterEventHandler
(
I2C_ID_T
id
,
I2C_EVENTHANDLER_T
event
)
144
{
145
struct
i2c_interface
*iic = &i2c[id];
146
if
(!iic->
mXfer
) {
147
iic->
mEvent
=
event
;
148
}
149
return
iic->
mEvent
==
event
;
150
}
151
152
/* Get the master event handler */
153
I2C_EVENTHANDLER_T
Chip_I2C_GetMasterEventHandler
(
I2C_ID_T
id
)
154
{
155
return
i2c[id].
mEvent
;
156
}
157
158
/* Transmit and Receive data in master mode */
159
int
Chip_I2C_MasterTransfer
(
I2C_ID_T
id
,
I2C_XFER_T
*xfer)
160
{
161
struct
i2c_interface
*iic = &i2c[id];
162
163
iic->
mEvent
(
id
,
I2C_EVENT_LOCK
);
164
xfer->
status
=
I2C_STATUS_BUSY
;
165
iic->
mXfer
= xfer;
166
167
/* If slave xfer not in progress */
168
if
(!iic->
sXfer
) {
169
IP_I2C_Master_StartXfer
(iic->
ip
);
170
}
171
iic->
mEvent
(
id
,
I2C_EVENT_WAIT
);
172
iic->
mXfer
= 0;
173
174
/* Wait for stop condition to appear on bus */
175
while
(!
IP_I2C_BusFree
(iic->
ip
)) {}
176
177
/* Start slave if one is active */
178
if
(
SLAVE_ACTIVE
(iic)) {
179
IP_I2C_Slave_StartXfer
(iic->
ip
);
180
}
181
182
iic->
mEvent
(
id
,
I2C_EVENT_UNLOCK
);
183
return
(
int
) xfer->
status
;
184
}
185
186
/* Master tx only */
187
int
Chip_I2C_MasterSend
(
I2C_ID_T
id
, uint8_t slaveAddr,
const
uint8_t *buff, uint8_t len)
188
{
189
I2C_XFER_T
xfer = {0};
190
xfer.
slaveAddr
= slaveAddr;
191
xfer.
txBuff
= buff;
192
xfer.
txSz
= len;
193
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
194
return
len - xfer.
txSz
;
195
}
196
197
/* Transmit one byte and receive an array of bytes after a repeated start condition is generated in Master mode.
198
* This function is useful for communicating with the I2C slave registers
199
*/
200
int
Chip_I2C_MasterCmdRead
(
I2C_ID_T
id
, uint8_t slaveAddr, uint8_t cmd, uint8_t *buff,
int
len)
201
{
202
I2C_XFER_T
xfer = {0};
203
xfer.
slaveAddr
= slaveAddr;
204
xfer.
txBuff
= &cmd;
205
xfer.
txSz
= 1;
206
xfer.
rxBuff
= buff;
207
xfer.
rxSz
= len;
208
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
209
return
len - xfer.
rxSz
;
210
}
211
212
/* Sequential master read */
213
int
Chip_I2C_MasterRead
(
I2C_ID_T
id
, uint8_t slaveAddr, uint8_t *buff,
int
len)
214
{
215
I2C_XFER_T
xfer = {0};
216
xfer.
slaveAddr
= slaveAddr;
217
xfer.
rxBuff
= buff;
218
xfer.
rxSz
= len;
219
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
220
return
len - xfer.
rxSz
;
221
}
222
223
/* Check if master state is active */
224
int
Chip_I2C_IsMasterActive
(
I2C_ID_T
id
)
225
{
226
return
IP_I2C_IsMasterState
(i2c[
id
].
ip
);
227
}
228
229
/* State change handler for master transfer */
230
void
Chip_I2C_MasterStateHandler
(
I2C_ID_T
id
)
231
{
232
if
(!
IP_I2C_MasterXfer_StateHandler
(i2c[
id
].
ip
, i2c[
id
].
mXfer
)) {
233
i2c[id].
mEvent
(
id
,
I2C_EVENT_DONE
);
234
}
235
}
236
237
/* Setup slave function */
238
void
Chip_I2C_SlaveSetup
(
I2C_ID_T
id
,
239
I2C_SLAVE_ID
sid,
240
I2C_XFER_T
*xfer,
241
I2C_EVENTHANDLER_T
event
,
242
uint8_t addrMask)
243
{
244
struct
i2c_interface
*iic = &i2c[id];
245
struct
i2c_slave_interface
*si2c = &
i2c_slave
[id][sid];
246
si2c->
xfer
=
xfer
;
247
si2c->
event
=
event
;
248
249
/* Set up the slave address */
250
if
(sid !=
I2C_SLAVE_GENERAL
) {
251
IP_I2C_SetSlaveAddress
(iic->
ip
, sid, xfer->
slaveAddr
, addrMask);
252
}
253
254
if
(!
SLAVE_ACTIVE
(iic) && !iic->
mXfer
) {
255
IP_I2C_Slave_StartXfer
(iic->
ip
);
256
}
257
iic->
flags
|= 1 << (sid + 8);
258
}
259
260
/* I2C Slave event handler */
261
void
Chip_I2C_SlaveStateHandler
(
I2C_ID_T
id
)
262
{
263
int
ret;
264
struct
i2c_interface
*iic = &i2c[id];
265
266
/* Get the currently addressed slave */
267
if
(!iic->
sXfer
) {
268
struct
i2c_slave_interface
*si2c;
269
270
I2C_SLAVE_ID
sid =
IP_I2C_GetSlaveIndex
(iic->
ip
);
271
si2c = &
i2c_slave
[id][sid];
272
iic->
sXfer
= si2c->
xfer
;
273
iic->
sEvent
= si2c->
event
;
274
}
275
276
iic->
sXfer
->
slaveAddr
|= iic->
mXfer
!= 0;
277
ret =
IP_I2C_SlaveXfer_StateHandler
(iic->
ip
, iic->
sXfer
);
278
if
(ret) {
279
if
(iic->
sXfer
->
status
==
I2C_STATUS_DONE
) {
280
iic->
sXfer
= 0;
281
}
282
iic->
sEvent
(
id
, (
I2C_EVENT_T
) ret);
283
}
284
}
285
286
/* Disable I2C device */
287
void
Chip_I2C_Disable
(
I2C_ID_T
id
)
288
{
289
IP_I2C_Disable
(i2c[
id
].ip);
290
}
291
292
/* State change checking */
293
int
Chip_I2C_IsStateChanged
(
I2C_ID_T
id
)
294
{
295
return
IP_I2C_IsStateChanged
(i2c[
id
].ip);
296
}
297
298
#endif
software
lpc_core
lpc_chip
chip_11xx
i2c_11xx.c
Generated on Fri May 10 2013 10:42:12 for LPCOpen Platform by
1.8.2