]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/i2c_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_Freescale / TARGET_KPSDK_MCUS / i2c_api.c
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 #include "mbed_assert.h"
17 #include "i2c_api.h"
18
19 #if DEVICE_I2C
20
21 #include "cmsis.h"
22 #include "pinmap.h"
23 #include "fsl_clock_manager.h"
24 #include "fsl_i2c_hal.h"
25 #include "fsl_port_hal.h"
26 #include "fsl_sim_hal.h"
27 #include "PeripheralPins.h"
28
29 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
30 uint32_t i2c_sda = pinmap_peripheral(sda, PinMap_I2C_SDA);
31 uint32_t i2c_scl = pinmap_peripheral(scl, PinMap_I2C_SCL);
32 obj->instance = pinmap_merge(i2c_sda, i2c_scl);
33 MBED_ASSERT((int)obj->instance != NC);
34
35 CLOCK_SYS_EnableI2cClock(obj->instance);
36 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
37 I2C_HAL_Init(i2c_addrs[obj->instance]);
38 I2C_HAL_Enable(i2c_addrs[obj->instance]);
39 I2C_HAL_SetIntCmd(i2c_addrs[obj->instance], true);
40 i2c_frequency(obj, 100000);
41
42 pinmap_pinout(sda, PinMap_I2C_SDA);
43 pinmap_pinout(scl, PinMap_I2C_SCL);
44
45 uint32_t port_addrs[] = PORT_BASE_ADDRS;
46 PORT_HAL_SetOpenDrainCmd(port_addrs[sda >> GPIO_PORT_SHIFT], sda & 0xFF, true);
47 PORT_HAL_SetOpenDrainCmd(port_addrs[scl >> GPIO_PORT_SHIFT], scl & 0xFF, true);
48 }
49
50 int i2c_start(i2c_t *obj) {
51 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
52 I2C_HAL_SendStart(i2c_addrs[obj->instance]);
53 return 0;
54 }
55
56 int i2c_stop(i2c_t *obj) {
57 volatile uint32_t n = 0;
58 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
59 if (I2C_HAL_IsMaster(i2c_addrs[obj->instance]))
60 I2C_HAL_SendStop(i2c_addrs[obj->instance]);
61
62 // It seems that there are timing problems
63 // when there is no waiting time after a STOP.
64 // This wait is also included on the samples
65 // code provided with the freedom board
66 for (n = 0; n < 200; n++) __NOP();
67 return 0;
68 }
69
70 static int timeout_status_poll(i2c_t *obj, i2c_status_flag_t flag) {
71 uint32_t i, timeout = 100000;
72 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
73
74 for (i = 0; i < timeout; i++) {
75 if (I2C_HAL_GetStatusFlag(i2c_addrs[obj->instance], flag))
76 return 0;
77 }
78 return 1;
79 }
80
81 // this function waits the end of a tx transfer and return the status of the transaction:
82 // 0: OK ack received
83 // 1: OK ack not received
84 // 2: failure
85 static int i2c_wait_end_tx_transfer(i2c_t *obj) {
86 // wait for the interrupt flag
87 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
88
89 if (timeout_status_poll(obj, kI2CInterruptPending)) {
90 return 2;
91 }
92 I2C_HAL_ClearInt(i2c_addrs[obj->instance]);
93
94 // wait transfer complete
95 if (timeout_status_poll(obj, kI2CTransferComplete)) {
96 return 2;
97 }
98
99 // check if we received the ACK or not
100 return I2C_HAL_GetStatusFlag(i2c_addrs[obj->instance], kI2CReceivedNak) ? 1 : 0;
101 }
102
103 // this function waits the end of a rx transfer and return the status of the transaction:
104 // 0: OK
105 // 1: failure
106 static int i2c_wait_end_rx_transfer(i2c_t *obj) {
107 // wait for the end of the rx transfer
108 if (timeout_status_poll(obj, kI2CInterruptPending)) {
109 return 1;
110 }
111 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
112 I2C_HAL_ClearInt(i2c_addrs[obj->instance]);
113
114 return 0;
115 }
116
117 static int i2c_do_write(i2c_t *obj, int value) {
118 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
119 I2C_HAL_WriteByte(i2c_addrs[obj->instance], value);
120
121 // init and wait the end of the transfer
122 return i2c_wait_end_tx_transfer(obj);
123 }
124
125 static int i2c_do_read(i2c_t *obj, char * data, int last) {
126 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
127 if (last) {
128 I2C_HAL_SendNak(i2c_addrs[obj->instance]);
129 } else {
130 I2C_HAL_SendAck(i2c_addrs[obj->instance]);
131 }
132
133 *data = (I2C_HAL_ReadByte(i2c_addrs[obj->instance]) & 0xFF);
134
135 // start rx transfer and wait the end of the transfer
136 return i2c_wait_end_rx_transfer(obj);
137 }
138
139 void i2c_frequency(i2c_t *obj, int hz) {
140 uint32_t busClock;
141 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
142 clock_manager_error_code_t error = CLOCK_SYS_GetFreq(kBusClock, &busClock);
143 if (error == kClockManagerSuccess) {
144 I2C_HAL_SetBaudRate(i2c_addrs[obj->instance], busClock, hz / 1000, NULL);
145 }
146 }
147
148 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
149 int count;
150 char dummy_read, *ptr;
151
152 if (i2c_start(obj)) {
153 i2c_stop(obj);
154 return I2C_ERROR_BUS_BUSY;
155 }
156
157 if (i2c_do_write(obj, (address | 0x01))) {
158 i2c_stop(obj);
159 return I2C_ERROR_NO_SLAVE;
160 }
161
162 // set rx mode
163 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
164 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive);
165
166 // Read in bytes
167 for (count = 0; count < (length); count++) {
168 ptr = (count == 0) ? &dummy_read : &data[count - 1];
169 uint8_t stop_ = (count == (length - 1)) ? 1 : 0;
170 if (i2c_do_read(obj, ptr, stop_)) {
171 i2c_stop(obj);
172 return count;
173 }
174 }
175
176 // If not repeated start, send stop.
177 if (stop)
178 i2c_stop(obj);
179
180 // last read
181 data[count-1] = I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
182
183 return length;
184 }
185
186 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
187 int i;
188
189 if (i2c_start(obj)) {
190 i2c_stop(obj);
191 return I2C_ERROR_BUS_BUSY;
192 }
193
194 if (i2c_do_write(obj, (address & 0xFE))) {
195 i2c_stop(obj);
196 return I2C_ERROR_NO_SLAVE;
197 }
198
199 for (i = 0; i < length; i++) {
200 if(i2c_do_write(obj, data[i])) {
201 i2c_stop(obj);
202 return i;
203 }
204 }
205
206 if (stop)
207 i2c_stop(obj);
208
209 return length;
210 }
211
212 void i2c_reset(i2c_t *obj) {
213 i2c_stop(obj);
214 }
215
216 int i2c_byte_read(i2c_t *obj, int last) {
217 char data;
218 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
219 // set rx mode
220 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive);
221
222 // Setup read
223 i2c_do_read(obj, &data, last);
224
225 // set tx mode
226 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend);
227 return I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
228 }
229
230 int i2c_byte_write(i2c_t *obj, int data) {
231 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
232 // set tx mode
233 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend);
234
235 return !i2c_do_write(obj, (data & 0xFF));
236 }
237
238
239 #if DEVICE_I2CSLAVE
240 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
241 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
242 if (enable_slave) {
243 // set slave mode
244 BW_I2C_C1_MST(i2c_addrs[obj->instance], 0);
245 I2C_HAL_SetIntCmd(i2c_addrs[obj->instance], true);
246 } else {
247 // set master mode
248 BW_I2C_C1_MST(i2c_addrs[obj->instance], 1);
249 }
250 }
251
252 int i2c_slave_receive(i2c_t *obj) {
253 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
254 switch(HW_I2C_S_RD(i2c_addrs[obj->instance])) {
255 // read addressed
256 case 0xE6:
257 return 1;
258 // write addressed
259 case 0xE2:
260 return 3;
261 default:
262 return 0;
263 }
264 }
265
266 int i2c_slave_read(i2c_t *obj, char *data, int length) {
267 uint8_t dummy_read;
268 uint8_t *ptr;
269 int count;
270 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
271 // set rx mode
272 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend);
273
274 // first dummy read
275 dummy_read = I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
276 if (i2c_wait_end_rx_transfer(obj))
277 return 0;
278
279 // read address
280 dummy_read = I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
281 if (i2c_wait_end_rx_transfer(obj))
282 return 0;
283
284 // read (length - 1) bytes
285 for (count = 0; count < (length - 1); count++) {
286 data[count] = I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
287 if (i2c_wait_end_rx_transfer(obj))
288 return count;
289 }
290
291 // read last byte
292 ptr = (length == 0) ? &dummy_read : (uint8_t *)&data[count];
293 *ptr = I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
294
295 return (length) ? (count + 1) : 0;
296 }
297
298 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
299 int i, count = 0;
300 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
301
302 // set tx mode
303 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CSend);
304
305 for (i = 0; i < length; i++) {
306 if (i2c_do_write(obj, data[count++]) == 2)
307 return i;
308 }
309
310 // set rx mode
311 I2C_HAL_SetDirMode(i2c_addrs[obj->instance], kI2CReceive);
312
313 // dummy rx transfer needed
314 // otherwise the master cannot generate a stop bit
315 I2C_HAL_ReadByte(i2c_addrs[obj->instance]);
316 if (i2c_wait_end_rx_transfer(obj) == 2)
317 return count;
318
319 return count;
320 }
321
322 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
323 uint32_t i2c_addrs[] = I2C_BASE_ADDRS;
324 I2C_HAL_SetUpperAddress7bit(i2c_addrs[obj->instance], address & 0xfe);
325 }
326 #endif
327
328 #endif
Imprint / Impressum