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_13xx.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
#include "
chip.h
"
32
33
/*****************************************************************************
34
* Private types/enumerations/variables
35
****************************************************************************/
36
#define SLAVE_ACTIVE(iic) (((iic)->flags & 0xFF00) != 0)
37
38
/* I2C common interface structure */
39
struct
i2c_interface
{
40
LPC_I2C_T
*
ip
;
/* IP base address of the I2C device */
41
CHIP_SYSCTL_CLOCK_T
clk
;
/* Clock used by I2C */
42
I2C_EVENTHANDLER_T
mEvent
;
/* Current active Master event handler */
43
I2C_EVENTHANDLER_T
sEvent
;
/* Slave transfer events */
44
I2C_XFER_T
*
mXfer
;
/* Current active xfer pointer */
45
I2C_XFER_T
*
sXfer
;
/* Pointer to store xfer when bus is busy */
46
uint32_t
flags
;
/* Flags used by I2C master and slave */
47
};
48
49
/* Slave interface structure */
50
struct
i2c_slave_interface
{
51
I2C_XFER_T
*
xfer
;
52
I2C_EVENTHANDLER_T
event
;
53
};
54
55
/* I2C interfaces */
56
static
struct
i2c_interface
i2c
[
I2C_NUM_INTERFACE
] = {
57
{
LPC_I2C
,
SYSCTL_CLOCK_I2C
,
Chip_I2C_EventHandler
,
NULL
,
NULL
,
NULL
, 0}
58
};
59
60
static
struct
i2c_slave_interface
i2c_slave
[
I2C_NUM_INTERFACE
][
I2C_SLAVE_NUM_INTERFACE
];
61
62
/*****************************************************************************
63
* Public types/enumerations/variables
64
****************************************************************************/
65
66
/*****************************************************************************
67
* Private functions
68
****************************************************************************/
69
70
/*****************************************************************************
71
* Public functions
72
****************************************************************************/
73
/* Chip event handler interrupt based */
74
void
Chip_I2C_EventHandler
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
75
{
76
struct
i2c_interface
*iic = &i2c[id];
77
volatile
I2C_STATUS_T
*stat;
78
79
/* Only WAIT event needs to be handled */
80
if
(event !=
I2C_EVENT_WAIT
) {
81
return
;
82
}
83
84
stat = &iic->
mXfer
->
status
;
85
/* Wait for the status to change */
86
while
(*stat ==
I2C_STATUS_BUSY
) {}
87
}
88
89
/* Chip polling event handler */
90
void
Chip_I2C_EventHandlerPolling
(
I2C_ID_T
id
,
I2C_EVENT_T
event
)
91
{
92
struct
i2c_interface
*iic = &i2c[id];
93
volatile
I2C_STATUS_T
*stat;
94
95
/* Only WAIT event needs to be handled */
96
if
(event !=
I2C_EVENT_WAIT
) {
97
return
;
98
}
99
100
stat = &iic->
mXfer
->
status
;
101
/* Call the state change handler till xfer is done */
102
while
(*stat ==
I2C_STATUS_BUSY
) {
103
if
(
IP_I2C_IsStateChanged
(iic->
ip
)) {
104
Chip_I2C_MasterStateHandler
(
id
);
105
}
106
}
107
}
108
109
/* Initializes the LPC_I2C peripheral with specified parameter */
110
void
Chip_I2C_Init
(
I2C_ID_T
id
)
111
{
112
/* Enable I2C Clocking */
113
Chip_Clock_EnablePeriphClock
(i2c[
id
].
clk
);
114
115
IP_I2C_Init
(i2c[
id
].
ip
);
116
}
117
118
/* De-initializes the I2C peripheral registers to their default reset values */
119
void
Chip_I2C_DeInit
(
I2C_ID_T
id
)
120
{
121
IP_I2C_DeInit
(i2c[
id
].
ip
);
122
123
/* Disable I2C clocking */
124
Chip_Clock_DisablePeriphClock
(i2c[
id
].
clk
);
125
}
126
127
/* Set up clock rate for LPC_I2C peripheral */
128
void
Chip_I2C_SetClockRate
(
I2C_ID_T
id
,
uint32_t
clockrate)
129
{
130
IP_I2C_SetClockRate
(i2c[
id
].
ip
, (
Chip_Clock_GetSystemClockRate
() / clockrate));
131
}
132
133
/* Get current clock rate for LPC_I2C peripheral */
134
uint32_t
Chip_I2C_GetClockRate
(
I2C_ID_T
id
)
135
{
136
return
Chip_Clock_GetSystemClockRate
() /
IP_I2C_GetClockDiv
(i2c[
id
].
ip
);
137
}
138
139
/* Set the master event handler */
140
int
Chip_I2C_SetMasterEventHandler
(
I2C_ID_T
id
,
I2C_EVENTHANDLER_T
event
)
141
{
142
struct
i2c_interface
*iic = &i2c[id];
143
if
(!iic->
mXfer
) {
144
iic->
mEvent
=
event
;
145
}
146
return
iic->
mEvent
==
event
;
147
}
148
149
/* Get the master event handler */
150
I2C_EVENTHANDLER_T
Chip_I2C_GetMasterEventHandler
(
I2C_ID_T
id
)
151
{
152
return
i2c[id].
mEvent
;
153
}
154
155
/* Transmit and Receive data in master mode */
156
int
Chip_I2C_MasterTransfer
(
I2C_ID_T
id
,
I2C_XFER_T
*xfer)
157
{
158
struct
i2c_interface
*iic = &i2c[id];
159
160
iic->
mEvent
(
id
,
I2C_EVENT_LOCK
);
161
xfer->
status
=
I2C_STATUS_BUSY
;
162
iic->
mXfer
= xfer;
163
164
/* If slave xfer not in progress */
165
if
(!iic->
sXfer
) {
166
IP_I2C_Master_StartXfer
(iic->
ip
);
167
}
168
iic->
mEvent
(
id
,
I2C_EVENT_WAIT
);
169
iic->
mXfer
= 0;
170
171
/* Wait for stop condition to appear on bus */
172
while
(!
IP_I2C_BusFree
(iic->
ip
)) {}
173
174
/* Start slave if one is active */
175
if
(
SLAVE_ACTIVE
(iic)) {
176
IP_I2C_Slave_StartXfer
(iic->
ip
);
177
}
178
179
iic->
mEvent
(
id
,
I2C_EVENT_UNLOCK
);
180
return
(
int
) xfer->
status
;
181
}
182
183
/* Master tx only */
184
int
Chip_I2C_MasterSend
(
I2C_ID_T
id
, uint8_t slaveAddr,
const
uint8_t *buff, uint8_t len)
185
{
186
I2C_XFER_T
xfer = {0};
187
xfer.
slaveAddr
= slaveAddr;
188
xfer.
txBuff
= buff;
189
xfer.
txSz
= len;
190
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
191
return
len - xfer.
txSz
;
192
}
193
194
/* Transmit one byte and receive an array of bytes after a repeated start condition is generated in Master mode.
195
* This function is useful for communicating with the I2C slave registers
196
*/
197
int
Chip_I2C_MasterCmdRead
(
I2C_ID_T
id
, uint8_t slaveAddr, uint8_t cmd, uint8_t *buff,
int
len)
198
{
199
I2C_XFER_T
xfer = {0};
200
xfer.
slaveAddr
= slaveAddr;
201
xfer.
txBuff
= &cmd;
202
xfer.
txSz
= 1;
203
xfer.
rxBuff
= buff;
204
xfer.
rxSz
= len;
205
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
206
return
len - xfer.
rxSz
;
207
}
208
209
/* Sequential master read */
210
int
Chip_I2C_MasterRead
(
I2C_ID_T
id
, uint8_t slaveAddr, uint8_t *buff,
int
len)
211
{
212
I2C_XFER_T
xfer = {0};
213
xfer.
slaveAddr
= slaveAddr;
214
xfer.
rxBuff
= buff;
215
xfer.
rxSz
= len;
216
while
(
Chip_I2C_MasterTransfer
(
id
, &xfer) ==
I2C_STATUS_ARBLOST
) {}
217
return
len - xfer.
rxSz
;
218
}
219
220
/* Check if master state is active */
221
int
Chip_I2C_IsMasterActive
(
I2C_ID_T
id
)
222
{
223
return
IP_I2C_IsMasterState
(i2c[
id
].
ip
);
224
}
225
226
/* State change handler for master transfer */
227
void
Chip_I2C_MasterStateHandler
(
I2C_ID_T
id
)
228
{
229
if
(!
IP_I2C_MasterXfer_StateHandler
(i2c[
id
].
ip
, i2c[
id
].
mXfer
)) {
230
i2c[id].
mEvent
(
id
,
I2C_EVENT_DONE
);
231
}
232
}
233
234
/* Setup slave function */
235
void
Chip_I2C_SlaveSetup
(
I2C_ID_T
id
,
236
I2C_SLAVE_ID
sid,
237
I2C_XFER_T
*xfer,
238
I2C_EVENTHANDLER_T
event
,
239
uint8_t addrMask)
240
{
241
struct
i2c_interface
*iic = &i2c[id];
242
struct
i2c_slave_interface
*si2c = &
i2c_slave
[id][sid];
243
si2c->
xfer
=
xfer
;
244
si2c->
event
=
event
;
245
246
/* Set up the slave address */
247
if
(sid !=
I2C_SLAVE_GENERAL
) {
248
IP_I2C_SetSlaveAddress
(iic->
ip
, sid, xfer->
slaveAddr
, addrMask);
249
}
250
251
if
(!
SLAVE_ACTIVE
(iic) && !iic->
mXfer
) {
252
IP_I2C_Slave_StartXfer
(iic->
ip
);
253
}
254
iic->
flags
|= 1 << (sid + 8);
255
}
256
257
/* I2C Slave event handler */
258
void
Chip_I2C_SlaveStateHandler
(
I2C_ID_T
id
)
259
{
260
int
ret;
261
struct
i2c_interface
*iic = &i2c[id];
262
263
/* Get the currently addressed slave */
264
if
(!iic->
sXfer
) {
265
struct
i2c_slave_interface
*si2c;
266
267
I2C_SLAVE_ID
sid =
IP_I2C_GetSlaveIndex
(iic->
ip
);
268
si2c = &
i2c_slave
[id][sid];
269
iic->
sXfer
= si2c->
xfer
;
270
iic->
sEvent
= si2c->
event
;
271
}
272
273
iic->
sXfer
->
slaveAddr
|= iic->
mXfer
!= 0;
274
ret =
IP_I2C_SlaveXfer_StateHandler
(iic->
ip
, iic->
sXfer
);
275
if
(ret) {
276
if
(iic->
sXfer
->
status
==
I2C_STATUS_DONE
) {
277
iic->
sXfer
= 0;
278
}
279
iic->
sEvent
(
id
, (
I2C_EVENT_T
) ret);
280
}
281
}
282
283
/* Disable I2C device */
284
void
Chip_I2C_Disable
(
I2C_ID_T
id
)
285
{
286
IP_I2C_Disable
(i2c[
id
].ip);
287
}
288
289
/* State change checking */
290
int
Chip_I2C_IsStateChanged
(
I2C_ID_T
id
)
291
{
292
return
IP_I2C_IsStateChanged
(i2c[
id
].ip);
293
}
software
lpc_core
lpc_chip
chip_13xx
i2c_13xx.c
Generated on Fri May 10 2013 10:42:13 for LPCOpen Platform by
1.8.2