]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F3XX/i2c_api.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32F3XX / 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
38 /* Timeout values for flags and events waiting loops. These timeouts are
39    not based on accurate values, they just guarantee that the application will
40    not remain stuck if the I2C communication is corrupted. */
41 #define FLAG_TIMEOUT ((int)0x1000)
42 #define LONG_TIMEOUT ((int)0x8000)
43
44 static const PinMap PinMap_I2C_SDA[] = {
45     {PA_10, I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
46     {PA_14, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
47     {PB_5,  I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_8)},
48     {PB_7,  I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
49     {PB_9,  I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
50     {PC_9,  I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_3)},
51     {PF_0,  I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
52     {NC,    NC,    0}
53 };
54
55 static const PinMap PinMap_I2C_SCL[] = {
56     {PA_8,  I2C_3, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_3)},
57     {PA_9,  I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
58     {PA_15, I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
59     {PB_6,  I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
60     {PB_8,  I2C_1, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
61     {PF_1,  I2C_2, STM_PIN_DATA(GPIO_Mode_AF, GPIO_OType_OD, GPIO_PuPd_UP, GPIO_AF_4)},
62     {NC,    NC,    0}
63 };
64
65 void i2c_init(i2c_t *obj, PinName sda, PinName scl) {
66     // Determine the I2C to use
67     I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
68     I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
69
70     obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
71     MBED_ASSERT(obj->i2c != (I2CName)NC);
72
73     // Enable I2C clock
74     if (obj->i2c == I2C_1) {
75         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
76     }
77     if (obj->i2c == I2C_2) {
78         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
79     }
80     if (obj->i2c == I2C_3) {
81         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
82     }
83
84     // Configure I2C pins
85     pinmap_pinout(scl, PinMap_I2C_SCL);
86     pin_mode(scl, OpenDrain);
87     pinmap_pinout(sda, PinMap_I2C_SDA);
88     pin_mode(sda, OpenDrain);
89
90     // Reset to clear pending flags if any
91     i2c_reset(obj);
92
93     // I2C configuration
94     i2c_frequency(obj, 100000); // 100 kHz per default
95 }
96
97 void i2c_frequency(i2c_t *obj, int hz) {
98     MBED_ASSERT((hz == 100000) || (hz == 200000) || (hz == 400000) || (hz == 1000000));
99     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
100     I2C_InitTypeDef I2C_InitStructure;
101     uint32_t tim;
102
103     // Disable the Fast Mode Plus capability
104     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // Enable SYSCFG clock
105     SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, DISABLE);
106     SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, DISABLE);
107
108     /*
109        Values calculated with I2C_Timing_Configuration_V1.0.1.xls file (see AN4235)
110        * Standard mode (up to 100 kHz)
111        * Fast Mode (up to 400 kHz)
112        * Fast Mode Plus (up to 1 MHz)
113        Below values obtained with:
114        - I2C clock source = 8 MHz (HSI clock per default)
115        - Analog filter delay = ON
116        - Digital filter coefficient = 0
117        - Rise time = 100 ns
118        - Fall time = 10ns
119     */
120     switch (hz) {
121         case 100000:
122             tim = 0x00201D2B; // Standard mode
123             break;
124         case 200000:
125             tim = 0x0010021E; // Fast Mode
126             break;
127         case 400000:
128             tim = 0x0010020A; // Fast Mode
129             break;
130         case 1000000:
131             tim = 0x00100001; // Fast Mode Plus
132             // Enable the Fast Mode Plus capability
133             if (obj->i2c == I2C_1) {
134                 SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C1, ENABLE);
135             }
136             if (obj->i2c == I2C_2) {
137                 SYSCFG_I2CFastModePlusConfig(SYSCFG_I2CFastModePlus_I2C2, ENABLE);
138             }
139             break;
140         default:
141             break;
142     }
143
144     // I2C configuration
145     I2C_DeInit(i2c);
146     I2C_InitStructure.I2C_Mode                = I2C_Mode_I2C;
147     I2C_InitStructure.I2C_AnalogFilter        = I2C_AnalogFilter_Enable;
148     I2C_InitStructure.I2C_DigitalFilter       = 0x00;
149     I2C_InitStructure.I2C_OwnAddress1         = 0x00;
150     I2C_InitStructure.I2C_Ack                 = I2C_Ack_Enable;
151     I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
152     I2C_InitStructure.I2C_Timing              = tim;
153     I2C_Init(i2c, &I2C_InitStructure);
154
155     I2C_Cmd(i2c, ENABLE);
156 }
157
158 inline int i2c_start(i2c_t *obj) {
159     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
160     int timeout;
161
162     // Test BUSY Flag
163     timeout = LONG_TIMEOUT;
164     while (I2C_GetFlagStatus(i2c, I2C_ISR_BUSY) != RESET) {
165         timeout--;
166         if (timeout == 0) {
167             return 0;
168         }
169     }
170
171     I2C_GenerateSTART(i2c, ENABLE);
172
173     return 0;
174 }
175
176 inline int i2c_stop(i2c_t *obj) {
177     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
178
179     I2C_GenerateSTOP(i2c, ENABLE);
180
181     return 0;
182 }
183
184 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
185     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
186     int count;
187     int value;
188
189     if (length == 0) return 0;
190
191     // Configure slave address, nbytes, reload, end mode and start or stop generation
192     I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
193
194     // Read all bytes
195     for (count = 0; count < length; count++) {
196         value = i2c_byte_read(obj, 0);
197         data[count] = (char)value;
198     }
199
200     return length;
201 }
202
203 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop) {
204     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
205     //int timeout;
206     int count;
207
208     if (length == 0) return 0;
209
210     // [TODO] The stop is always sent even with I2C_SoftEnd_Mode. To be corrected.
211
212     // Configure slave address, nbytes, reload, end mode and start or stop generation
213     //if (stop) {
214     I2C_TransferHandling(i2c, address, length, I2C_AutoEnd_Mode, I2C_Generate_Start_Write);
215     //}
216     //else {
217     //    I2C_TransferHandling(i2c, address, length, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
218     //}
219
220     // Write all bytes
221     for (count = 0; count < length; count++) {
222         if (i2c_byte_write(obj, data[count]) != 1) {
223             i2c_stop(obj);
224             return 0;
225         }
226     }
227
228     /*
229     if (stop) {
230         // Wait until STOPF flag is set
231         timeout = LONG_TIMEOUT;
232         while (I2C_GetFlagStatus(i2c, I2C_ISR_STOPF) == RESET) {
233             timeout--;
234             if (timeout == 0) {
235                 return 0;
236             }
237         }
238         // Clear STOPF flag
239         I2C_ClearFlag(i2c, I2C_ICR_STOPCF);
240     }
241     */
242
243     return count;
244 }
245
246 int i2c_byte_read(i2c_t *obj, int last) {
247     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
248     uint8_t data;
249     int timeout;
250
251     // Wait until the byte is received
252     timeout = FLAG_TIMEOUT;
253     while (I2C_GetFlagStatus(i2c, I2C_ISR_RXNE) == RESET) {
254         timeout--;
255         if (timeout == 0) {
256             return 0;
257         }
258     }
259
260     data = I2C_ReceiveData(i2c);
261
262     return (int)data;
263 }
264
265 int i2c_byte_write(i2c_t *obj, int data) {
266     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
267     int timeout;
268
269     // Wait until the previous byte is transmitted
270     timeout = FLAG_TIMEOUT;
271     while (I2C_GetFlagStatus(i2c, I2C_ISR_TXIS) == RESET) {
272         timeout--;
273         if (timeout == 0) {
274             return 0;
275         }
276     }
277
278     I2C_SendData(i2c, (uint8_t)data);
279
280     return 1;
281 }
282
283 void i2c_reset(i2c_t *obj) {
284     if (obj->i2c == I2C_1) {
285         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
286         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
287     }
288     if (obj->i2c == I2C_2) {
289         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
290         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
291     }
292     if (obj->i2c == I2C_3) {
293         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, ENABLE);
294         RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C3, DISABLE);
295     }
296 }
297
298 #if DEVICE_I2CSLAVE
299
300 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask) {
301     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
302     uint16_t tmpreg;
303
304     // Get the old register value
305     tmpreg = i2c->OAR1;
306     // Reset address bits
307     tmpreg &= 0xFC00;
308     // Set new address
309     tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
310     // Store the new register value
311     i2c->OAR1 = tmpreg;
312 }
313
314 void i2c_slave_mode(i2c_t *obj, int enable_slave) {
315     // Nothing to do
316 }
317
318 // See I2CSlave.h
319 #define NoData         0 // the slave has not been addressed
320 #define ReadAddressed  1 // the master has requested a read from this slave (slave = transmitter)
321 #define WriteGeneral   2 // the master is writing to all slave
322 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
323
324 int i2c_slave_receive(i2c_t *obj) {
325     // TO BE DONE
326     return (0);
327 }
328
329 int i2c_slave_read(i2c_t *obj, char *data, int length) {
330     int count = 0;
331
332     // Read all bytes
333     for (count = 0; count < length; count++) {
334         data[count] = i2c_byte_read(obj, 0);
335     }
336
337     return count;
338 }
339
340 int i2c_slave_write(i2c_t *obj, const char *data, int length) {
341     int count = 0;
342
343     // Write all bytes
344     for (count = 0; count < length; count++) {
345         i2c_byte_write(obj, data[count]);
346     }
347
348     return count;
349 }
350
351
352 #endif // DEVICE_I2CSLAVE
353
354 #endif // DEVICE_I2C