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_18xx_43xx.c
Go to the documentation of this file.
1
/*
2
* @brief LPC18xx/43xx 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
#include "
chip.h
"
33
34
/*****************************************************************************
35
* Private types/enumerations/variables
36
****************************************************************************/
37
#define SLAVE_ACTIVE(iic) (((iic)->flags & 0xFF00) != 0)
38
39
/* I2C common interface structure */
40
struct
i2c_interface
{
41
LPC_I2C_T
*
ip
;
/* IP base address of the I2C device */
42
CHIP_CCU_CLK_T
clk
;
/* Clock used by I2C */
43
I2C_EVENTHANDLER_T
mEvent
;
/* Current active Master event handler */
44
I2C_EVENTHANDLER_T
sEvent
;
/* Slave transfer events */
45
I2C_XFER_T
*
mXfer
;
/* Current active xfer pointer */
46
I2C_XFER_T
*
sXfer
;
/* Pointer to store xfer when bus is busy */
47
uint32_t
flags
;
/* Flags used by I2C master and slave */
48
};
49
50
/* Slave interface structure */
51
struct
i2c_slave_interface
{
52
I2C_XFER_T
*
xfer
;
53
I2C_EVENTHANDLER_T
event
;
54
};
55
56
/*****************************************************************************
57
* Public types/enumerations/variables
58
****************************************************************************/
59
/* I2C interfaces */
60
static
struct
i2c_interface
i2c
[
I2C_NUM_INTERFACE
] = {
61
{
LPC_I2C0
,
CLK_APB1_I2C0
,
Chip_I2C_EventHandler
,
NULL
,
NULL
,
NULL
, 0},
62
{
LPC_I2C1
,
CLK_APB3_I2C1
,
Chip_I2C_EventHandler
,
NULL
,
NULL
,
NULL
, 0}
63
};
64
65
static
struct
i2c_slave_interface
i2c_slave
[
I2C_NUM_INTERFACE
][
I2C_SLAVE_NUM_INTERFACE
];
66
67
/*****************************************************************************
68
* Private functions
69
****************************************************************************/
70
71
/*****************************************************************************
72
* Public functions
73
****************************************************************************/
74
/* Chip event handler interrupt based */
75
void
Chip_I2C_EventHandler
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
76
{
77
struct
i2c_interface
*iic = &i2c[id];
78
volatile
I2C_STATUS_T
*stat;
79
80
/* Only WAIT event needs to be handled */
81
if
(event !=
I2C_EVENT_WAIT
) {
82
return
;
83
}
84
85
stat = &iic->
mXfer
->
status
;
86
/* Wait for the status to change */
87
while
(*stat ==
I2C_STATUS_BUSY
) {}
88
}
89
90
/* Chip polling event handler */
91
void
Chip_I2C_EventHandlerPolling
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
92
{
93
struct
i2c_interface
*iic = &i2c[id];
94
volatile
I2C_STATUS_T
*stat;
95
96
/* Only WAIT event needs to be handled */
97
if
(event !=
I2C_EVENT_WAIT
) {
98
return
;
99
}
100
101
stat = &iic->
mXfer
->
status
;
102
/* Call the state change handler till xfer is done */
103
while
(*stat ==
I2C_STATUS_BUSY
) {
104
if
(
IP_I2C_IsStateChanged
(iic->
ip
)) {
105
Chip_I2C_MasterStateHandler
(
id
);
106
}
107
}
108
}
109
110
/* Initializes the LPC_I2C peripheral with specified parameter */
111
void
Chip_I2C_Init
(
I2C_ID_T
id
)
112
{
113
/* Enable I2C Clocking */
114
Chip_Clock_Enable
(i2c[
id
].
clk
);
115
116
IP_I2C_Init
(i2c[
id
].
ip
);
117
}
118
119
/* De-initializes the I2C peripheral registers to their default reset values */
120
void
Chip_I2C_DeInit
(
I2C_ID_T
id
)
121
{
122
IP_I2C_DeInit
(i2c[
id
].
ip
);
123
124
/* Disable I2C clocking */
125
Chip_Clock_Disable
(i2c[
id
].
clk
);
126
}
127
128
/* Set up clock rate for LPC_I2C peripheral */
129
void
Chip_I2C_SetClockRate
(
I2C_ID_T
id
,
uint32_t
clockrate)
130
{
131
IP_I2C_SetClockRate
(i2c[
id
].
ip
,
Chip_Clock_GetRate
(i2c[
id
].
clk
) / clockrate);
132
}
133
134
/* Get current clock rate for LPC_I2C peripheral */
135
uint32_t
Chip_I2C_GetClockRate
(
I2C_ID_T
id
)
136
{
137
return
Chip_Clock_GetRate
(i2c[
id
].
clk
) /
IP_I2C_GetClockDiv
(i2c[
id
].
ip
);
138
}
139
140
/* Set the master event handler */
141
int
Chip_I2C_SetMasterEventHandler
(
I2C_ID_T
id
,
I2C_EVENTHANDLER_T
event
)
142
{
143
struct
i2c_interface
*iic = &i2c[id];
144
if
(!iic->
mXfer
) {
145
iic->
mEvent
=
event
;
146
}
147
return
iic->
mEvent
==
event
;
148
}
149
150
/* Get the master event handler */
151
I2C_EVENTHANDLER_T
Chip_I2C_GetMasterEventHandler
(
I2C_ID_T
id
)
152
{
153
return
i2c[id].
mEvent
;
154
}
155
156
/* Transmit and Receive data in master mode */
157
int
Chip_I2C_MasterTransfer
(
I2C_ID_T
id
,
I2C_XFER_T
*xfer)
158
{
159
struct
i2c_interface
*iic = &i2c[id];
160
161
iic->
mEvent
(
id
,
I2C_EVENT_LOCK
);
162
xfer->
status
=
I2C_STATUS_BUSY
;
163
iic->
mXfer
= xfer;
164
165
/* If slave xfer not in progress */
166
if
(!iic->
sXfer
) {
167
IP_I2C_Master_StartXfer
(iic->
ip
);
168
}
169
170
iic->
mEvent
(
id
,
I2C_EVENT_WAIT
);
171
iic->
mXfer
= 0;
172
173
/* Wait for stop condition to appear on bus */
174
while
(!
IP_I2C_BusFree
(iic->
ip
)) {}
175
176
/* Start slave if one is active */
177
if
(
SLAVE_ACTIVE
(iic)) {
178
IP_I2C_Slave_StartXfer
(iic->
ip
);
179
}
180
181
iic->
mEvent
(
id
,
I2C_EVENT_UNLOCK
);
182
183
return
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
}
software
lpc_core
lpc_chip
chip_18xx_43xx
i2c_18xx_43xx.c
Generated on Fri May 10 2013 10:42:16 for LPCOpen Platform by
1.8.2