]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F1/i2c_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32F1 / 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 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
48 {
49     static int i2c1_inited = 0;
50     static int i2c2_inited = 0;
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     // Check if I2C peripherals are already configured
60     if ((obj->i2c == I2C_1) && i2c1_inited) return;
61     if ((obj->i2c == I2C_2) && i2c2_inited) return;
62
63     // Set I2C clock
64     if (obj->i2c == I2C_1) {
65         i2c1_inited = 1;
66         __I2C1_CLK_ENABLE();
67     }
68
69     if (obj->i2c == I2C_2) {
70         i2c2_inited = 1;
71         __I2C2_CLK_ENABLE();
72     }
73
74     // Configure I2C pins
75     pinmap_pinout(sda, PinMap_I2C_SDA);
76     pinmap_pinout(scl, PinMap_I2C_SCL);
77     pin_mode(sda, OpenDrain);
78     pin_mode(scl, OpenDrain);
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.ClockSpeed       = hz;
102     I2cHandle.Init.DutyCycle        = I2C_DUTYCYCLE_2;
103     I2cHandle.Init.OwnAddress1      = 0;
104     I2cHandle.Init.AddressingMode   = I2C_ADDRESSINGMODE_7BIT;
105     I2cHandle.Init.DualAddressMode  = I2C_DUALADDRESS_DISABLED;
106     I2cHandle.Init.OwnAddress2      = 0;
107     I2cHandle.Init.GeneralCallMode  = I2C_GENERALCALL_DISABLED;
108     I2cHandle.Init.NoStretchMode    = I2C_NOSTRETCH_DISABLED;
109     HAL_I2C_Init(&I2cHandle);
110
111     if (obj->slave) {
112         // Enable Address Acknowledge
113         I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
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     // Generate start condition
160     i2c_start(obj);
161
162     // Send address for read
163     i2c->DR = __HAL_I2C_7BIT_ADD_READ(address);
164
165     // Wait address is acknowledged
166     timeout = FLAG_TIMEOUT;
167     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
168         timeout--;
169         if (timeout == 0) {
170             return -1;
171         }
172     }
173     __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
174
175     // Read all bytes except last one
176     for (count = 0; count < (length - 1); count++) {
177         value = i2c_byte_read(obj, 0);
178         data[count] = (char)value;
179     }
180
181     // If not repeated start, send stop.
182     // Warning: must be done BEFORE the data is read.
183     if (stop) {
184         i2c_stop(obj);
185     }
186
187     // Read the last byte
188     value = i2c_byte_read(obj, 1);
189     data[count] = (char)value;
190
191     return length;
192 }
193
194 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
195 {
196     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
197     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
198     int timeout;
199     int count;
200
201     // Generate start condition
202     i2c_start(obj);
203
204     // Send address for write
205     i2c->DR = __HAL_I2C_7BIT_ADD_WRITE(address);
206
207     // Wait address is acknowledged
208     timeout = FLAG_TIMEOUT;
209     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
210         timeout--;
211         if (timeout == 0) {
212             return -1;
213         }
214     }
215     __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
216
217     // Write all bytes
218     for (count = 0; count < length; count++) {
219         if (i2c_byte_write(obj, data[count]) != 1) {
220             i2c_stop(obj);
221             return -1;
222         }
223     }
224
225     // If not repeated start, send stop.
226     if (stop) {
227         i2c_stop(obj);
228     }
229
230     return count;
231 }
232
233 int i2c_byte_read(i2c_t *obj, int last)
234 {
235     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
236     int timeout;
237
238     if (last) {
239         // Don't acknowledge the last byte
240         i2c->CR1 &= ~I2C_CR1_ACK;
241     } else {
242         // Acknowledge the byte
243         i2c->CR1 |= I2C_CR1_ACK;
244     }
245
246     // Wait until the byte is received
247     timeout = FLAG_TIMEOUT;
248     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
249         if ((timeout--) == 0) {
250             return -1;
251         }
252     }
253
254     return (int)i2c->DR;
255 }
256
257 int i2c_byte_write(i2c_t *obj, int data)
258 {
259     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
260     int timeout;
261
262     i2c->DR = (uint8_t)data;
263
264     // Wait until the byte is transmitted
265     timeout = FLAG_TIMEOUT;
266     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
267             (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
268         if ((timeout--) == 0) {
269             return 0;
270         }
271     }
272
273     return 1;
274 }
275
276 void i2c_reset(i2c_t *obj)
277 {
278     int timeout;
279
280     // Wait before reset
281     timeout = LONG_TIMEOUT;
282     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
283
284     if (obj->i2c == I2C_1) {
285         __I2C1_FORCE_RESET();
286         __I2C1_RELEASE_RESET();
287     }
288
289     if (obj->i2c == I2C_2) {
290         __I2C2_FORCE_RESET();
291         __I2C2_RELEASE_RESET();
292     }
293 }
294
295 #if DEVICE_I2CSLAVE
296
297 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
298 {
299     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
300     uint16_t tmpreg = 0;
301
302     // Get the old register value
303     tmpreg = i2c->OAR1;
304     // Reset address bits
305     tmpreg &= 0xFC00;
306     // Set new address
307     tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
308     // Store the new register value
309     i2c->OAR1 = tmpreg;
310 }
311
312 void i2c_slave_mode(i2c_t *obj, int enable_slave)
313 {
314     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
315     if (enable_slave) {
316         obj->slave = 1;
317         /* Enable Address Acknowledge */
318         I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
319     }
320 }
321
322 // See I2CSlave.h
323 #define NoData         0 // the slave has not been addressed
324 #define ReadAddressed  1 // the master has requested a read from this slave (slave = transmitter)
325 #define WriteGeneral   2 // the master is writing to all slave
326 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
327
328 int i2c_slave_receive(i2c_t *obj)
329 {
330     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
331     int retValue = NoData;
332
333     if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
334         if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
335             if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1) {
336                 retValue = ReadAddressed;
337             } else {
338                 retValue = WriteAddressed;
339             }
340             __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
341         }
342     }
343
344     return (retValue);
345 }
346
347 int i2c_slave_read(i2c_t *obj, char *data, int length)
348 {
349     uint32_t Timeout;
350     int size = 0;
351
352     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
353
354     while (length > 0) {
355         // Wait until RXNE flag is set
356         // Wait until the byte is received
357         Timeout = FLAG_TIMEOUT;
358         while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
359             Timeout--;
360             if (Timeout == 0) {
361                 return -1;
362             }
363         }
364
365         // Read data
366         (*data++) = I2cHandle.Instance->DR;
367         length--;
368         size++;
369
370         if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
371             // Read data
372             (*data++) = I2cHandle.Instance->DR;
373             length--;
374             size++;
375         }
376     }
377
378     // Wait until STOP flag is set
379     Timeout = FLAG_TIMEOUT;
380     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
381         Timeout--;
382         if (Timeout == 0) {
383             return -1;
384         }
385     }
386
387     // Clear STOP flag
388     __HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
389
390     // Wait until BUSY flag is reset
391     Timeout = FLAG_TIMEOUT;
392     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
393         Timeout--;
394         if (Timeout == 0) {
395             return -1;
396         }
397     }
398
399     return size;
400 }
401
402 int i2c_slave_write(i2c_t *obj, const char *data, int length)
403 {
404     uint32_t Timeout;
405     int size = 0;
406
407     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
408
409     while (length > 0) {
410         // Wait until TXE flag is set
411         Timeout = FLAG_TIMEOUT;
412         while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
413             Timeout--;
414             if (Timeout == 0) {
415                 return -1;
416             }
417         }
418
419         // Write data
420         I2cHandle.Instance->DR = (*data++);
421         length--;
422         size++;
423
424         if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
425             // Write data to DR
426             I2cHandle.Instance->DR = (*data++);
427             length--;
428             size++;
429         }
430     }
431
432     // Wait until AF flag is set
433     Timeout = FLAG_TIMEOUT;
434     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
435         Timeout--;
436         if (Timeout == 0) {
437             return -1;
438         }
439     }
440
441     // Clear AF flag
442     __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
443
444     // Wait until BUSY flag is reset
445     Timeout = FLAG_TIMEOUT;
446     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
447         Timeout--;
448         if (Timeout == 0) {
449             return -1;
450         }
451     }
452
453     return size;
454 }
455
456
457 #endif // DEVICE_I2CSLAVE
458
459 #endif // DEVICE_I2C