Skip to content

Commit a2f2f44

Browse files
committed
[LPC1549] Added I2C master support
1 parent 95f4057 commit a2f2f44

File tree

2 files changed

+259
-1
lines changed

2 files changed

+259
-1
lines changed

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC15XX/device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
#define DEVICE_SERIAL 1
2929
#define DEVICE_SERIAL_FC 1
3030

31-
#define DEVICE_I2C 0
31+
#define DEVICE_I2C 1
3232
#define DEVICE_I2CSLAVE 0
3333

3434
#define DEVICE_SPI 1
Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2013 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include "i2c_api.h"
18+
#include "cmsis.h"
19+
#include "pinmap.h"
20+
#include "error.h"
21+
22+
static uint8_t repeated_start = 0;
23+
24+
#define I2C_STAT(x) ((LPC_I2C0->STAT >> 1) & (0x07))
25+
26+
static inline int i2c_status(i2c_t *obj) {
27+
return I2C_STAT(obj);
28+
}
29+
30+
// Wait until the Serial Interrupt (SI) is set
31+
static int i2c_wait_SI(i2c_t *obj) {
32+
int timeout = 0;
33+
while (!(LPC_I2C0->STAT & (1 << 0))) {
34+
timeout++;
35+
if (timeout > 100000) return -1;
36+
}
37+
return 0;
38+
}
39+
40+
static inline void i2c_interface_enable(i2c_t *obj) {
41+
LPC_I2C0->CFG |= (1 << 0);
42+
}
43+
44+
static inline void i2c_power_enable(i2c_t *obj) {
45+
// Enables clock for I2C0
46+
LPC_SYSCON->SYSAHBCLKCTRL1 |= (1<<13);
47+
// LPC_SYSCON->PRESETCTRL1 &= ~(0x1<<13);
48+
LPC_SYSCON->PRESETCTRL1 |= (0x1<<13);
49+
LPC_SYSCON->PRESETCTRL1 &= ~(0x1 << 13);
50+
51+
}
52+
53+
void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
54+
55+
// ピン定義の確認どうしよう…
56+
57+
58+
// enable power
59+
i2c_power_enable(obj);
60+
// pin enable
61+
LPC_SWM->PINENABLE1 &= ~(0x3 << 3);
62+
// set default frequency at 100k
63+
i2c_frequency(obj, 100000);
64+
i2c_interface_enable(obj);
65+
}
66+
67+
inline int i2c_start(i2c_t *obj) {
68+
int status = 0;
69+
if (repeated_start) {
70+
LPC_I2C0->MSTCTL = (1 << 1) | (1 << 0);
71+
repeated_start = 0;
72+
} else {
73+
LPC_I2C0->MSTCTL = (1 << 1);
74+
}
75+
return status;
76+
}
77+
78+
inline int i2c_stop(i2c_t *obj) {
79+
int timeout = 0;
80+
81+
LPC_I2C0->MSTCTL = (1 << 2) | (1 << 0);
82+
while ((LPC_I2C0->STAT & ((1 << 0) | (7 << 1))) != ((1 << 0) | (0 << 1))) {
83+
timeout ++;
84+
if (timeout > 100000) return 1;
85+
}
86+
87+
return 0;
88+
}
89+
90+
91+
static inline int i2c_do_write(i2c_t *obj, int value, uint8_t addr) {
92+
// write the data
93+
LPC_I2C0->MSTDAT = value;
94+
95+
if (!addr)
96+
LPC_I2C0->MSTCTL = (1 << 0);
97+
98+
// wait and return status
99+
i2c_wait_SI(obj);
100+
return i2c_status(obj);
101+
}
102+
103+
static inline int i2c_do_read(i2c_t *obj, int last) {
104+
// wait for it to arrive
105+
i2c_wait_SI(obj);
106+
if (!last)
107+
LPC_I2C0->MSTCTL = (1 << 0);
108+
109+
// return the data
110+
//return (I2C_DAT(obj) & 0xFF);
111+
return (LPC_I2C0->MSTDAT & 0xFF);
112+
}
113+
114+
void i2c_frequency(i2c_t *obj, int hz) {
115+
// No peripheral clock divider on the M0
116+
uint32_t PCLK = SystemCoreClock;
117+
118+
uint32_t clkdiv = PCLK / (hz * 4) - 1;
119+
120+
LPC_I2C0->DIV = clkdiv;
121+
LPC_I2C0->MSTTIME = 0;
122+
}
123+
124+
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
125+
int count, status;
126+
int timeout = 0;
127+
128+
i2c_start(obj);
129+
130+
//status = i2c_do_write(obj, (address | 0x01), 1);
131+
LPC_I2C0->MSTDAT = (address | 0x01);
132+
LPC_I2C0->MSTCTL |= 0x20;
133+
while (!(LPC_I2C0->STAT & (1 << 0))) {
134+
timeout++;
135+
if (timeout > 100000) return -1;
136+
}
137+
status = ((LPC_I2C0->STAT >> 1) & (0x07));
138+
139+
if (status != 0x01) {
140+
i2c_stop(obj);
141+
return I2C_ERROR_NO_SLAVE;
142+
}
143+
144+
// Read in all except last byte
145+
for (count = 0; count < (length - 1); count++) {
146+
//int value = i2c_do_read(obj, 0);
147+
while (!(LPC_I2C0->STAT & (1 << 0))) {
148+
timeout++;
149+
if (timeout > 100000) return -1;
150+
}
151+
if (!0)
152+
LPC_I2C0->MSTCTL = (1 << 0);
153+
data[count] = (LPC_I2C0->MSTDAT & 0xFF);
154+
//
155+
status = ((LPC_I2C0->STAT >> 1) & (0x07));
156+
if (status != 0x00) {
157+
i2c_stop(obj);
158+
return count;
159+
}
160+
//data[count] = (char) value;
161+
}
162+
163+
// read in last byte
164+
//int value = i2c_do_read(obj, 1);
165+
while (!(LPC_I2C0->STAT & (1 << 0))) {
166+
timeout++;
167+
if (timeout > 100000) return -1;
168+
}
169+
data[count] = (LPC_I2C0->MSTDAT & 0xFF);
170+
//
171+
status = i2c_status(obj);
172+
if (status != 0x01) {
173+
i2c_stop(obj);
174+
return length - 1;
175+
}
176+
177+
//data[count] = (char) value;
178+
179+
// If not repeated start, send stop.
180+
if (stop) {
181+
i2c_stop(obj);
182+
} else {
183+
repeated_start = 1;
184+
}
185+
186+
return length;
187+
}
188+
189+
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
190+
int i, status;
191+
int timeout = 0;
192+
193+
i2c_start(obj);
194+
195+
//status = i2c_do_write(obj, (address & 0xFE), 1);
196+
LPC_I2C0->MSTDAT = (address & 0xFE);
197+
LPC_I2C0->MSTCTL |= 0x20;
198+
// wait and return status
199+
while (!(LPC_I2C0->STAT & (1 << 0))) {
200+
timeout++;
201+
if (timeout > 100000) return -1;
202+
}
203+
status = ((LPC_I2C0->STAT >> 1) & (0x07));
204+
205+
if (status != 0x02) {
206+
i2c_stop(obj);
207+
return I2C_ERROR_NO_SLAVE;
208+
}
209+
210+
for (i=0; i<length; i++) {
211+
//status = i2c_do_write(obj, data[i], 0);
212+
LPC_I2C0->MSTDAT = data[i];
213+
LPC_I2C0->MSTCTL = (1 << 0);
214+
// wait and return status
215+
while (!(LPC_I2C0->STAT & (1 << 0))) {
216+
timeout++;
217+
if (timeout > 100000) return -1;
218+
}
219+
status = ((LPC_I2C0->STAT >> 1) & (0x07));
220+
if (status != 0x02) {
221+
i2c_stop(obj);
222+
return i;
223+
}
224+
}
225+
226+
// If not repeated start, send stop.
227+
if (stop) {
228+
i2c_stop(obj);
229+
} else {
230+
repeated_start = 1;
231+
}
232+
233+
return length;
234+
}
235+
236+
void i2c_reset(i2c_t *obj) {
237+
i2c_stop(obj);
238+
}
239+
240+
int i2c_byte_read(i2c_t *obj, int last) {
241+
return (i2c_do_read(obj, last) & 0xFF);
242+
}
243+
244+
int i2c_byte_write(i2c_t *obj, int data) {
245+
int ack;
246+
int status = i2c_do_write(obj, (data & 0xFF), 0);
247+
248+
switch(status) {
249+
case 2:
250+
ack = 1;
251+
break;
252+
default:
253+
ack = 0;
254+
break;
255+
}
256+
257+
return ack;
258+
}

0 commit comments

Comments
 (0)