]> git.donarmstrong.com Git - qmk_firmware.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/i2c_api.c
Merge commit '1fe4406f374291ab2e86e95a97341fd9c475fcb8'
[qmk_firmware.git] / tmk_core / 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