]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_STM/TARGET_STM32F4/i2c_api.c
Add a qwerty layer
[max/tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_STM / TARGET_STM32F4 / 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 int i2c3_inited = 0;
50
51 void i2c_init(i2c_t *obj, PinName sda, PinName scl)
52 {
53     // Determine the I2C to use
54     I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
55     I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
56
57     obj->i2c = (I2CName)pinmap_merge(i2c_sda, i2c_scl);
58     MBED_ASSERT(obj->i2c != (I2CName)NC);
59
60     // Enable I2C1 clock and pinout if not done
61     if ((obj->i2c == I2C_1) && !i2c1_inited) {
62         i2c1_inited = 1;
63         __I2C1_CLK_ENABLE();
64         // Configure I2C pins
65         pinmap_pinout(sda, PinMap_I2C_SDA);
66         pinmap_pinout(scl, PinMap_I2C_SCL);
67         pin_mode(sda, OpenDrain);
68         pin_mode(scl, OpenDrain);
69     }
70     // Enable I2C2 clock and pinout if not done
71     if ((obj->i2c == I2C_2) && !i2c2_inited) {
72         i2c2_inited = 1;
73         __I2C2_CLK_ENABLE();
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     // Enable I2C3 clock and pinout if not done
81     if ((obj->i2c == I2C_3) && !i2c3_inited) {
82         i2c3_inited = 1;
83         __I2C3_CLK_ENABLE();
84         // Configure I2C pins
85         pinmap_pinout(sda, PinMap_I2C_SDA);
86         pinmap_pinout(scl, PinMap_I2C_SCL);
87         pin_mode(sda, OpenDrain);
88         pin_mode(scl, OpenDrain);
89     }
90
91     // Reset to clear pending flags if any
92     i2c_reset(obj);
93
94     // I2C configuration
95     i2c_frequency(obj, 100000); // 100 kHz per default
96
97     // I2C master by default
98     obj->slave = 0;
99 }
100
101 void i2c_frequency(i2c_t *obj, int hz)
102 {
103     MBED_ASSERT((hz != 0) && (hz <= 400000));
104     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
105     int timeout;
106
107     // wait before init
108     timeout = LONG_TIMEOUT;
109     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
110
111     // I2C configuration
112     I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
113     I2cHandle.Init.ClockSpeed      = hz;
114     I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
115     I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
116     I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
117     I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
118     I2cHandle.Init.OwnAddress1     = 0;
119     I2cHandle.Init.OwnAddress2     = 0;
120     HAL_I2C_Init(&I2cHandle);
121     if (obj->slave) {
122         /* Enable Address Acknowledge */
123         I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
124     }
125
126 }
127
128 inline int i2c_start(i2c_t *obj)
129 {
130     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
131     int timeout;
132
133     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
134
135     // Clear Acknowledge failure flag
136     __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
137
138     // Generate the START condition
139     i2c->CR1 |= I2C_CR1_START;
140
141     // Wait the START condition has been correctly sent
142     timeout = FLAG_TIMEOUT;
143     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
144         if ((timeout--) == 0) {
145             return 1;
146         }
147     }
148
149     return 0;
150 }
151
152 inline int i2c_stop(i2c_t *obj)
153 {
154     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
155
156     // Generate the STOP condition
157     i2c->CR1 |= I2C_CR1_STOP;
158
159     return 0;
160 }
161
162 int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
163 {
164     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
165     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
166     int timeout;
167     int count;
168     int value;
169
170     i2c_start(obj);
171
172     // Wait until SB flag is set
173     timeout = FLAG_TIMEOUT;
174     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
175         timeout--;
176         if (timeout == 0) {
177             return -1;
178         }
179     }
180
181     i2c->DR = __HAL_I2C_7BIT_ADD_READ(address);
182
183
184     // Wait address is acknowledged
185     timeout = FLAG_TIMEOUT;
186     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
187         timeout--;
188         if (timeout == 0) {
189             return -1;
190         }
191     }
192     __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
193
194     // Read all bytes except last one
195     for (count = 0; count < (length - 1); count++) {
196         value = i2c_byte_read(obj, 0);
197         data[count] = (char)value;
198     }
199
200     // If not repeated start, send stop.
201     // Warning: must be done BEFORE the data is read.
202     if (stop) {
203         i2c_stop(obj);
204     }
205
206     // Read the last byte
207     value = i2c_byte_read(obj, 1);
208     data[count] = (char)value;
209
210     return length;
211 }
212
213 int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
214 {
215     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
216     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
217     int timeout;
218     int count;
219
220     i2c_start(obj);
221
222     // Wait until SB flag is set
223     timeout = FLAG_TIMEOUT;
224     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_SB) == RESET) {
225         timeout--;
226         if (timeout == 0) {
227             return -1;
228         }
229     }
230
231     i2c->DR = __HAL_I2C_7BIT_ADD_WRITE(address);
232
233
234     // Wait address is acknowledged
235     timeout = FLAG_TIMEOUT;
236     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == RESET) {
237         timeout--;
238         if (timeout == 0) {
239             return -1;
240         }
241     }
242     __HAL_I2C_CLEAR_ADDRFLAG(&I2cHandle);
243
244     for (count = 0; count < length; count++) {
245         if (i2c_byte_write(obj, data[count]) != 1) {
246             i2c_stop(obj);
247             return -1;
248         }
249     }
250
251     // If not repeated start, send stop.
252     if (stop) {
253         i2c_stop(obj);
254     }
255
256     return count;
257 }
258
259 int i2c_byte_read(i2c_t *obj, int last)
260 {
261     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
262     int timeout;
263
264     if (last) {
265         // Don't acknowledge the last byte
266         i2c->CR1 &= ~I2C_CR1_ACK;
267     } else {
268         // Acknowledge the byte
269         i2c->CR1 |= I2C_CR1_ACK;
270     }
271
272     // Wait until the byte is received
273     timeout = FLAG_TIMEOUT;
274     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
275         if ((timeout--) == 0) {
276             return -1;
277         }
278     }
279
280     return (int)i2c->DR;
281 }
282
283 int i2c_byte_write(i2c_t *obj, int data)
284 {
285     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
286     int timeout;
287
288     i2c->DR = (uint8_t)data;
289
290     // Wait until the byte is transmitted
291     timeout = FLAG_TIMEOUT;
292     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) &&
293             (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == RESET)) {
294         if ((timeout--) == 0) {
295             return 0;
296         }
297     }
298
299     return 1;
300 }
301
302 void i2c_reset(i2c_t *obj)
303 {
304     int timeout;
305
306     // wait before reset
307     timeout = LONG_TIMEOUT;
308     while ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY)) && (timeout-- != 0));
309
310     if (obj->i2c == I2C_1) {
311         __I2C1_FORCE_RESET();
312         __I2C1_RELEASE_RESET();
313     }
314     if (obj->i2c == I2C_2) {
315         __I2C2_FORCE_RESET();
316         __I2C2_RELEASE_RESET();
317     }
318     if (obj->i2c == I2C_3) {
319         __I2C3_FORCE_RESET();
320         __I2C3_RELEASE_RESET();
321     }
322 }
323
324 #if DEVICE_I2CSLAVE
325
326 void i2c_slave_address(i2c_t *obj, int idx, uint32_t address, uint32_t mask)
327 {
328     I2C_TypeDef *i2c = (I2C_TypeDef *)(obj->i2c);
329     uint16_t tmpreg = 0;
330
331     // Get the old register value
332     tmpreg = i2c->OAR1;
333     // Reset address bits
334     tmpreg &= 0xFC00;
335     // Set new address
336     tmpreg |= (uint16_t)((uint16_t)address & (uint16_t)0x00FE); // 7-bits
337     // Store the new register value
338     i2c->OAR1 = tmpreg;
339 }
340
341 void i2c_slave_mode(i2c_t *obj, int enable_slave)
342 {
343     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
344     if (enable_slave) {
345         obj->slave = 1;
346         /* Enable Address Acknowledge */
347         I2cHandle.Instance->CR1 |= I2C_CR1_ACK;
348     }
349 }
350
351 // See I2CSlave.h
352 #define NoData         0 // the slave has not been addressed
353 #define ReadAddressed  1 // the master has requested a read from this slave (slave = transmitter)
354 #define WriteGeneral   2 // the master is writing to all slave
355 #define WriteAddressed 3 // the master is writing to this slave (slave = receiver)
356
357 int i2c_slave_receive(i2c_t *obj)
358 {
359     int retValue = NoData;
360
361     if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == 1) {
362         if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_ADDR) == 1) {
363             if (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TRA) == 1)
364                 retValue = ReadAddressed;
365             else
366                 retValue = WriteAddressed;
367
368             __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_ADDR);
369         }
370     }
371
372     return (retValue);
373 }
374
375 int i2c_slave_read(i2c_t *obj, char *data, int length)
376 {
377     uint32_t Timeout;
378     int size = 0;
379
380     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
381
382     while (length > 0) {
383         /* Wait until RXNE flag is set */
384         // Wait until the byte is received
385         Timeout = FLAG_TIMEOUT;
386         while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_RXNE) == RESET) {
387             Timeout--;
388             if (Timeout == 0) {
389                 return -1;
390             }
391         }
392
393         /* Read data from DR */
394         (*data++) = I2cHandle.Instance->DR;
395         length--;
396         size++;
397
398         if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
399             /* Read data from DR */
400             (*data++) = I2cHandle.Instance->DR;
401             length--;
402             size++;
403         }
404     }
405
406     /* Wait until STOP flag is set */
407     Timeout = FLAG_TIMEOUT;
408     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_STOPF) == RESET) {
409         Timeout--;
410         if (Timeout == 0) {
411             return -1;
412         }
413     }
414
415     /* Clear STOP flag */
416     __HAL_I2C_CLEAR_STOPFLAG(&I2cHandle);
417
418     /* Wait until BUSY flag is reset */
419     Timeout = FLAG_TIMEOUT;
420     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
421         Timeout--;
422         if (Timeout == 0) {
423             return -1;
424         }
425     }
426
427     return size;
428 }
429
430 int i2c_slave_write(i2c_t *obj, const char *data, int length)
431 {
432     uint32_t Timeout;
433     int size = 0;
434
435     I2cHandle.Instance = (I2C_TypeDef *)(obj->i2c);
436
437     while (length > 0) {
438         /* Wait until TXE flag is set */
439         Timeout = FLAG_TIMEOUT;
440         while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_TXE) == RESET) {
441             Timeout--;
442             if (Timeout == 0) {
443                 return -1;
444             }
445         }
446
447
448         /* Write data to DR */
449         I2cHandle.Instance->DR = (*data++);
450         length--;
451         size++;
452
453         if ((__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BTF) == SET) && (length != 0)) {
454             /* Write data to DR */
455             I2cHandle.Instance->DR = (*data++);
456             length--;
457             size++;
458         }
459     }
460
461     /* Wait until AF flag is set */
462     Timeout = FLAG_TIMEOUT;
463     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_AF) == RESET) {
464         Timeout--;
465         if (Timeout == 0) {
466             return -1;
467         }
468     }
469
470
471     /* Clear AF flag */
472     __HAL_I2C_CLEAR_FLAG(&I2cHandle, I2C_FLAG_AF);
473
474
475     /* Wait until BUSY flag is reset */
476     Timeout = FLAG_TIMEOUT;
477     while (__HAL_I2C_GET_FLAG(&I2cHandle, I2C_FLAG_BUSY) == SET) {
478         Timeout--;
479         if (Timeout == 0) {
480             return -1;
481         }
482     }
483
484     I2cHandle.State = HAL_I2C_STATE_READY;
485
486     /* Process Unlocked */
487     __HAL_UNLOCK(&I2cHandle);
488
489     return size;
490 }
491
492
493 #endif // DEVICE_I2CSLAVE
494
495 #endif // DEVICE_I2C