Skip to content

Commit

Permalink
Parameterise STM32 I2C pin modes and timing parameters. (qmk#5671)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tzarc authored and drashna committed Jun 5, 2019
1 parent 028d02d commit 0513f23
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 11 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@
05-29-2019 - Fixing matrix_scan so it properly returns changed status
05-29-2019 - Add belgian layour for sendstring (qmk#6008)
06-03-2019 - Overhaul of AutoShift feature (qmk#6067)
06-05-2019 - Parameterize STM32 I2C pin modes and timing parameters. (qmk#5671)
16 changes: 7 additions & 9 deletions drivers/arm/i2c_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,10 @@

static uint8_t i2c_address;

// This configures the I2C clock to 400khz assuming a 72Mhz clock
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
static const I2CConfig i2cconfig = {
STM32_TIMINGR_PRESC(15U) |
STM32_TIMINGR_SCLDEL(4U) | STM32_TIMINGR_SDADEL(2U) |
STM32_TIMINGR_SCLH(15U) | STM32_TIMINGR_SCLL(21U),
STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) |
STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) |
STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL),
0,
0
};
Expand All @@ -58,13 +56,13 @@ __attribute__ ((weak))
void i2c_init(void)
{
// Try releasing special pins for a short time
palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_INPUT);
palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_INPUT);
palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);

chThdSleepMilliseconds(10);

palSetPadMode(I2C1_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN);
palSetPadMode(I2C1_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN);
palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);

//i2cInit(); //This is invoked by halInit() so no need to redo it.
}
Expand Down
40 changes: 38 additions & 2 deletions drivers/arm/i2c_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,52 @@
#include "ch.h"
#include <hal.h>

#ifndef I2C1_BANK
#define I2C1_BANK GPIOB
#ifdef I2C1_BANK
#define I2C1_SCL_BANK I2C1_BANK
#define I2C1_SDA_BANK I2C1_BANK
#endif

#ifndef I2C1_SCL_BANK
#define I2C1_SCL_BANK GPIOB
#endif

#ifndef I2C1_SDA_BANK
#define I2C1_SDA_BANK GPIOB
#endif

#ifndef I2C1_SCL
#define I2C1_SCL 6
#endif
#ifndef I2C1_SDA
#define I2C1_SDA 7
#endif

// The default PAL alternate modes are used to signal that the pins are used for I2C
#ifndef I2C1_SCL_PAL_MODE
#define I2C1_SCL_PAL_MODE 4
#endif
#ifndef I2C1_SDA_PAL_MODE
#define I2C1_SDA_PAL_MODE 4
#endif

// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
#ifndef I2C1_TIMINGR_PRESC
#define I2C1_TIMINGR_PRESC 15U
#endif
#ifndef I2C1_TIMINGR_SCLDEL
#define I2C1_TIMINGR_SCLDEL 4U
#endif
#ifndef I2C1_TIMINGR_SDADEL
#define I2C1_TIMINGR_SDADEL 2U
#endif
#ifndef I2C1_TIMINGR_SCLH
#define I2C1_TIMINGR_SCLH 15U
#endif
#ifndef I2C1_TIMINGR_SCLL
#define I2C1_TIMINGR_SCLL 21U
#endif

#ifndef I2C_DRIVER
#define I2C_DRIVER I2CD1
#endif
Expand Down

0 comments on commit 0513f23

Please sign in to comment.