aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2019-06-02 09:04:09 +1000
committerDrashna Jaelre <drashna@live.com>2019-06-01 16:04:09 -0700
commit155be34a1d2b782a73318cc507315b33cc86cc49 (patch)
tree842b3fa9e4881d18932a0e01666dec5a8144d3b2
parent4f788c2ae90583f64e0cec6545a3da75a5aff0f8 (diff)
downloadqmk_firmware-155be34a1d2b782a73318cc507315b33cc86cc49.tar.gz
qmk_firmware-155be34a1d2b782a73318cc507315b33cc86cc49.zip
Parameterise STM32 I2C pin modes and timing parameters. (#5671)
I2C timing parameters were seemingly set up for an STM32F303 target MCU, at a specific clock speed. This commit allows specifying the timing parameters via config.h, allowing other STM32 MCUs to be targeted, potentially at different clock frequencies. Alternate function modes for the I2C pins are now also configurable, allowing for remapping to other pins.
-rw-r--r--docs/i2c_driver.md29
-rw-r--r--drivers/arm/i2c_master.c16
-rw-r--r--drivers/arm/i2c_master.h40
3 files changed, 69 insertions, 16 deletions
diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md
index bb1a2d74f..4a47a92b1 100644
--- a/docs/i2c_driver.md
+++ b/docs/i2c_driver.md
@@ -65,11 +65,30 @@ By default the I2C1 hardware driver is assumed to be used. If another hardware d
65 65
66STM32 MCUs allows a variety of pins to be configured as I2C pins depending on the hardware driver used. By default B6 and B7 are set to I2C. You can use these defines to set your i2c pins: 66STM32 MCUs allows a variety of pins to be configured as I2C pins depending on the hardware driver used. By default B6 and B7 are set to I2C. You can use these defines to set your i2c pins:
67 67
68| Variable | Description | Default | 68| Variable | Description | Default |
69|-------------|----------------------------------------------|---------| 69|--------------------------|----------------------------------------------------------------------------------------------|---------|
70| `I2C1_BANK` | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`) | `GPIOB` | 70| `I2C1_SCL_BANK` | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`) to use for SCL | `GPIOB` |
71| `I2C1_SCL` | The pin number for the SCL pin (0-9) | `6` | 71| `I2C1_SDA_BANK` | The bank of pins (`GPIOA`, `GPIOB`, `GPIOC`) to use for SDA | `GPIOB` |
72| `I2C1_SDA` | The pin number for the SDA pin (0-9) | `7` | 72| `I2C1_SCL` | The pin number for the SCL pin (0-9) | `6` |
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` |
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:
77
78| Variable | Default |
79|-----------------------|---------|
80| `I2C1_TIMINGR_PRESC` | `15U` |
81| `I2C1_TIMINGR_SCLDEL` | `4U` |
82| `I2C1_TIMINGR_SDADEL` | `2U` |
83| `I2C1_TIMINGR_SCLH` | `15U` |
84| `I2C1_TIMINGR_SCLL` | `21U` |
85
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.
87
88| Variable | Default |
89|---------------------|---------|
90| `I2C1_SCL_PAL_MODE` | `4` |
91| `I2C1_SDA_PAL_MODE` | `4` |
73 92
74You 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: 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:
75 94
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c
index 7369398cc..5814375f3 100644
--- a/drivers/arm/i2c_master.c
+++ b/drivers/arm/i2c_master.c
@@ -32,12 +32,10 @@
32 32
33static uint8_t i2c_address; 33static uint8_t i2c_address;
34 34
35// This configures the I2C clock to 400khz assuming a 72Mhz clock
36// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
37static const I2CConfig i2cconfig = { 35static const I2CConfig i2cconfig = {
38 STM32_TIMINGR_PRESC(15U) | 36 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) |
39 STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) | 37 STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) |
40 STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U), 38 STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL),
41 0, 39 0,
42 0 40 0
43}; 41};
@@ -58,13 +56,13 @@ __attribute__ ((weak))
58void i2c_init(void) 56void i2c_init(void)
59{ 57{
60 // Try releasing special pins for a short time 58 // Try releasing special pins for a short time
61 palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_INPUT); 59 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
62 palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_INPUT); 60 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);
63 61
64 chThdSleepMilliseconds(10); 62 chThdSleepMilliseconds(10);
65 63
66 palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); 64 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
67 palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN); 65 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
68 66
69 //i2cInit(); //This is invoked by halInit() so no need to redo it. 67 //i2cInit(); //This is invoked by halInit() so no need to redo it.
70} 68}
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h
index a15f1702d..1bb74c800 100644
--- a/drivers/arm/i2c_master.h
+++ b/drivers/arm/i2c_master.h
@@ -26,9 +26,19 @@
26#include "ch.h" 26#include "ch.h"
27#include <hal.h> 27#include <hal.h>
28 28
29#ifndef I2C1_BANK 29#ifdef I2C1_BANK
30 #define I2C1_BANK GPIOB 30 #define I2C1_SCL_BANK I2C1_BANK
31 #define I2C1_SDA_BANK I2C1_BANK
31#endif 32#endif
33
34#ifndef I2C1_SCL_BANK
35 #define I2C1_SCL_BANK GPIOB
36#endif
37
38#ifndef I2C1_SDA_BANK
39 #define I2C1_SDA_BANK GPIOB
40#endif
41
32#ifndef I2C1_SCL 42#ifndef I2C1_SCL
33 #define I2C1_SCL 6 43 #define I2C1_SCL 6
34#endif 44#endif
@@ -36,6 +46,32 @@
36 #define I2C1_SDA 7 46 #define I2C1_SDA 7
37#endif 47#endif
38 48
49// The default PAL alternate modes are used to signal that the pins are used for I2C
50#ifndef I2C1_SCL_PAL_MODE
51 #define I2C1_SCL_PAL_MODE 4
52#endif
53#ifndef I2C1_SDA_PAL_MODE
54 #define I2C1_SDA_PAL_MODE 4
55#endif
56
57// 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
59#ifndef I2C1_TIMINGR_PRESC
60 #define I2C1_TIMINGR_PRESC 15U
61#endif
62#ifndef I2C1_TIMINGR_SCLDEL
63 #define I2C1_TIMINGR_SCLDEL 4U
64#endif
65#ifndef I2C1_TIMINGR_SDADEL
66 #define I2C1_TIMINGR_SDADEL 2U
67#endif
68#ifndef I2C1_TIMINGR_SCLH
69 #define I2C1_TIMINGR_SCLH 15U
70#endif
71#ifndef I2C1_TIMINGR_SCLL
72 #define I2C1_TIMINGR_SCLL 21U
73#endif
74
39#ifndef I2C_DRIVER 75#ifndef I2C_DRIVER
40 #define I2C_DRIVER I2CD1 76 #define I2C_DRIVER I2CD1
41#endif 77#endif