]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32L1/i2c_api.c
Merge commit '4d116a04e94cf0d19317d5b44e4fa9f34a3e5594'
[tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32L1 / i2c_api.c
1 /* mbed Microcontroller Library
2 *******************************************************************************
3 * Copyright (c) 2014, STMicroelectronics
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * 3. Neither the name of STMicroelectronics nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *******************************************************************************
29 */
30 #include "mbed_assert.h"
31 #include "i2c_api.h"
32
33 #if DEVICE_I2C
34
35 #include "cmsis.h"
36 #include "pinmap.h"
37 #include "PeripheralPins.h"
38
39 /* Timeout values for flags and events waiting loops. These timeouts are
40 not based on accurate values, they just guarantee that the application will
41 not remain stuck if the I2C communication is corrupted. */
42 #define FLAG_TIMEOUT ((int)0x1000)
43 #define LONG_TIMEOUT ((int)0x8000)
44
45 I2C_HandleTypeDef I2cHandle;
46
47 int i2c1_inited = 0;
48 int i2c2_inited = 0;
49
50 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
51 {
52 // Determine the I2C to use
53 I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
54 I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
55
56 obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
57 MBED_ASSERT(obj->i2c != (I2CName)NC);
58
59 // Enable I2C1 clock and pinout if not done
60 if ((obj->i2c == I2C_1) && !i2c1_inited) {
61 i2c1_inited = 1;
62 __I2C1_CLK_ENABLE();
63 // Configure I2C pins
64 pinmap_pinout(sda, PinMap_I2C_SDA);
65 pinmap_pinout(scl, PinMap_I2C_SCL);
66 pin_mode(sda, OpenDrain);
67 pin_mode(scl, OpenDrain);
68 }
69 // Enable I2C2 clock and pinout if not done
70 if ((obj->i2c == I2C_2) && !i2c2_inited) {
71 i2c2_inited = 1;
72 __I2C2_CLK_ENABLE();
73 // Configure I2C pins
74 pinmap_pinout(sda, PinMap_I2C_SDA);
75 pinmap_pinout(scl, PinMap_I2C_SCL);
76 pin_mode(sda, OpenDrain);
77 pin_mode(scl, OpenDrain);
78 }
79
80 // Reset to clear pending flags if any
81 i2c_reset(obj);
82
83 // I2C configuration
84 i2c_frequency(obj, 100000); // 100 kHz per default
85
86 // I2C master by default
87 obj->slave = 0;
88 }
89
90 void i2c_frequency(i2c_t *obj, int hz)
91 {
92 MBED_ASSERT((hz != 0) && (hz <= 400000));
93 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
94 int timeout;
95
96 // wait before init
97 timeout = LONG_TIMEOUT;
98 while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
99
100 // I2C configuration
101 I2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
102 I2cHandle.Init.ClockSpeed = hz;
103 I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
104 I2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2;
105 I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
106 I2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED;
107 I2cHandle.Init.OwnAddress1 = 0;
108 I2cHandle.Init.OwnAddress2 = 0;
109 HAL_I2C_Init(&I2cHandle);
110 if (obj->slave) {
111 /* Enable Address Acknowledge */
112 I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
113 }
114
115 }
116
117 inline int i2c_start(i2c_t *obj)
118 {
119 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
120 int timeout;
121
122 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
123
124 // Clear Acknowledge failure flag
125 __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
126
127 // Generate the START condition
128 i2c->CR1 |= I2C_CR1_START;
129
130 // Wait the START condition has been correctly sent
131 timeout = FLAG_TIMEOUT;
132 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
133 if ((timeout--) == 0) {
134 return 1;
135 }
136 }
137
138 return 0;
139 }
140
141 inline int i2c_stop(i2c_t *obj)
142 {
143 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
144
145 // Generate the STOP condition
146 i2c->CR1 |= I2C_CR1_STOP;
147
148 return 0;
149 }
150
151 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
152 {
153 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
154 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
155 int timeout;
156 int count;
157 int value;
158
159 i2c_start(obj);
160
161 // Wait until SB flag is set
162 timeout = FLAG_TIMEOUT;
163 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
164 timeout--;
165 if (timeout == 0) {
166 return -1;
167 }
168 }
169
170 i2c->DR = I2C_7BIT_ADD_READ(address);
171
172
173 // Wait address is acknowledged
174 timeout = FLAG_TIMEOUT;
175 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
176 timeout--;
177 if (timeout == 0) {
178 return -1;
179 }
180 }
181 __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
182
183 // Read all bytes except last one
184 for (count = 0; count < (length - 1); count++) {
185 value = i2c_byte_read(obj, 0);
186 data[count] = (char)value;
187 }
188
189 // If not repeated start, send stop.
190 // Warning: must be done BEFORE the data is read.
191 if (stop) {
192 i2c_stop(obj);
193 }
194
195 // Read the last byte
196 value = i2c_byte_read(obj, 1);
197 data[count] = (char)value;
198
199 return length;
200 }
201
202 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
203 {
204 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
205 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
206 int timeout;
207 int count;
208
209 i2c_start(obj);
210
211 // Wait until SB flag is set
212 timeout = FLAG_TIMEOUT;
213 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
214 timeout--;
215 if (timeout == 0) {
216 return -1;
217 }
218 }
219
220 i2c->DR = I2C_7BIT_ADD_WRITE(address);
221
222
223 // Wait address is acknowledged
224 timeout = FLAG_TIMEOUT;
225 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
226 timeout--;
227 if (timeout == 0) {
228 return -1;
229 }
230 }
231 __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
232
233 for (count = 0; count < length; count++) {
234 if (i2c_byte_write(obj, data[count]) != 1) {
235 i2c_stop(obj);
236 return -1;
237 }
238 }
239
240 // If not repeated start, send stop.
241 if (stop) {
242 i2c_stop(obj);
243 }
244
245 return count;
246 }
247
248 int i2c_byte_read(i2c_t *obj, int last)
249 {
250 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
251 int timeout;
252
253 if (last) {
254 // Don't acknowledge the last byte
255 i2c->CR1 &= ~I2C_CR1_ACK;
256 } else {
257 // Acknowledge the byte
258 i2c->CR1 |= I2C_CR1_ACK;
259 }
260
261 // Wait until the byte is received
262 timeout = FLAG_TIMEOUT;
263 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
264 if ((timeout--) == 0) {
265 return -1;
266 }
267 }
268
269 return (int)i2c->DR;
270 }
271
272 int i2c_byte_write(i2c_t *obj, int data)
273 {
274 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
275 int timeout;
276
277 i2c->DR = (uint8_t)data;
278
279 // Wait until the byte is transmitted
280 timeout = FLAG_TIMEOUT;
281 while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
282 (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
283 if ((timeout--) == 0) {
284 return 0;
285 }
286 }
287
288 return 1;
289 }
290
291 void i2c_reset(i2c_t *obj)
292 {
293 int timeout;
294
295 // wait before reset
296 timeout = LONG_TIMEOUT;
297 while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
298
299 if (obj->i2c == I2C_1) {
300 __I2C1_FORCE_RESET();
301 __I2C1_RELEASE_RESET();
302 }
303 if (obj->i2c == I2C_2) {
304 __I2C2_FORCE_RESET();
305 __I2C2_RELEASE_RESET();
306 }
307 }
308
309 #if DEVICE_I2CSLAVE
310
311 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
312 {
313 I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
314 uint16_t tmpreg = 0;
315
316 // Get the old register value
317 tmpreg = i2c->OAR1;
318 // Reset address bits
319 tmpreg &= 0xFC00;
320 // Set new address
321 tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
322 // Store the new register value
323 i2c->OAR1 = tmpreg;
324 }
325
326 void i2c_slave_mode(i2c_t *obj, int enable_slave)
327 {
328 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
329 if (enable_slave) {
330 obj->slave = 1;
331 /* Enable Address Acknowledge */
332 I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
333 }
334 }
335
336 // See I2CSlave.h
337 #define NoData 0 // the slave has not been addressed
338 #define ReadAddressed 1 // the master has requested a read from this slave (slave = transmitter)
339 #define WriteGeneral 2 // the master is writing to all slave
340 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
341
342 int i2c_slave_receive(i2c_t *obj)
343 {
344 int retValue = NoData;
345
346 if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
347 if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
348 if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
349 retValue = ReadAddressed;
350 else
351 retValue = WriteAddressed;
352
353 __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
354 }
355 }
356
357 return (retValue);
358 }
359
360 int i2c_slave_read(i2c_t *obj, char *data, int length)
361 {
362 uint32_t Timeout;
363 int size = 0;
364
365 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
366
367 while (length > 0) {
368 /* Wait until RXNE flag is set */
369 // Wait until the byte is received
370 Timeout = FLAG_TIMEOUT;
371 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
372 Timeout--;
373 if (Timeout == 0) {
374 return -1;
375 }
376 }
377
378 /* Read data from DR */
379 (*data++) = I2cHandle.Instance->DR;
380 length--;
381 size++;
382
383 if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
384 /* Read data from DR */
385 (*data++) = I2cHandle.Instance->DR;
386 length--;
387 size++;
388 }
389 }
390
391 /* Wait until STOP flag is set */
392 Timeout = FLAG_TIMEOUT;
393 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
394 Timeout--;
395 if (Timeout == 0) {
396 return -1;
397 }
398 }
399
400 /* Clear STOP flag */
401 __HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
402
403 /* Wait until BUSY flag is reset */
404 Timeout = FLAG_TIMEOUT;
405 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
406 Timeout--;
407 if (Timeout == 0) {
408 return -1;
409 }
410 }
411
412 return size;
413 }
414
415 int i2c_slave_write(i2c_t *obj, const char *data, int length)
416 {
417 uint32_t Timeout;
418 int size = 0;
419
420 I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
421
422 while (length > 0) {
423 /* Wait until TXE flag is set */
424 Timeout = FLAG_TIMEOUT;
425 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
426 Timeout--;
427 if (Timeout == 0) {
428 return -1;
429 }
430 }
431
432
433 /* Write data to DR */
434 I2cHandle.Instance->DR = (*data++);
435 length--;
436 size++;
437
438 if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
439 /* Write data to DR */
440 I2cHandle.Instance->DR = (*data++);
441 length--;
442 size++;
443 }
444 }
445
446 /* Wait until AF flag is set */
447 Timeout = FLAG_TIMEOUT;
448 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
449 Timeout--;
450 if (Timeout == 0) {
451 return -1;
452 }
453 }
454
455
456 /* Clear AF flag */
457 __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
458
459
460 /* Wait until BUSY flag is reset */
461 Timeout = FLAG_TIMEOUT;
462 while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
463 Timeout--;
464 if (Timeout == 0) {
465 return -1;
466 }
467 }
468
469 I2cHandle.State = HAL_I2C_STATE_READY;
470
471 /* Process Unlocked */
472 __HAL_UNLOCK(&I2cHandle);
473
474 return size;
475 }
476
477
478 #endif // DEVICE_I2CSLAVE
479
480 #endif // DEVICE_I2C
Imprint / Impressum