aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Challis <git@zvecr.com>2019-07-16 09:30:53 +0100
committerskullydazed <skullydazed@users.noreply.github.com>2019-07-16 01:30:53 -0700
commit4e375aa1f536e979a587534df0b6951fa39e8a30 (patch)
treeb858c1cecf7af98092f9abc02aa5f9b4cdf9bd0a
parentf859375284f5a27f5b4f8cbe654e305ca3face17 (diff)
downloadqmk_firmware-4e375aa1f536e979a587534df0b6951fa39e8a30.tar.gz
qmk_firmware-4e375aa1f536e979a587534df0b6951fa39e8a30.zip
Add ARM I2Cv1 support to i2c_master (#6262)
* Add ARM I2Cv1 support to i2c_master * Add I2Cv1 docs
-rw-r--r--docs/i2c_driver.md20
-rw-r--r--drivers/arm/i2c_master.c11
-rw-r--r--drivers/arm/i2c_master.h64
3 files changed, 70 insertions, 25 deletions
diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md
index 4a47a92b1..317307e1b 100644
--- a/docs/i2c_driver.md
+++ b/docs/i2c_driver.md
@@ -73,7 +73,22 @@ STM32 MCUs allows a variety of pins to be configured as I2C pins depending on th
73| `I2C1_SDA` | The pin number for the SDA pin (0-9) | `7` | 73| `I2C1_SDA` | The pin number for the SDA pin (0-9) | `7` |
74| `I2C1_BANK` (deprecated) | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`), superceded by `I2C1_SCL_BANK`, `I2C1_SDA_BANK` | `GPIOB` | 74| `I2C1_BANK` (deprecated) | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`), superceded by `I2C1_SCL_BANK`, `I2C1_SDA_BANK` | `GPIOB` |
75 75
76STM32 MCUs allow for different timing parameters when configuring I2C. These can be modified using the following parameters, using https://www.st.com/en/embedded-software/stsw-stm32126.html as a reference: 76The ChibiOS I2C driver configuration depends on STM32 MCU:
77
78 STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx and STM32L1xx use I2Cv1;
79 STM32F0xx, STM32F3xx, STM32F7xx and STM32L4xx use I2Cv2;
80
81#### I2Cv1
82STM32 MCUs allow for different clock and duty parameters when configuring I2Cv1. These can be modified using the following parameters, using <https://www.playembedded.org/blog/stm32-i2c-chibios/#I2Cv1_configuration_structure> as a reference:
83
84| Variable | Default |
85|--------------------|------------------|
86| `I2C1_OPMODE` | `OPMODE_I2C` |
87| `I2C1_CLOCK_SPEED` | `100000` |
88| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` |
89
90#### I2Cv2
91STM32 MCUs allow for different timing parameters when configuring I2Cv2. These can be modified using the following parameters, using <https://www.st.com/en/embedded-software/stsw-stm32126.html> as a reference:
77 92
78| Variable | Default | 93| Variable | Default |
79|-----------------------|---------| 94|-----------------------|---------|
@@ -83,13 +98,14 @@ STM32 MCUs allow for different timing parameters when configuring I2C. These can
83| `I2C1_TIMINGR_SCLH` | `15U` | 98| `I2C1_TIMINGR_SCLH` | `15U` |
84| `I2C1_TIMINGR_SCLL` | `21U` | 99| `I2C1_TIMINGR_SCLL` | `21U` |
85 100
86STM32 MCUs allow for different "alternate function" modes when configuring GPIO pins. These are required to switch the pins used to I2C mode. See the respective datasheet for the appropriate values for your MCU. 101STM32 MCUs allow for different "alternate function" modes when configuring GPIO pins. These are required to switch the pins used to I2Cv2 mode. See the respective datasheet for the appropriate values for your MCU.
87 102
88| Variable | Default | 103| Variable | Default |
89|---------------------|---------| 104|---------------------|---------|
90| `I2C1_SCL_PAL_MODE` | `4` | 105| `I2C1_SCL_PAL_MODE` | `4` |
91| `I2C1_SDA_PAL_MODE` | `4` | 106| `I2C1_SDA_PAL_MODE` | `4` |
92 107
108#### Other
93You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function: 109You can also overload the `void i2c_init(void)` function, which has a weak attribute. If you do this the configuration variables above will not be used. Please consult the datasheet of your MCU for the available GPIO configurations. The following is an example initialization function:
94 110
95```C 111```C
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c
index 5814375f3..9b4a752b1 100644
--- a/drivers/arm/i2c_master.c
+++ b/drivers/arm/i2c_master.c
@@ -33,11 +33,17 @@
33static uint8_t i2c_address; 33static uint8_t i2c_address;
34 34
35static const I2CConfig i2cconfig = { 35static const I2CConfig i2cconfig = {
36#ifdef USE_I2CV1
37 I2C1_OPMODE,
38 I2C1_CLOCK_SPEED,
39 I2C1_DUTY_CYCLE,
40#else
36 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | 41 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) |
37 STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | 42 STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) |
38 STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), 43 STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL),
39 0, 44 0,
40 0 45 0
46#endif
41}; 47};
42 48
43static i2c_status_t chibios_to_qmk(const msg_t* status) { 49static i2c_status_t chibios_to_qmk(const msg_t* status) {
@@ -61,8 +67,13 @@ void i2c_init(void)
61 67
62 chThdSleepMilliseconds(10); 68 chThdSleepMilliseconds(10);
63 69
70#ifdef USE_I2CV1
71 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
72 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
73#else
64 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); 74 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
65 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); 75 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
76#endif
66 77
67 //i2cInit(); //This is invoked by halInit() so no need to redo it. 78 //i2cInit(); //This is invoked by halInit() so no need to redo it.
68} 79}
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h
index 1bb74c800..2f40d4985 100644
--- a/drivers/arm/i2c_master.h
+++ b/drivers/arm/i2c_master.h
@@ -22,10 +22,16 @@
22 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that 22 * Please ensure that HAL_USE_I2C is TRUE in the halconf.h file and that
23 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file. 23 * STM32_I2C_USE_I2C1 is TRUE in the mcuconf.h file.
24 */ 24 */
25#pragma once
25 26
26#include "ch.h" 27#include "ch.h"
27#include <hal.h> 28#include <hal.h>
28 29
30
31#if defined(STM32F1XX) || defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32L0xx) || defined(STM32L1xx)
32 #define USE_I2CV1
33#endif
34
29#ifdef I2C1_BANK 35#ifdef I2C1_BANK
30 #define I2C1_SCL_BANK I2C1_BANK 36 #define I2C1_SCL_BANK I2C1_BANK
31 #define I2C1_SDA_BANK I2C1_BANK 37 #define I2C1_SDA_BANK I2C1_BANK
@@ -46,30 +52,42 @@
46 #define I2C1_SDA 7 52 #define I2C1_SDA 7
47#endif 53#endif
48 54
49// The default PAL alternate modes are used to signal that the pins are used for I2C 55#ifdef USE_I2CV1
50#ifndef I2C1_SCL_PAL_MODE 56 #ifndef I2C1_OPMODE
51 #define I2C1_SCL_PAL_MODE 4 57 #define I2C1_OPMODE OPMODE_I2C
52#endif 58 #endif
53#ifndef I2C1_SDA_PAL_MODE 59 #ifndef I2C1_CLOCK_SPEED
54 #define I2C1_SDA_PAL_MODE 4 60 #define I2C1_CLOCK_SPEED 100000 /* 400000 */
55#endif 61 #endif
62 #ifndef I2C1_DUTY_CYCLE
63 #define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */
64 #endif
65#else
66 // The default PAL alternate modes are used to signal that the pins are used for I2C
67 #ifndef I2C1_SCL_PAL_MODE
68 #define I2C1_SCL_PAL_MODE 4
69 #endif
70 #ifndef I2C1_SDA_PAL_MODE
71 #define I2C1_SDA_PAL_MODE 4
72 #endif
56 73
57// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock 74 // The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
58// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html 75 // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
59#ifndef I2C1_TIMINGR_PRESC 76 #ifndef I2C1_TIMINGR_PRESC
60 #define I2C1_TIMINGR_PRESC 15U 77 #define I2C1_TIMINGR_PRESC 15U
61#endif 78 #endif
62#ifndef I2C1_TIMINGR_SCLDEL 79 #ifndef I2C1_TIMINGR_SCLDEL
63 #define I2C1_TIMINGR_SCLDEL 4U 80 #define I2C1_TIMINGR_SCLDEL 4U
64#endif 81 #endif
65#ifndef I2C1_TIMINGR_SDADEL 82 #ifndef I2C1_TIMINGR_SDADEL
66 #define I2C1_TIMINGR_SDADEL 2U 83 #define I2C1_TIMINGR_SDADEL 2U
67#endif 84 #endif
68#ifndef I2C1_TIMINGR_SCLH 85 #ifndef I2C1_TIMINGR_SCLH
69 #define I2C1_TIMINGR_SCLH 15U 86 #define I2C1_TIMINGR_SCLH 15U
70#endif 87 #endif
71#ifndef I2C1_TIMINGR_SCLL 88 #ifndef I2C1_TIMINGR_SCLL
72 #define I2C1_TIMINGR_SCLL 21U 89 #define I2C1_TIMINGR_SCLL 21U
90 #endif
73#endif 91#endif
74 92
75#ifndef I2C_DRIVER 93#ifndef I2C_DRIVER