From acb7e6496fcf59746f490be1a0970bf1078c58f4 Mon Sep 17 00:00:00 2001 From: deadprogram Date: Mon, 6 May 2024 19:29:11 +0200 Subject: [PATCH] machine/stm32: add i2c Frequency and SetBaudRate() function for boards that were missing implementation Signed-off-by: deadprogram --- src/machine/machine_stm32_i2c_revb.go | 34 +++++++++++++++++++++++---- src/machine/machine_stm32f7x2.go | 15 ++++++++++-- src/machine/machine_stm32l0.go | 17 +++++++++++--- src/machine/machine_stm32l4x2.go | 17 +++++++++++--- src/machine/machine_stm32l4x5.go | 15 ++++++++++-- src/machine/machine_stm32l4x6.go | 15 ++++++++++-- src/machine/machine_stm32l5x2.go | 15 ++++++++++-- src/machine/machine_stm32wlx.go | 15 ++++++++++-- 8 files changed, 122 insertions(+), 21 deletions(-) diff --git a/src/machine/machine_stm32_i2c_revb.go b/src/machine/machine_stm32_i2c_revb.go index 9253902940..307e0b4697 100644 --- a/src/machine/machine_stm32_i2c_revb.go +++ b/src/machine/machine_stm32_i2c_revb.go @@ -45,8 +45,9 @@ type I2C struct { // I2CConfig is used to store config info for I2C. type I2CConfig struct { - SCL Pin - SDA Pin + Frequency uint32 + SCL Pin + SDA Pin } func (i2c *I2C) Configure(config I2CConfig) error { @@ -64,7 +65,15 @@ func (i2c *I2C) Configure(config I2CConfig) error { i2c.configurePins(config) // Frequency range - i2c.Bus.TIMINGR.Set(i2c.getFreqRange()) + switch config.Frequency { + case 0: + config.Frequency = 100 * KHz + case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz: + default: + return errI2CNotImplemented + } + + i2c.Bus.TIMINGR.Set(i2c.getFreqRange(config.Frequency)) // Disable Own Address1 before set the Own Address1 configuration i2c.Bus.OAR1.ClearBits(stm32.I2C_OAR1_OA1EN) @@ -86,8 +95,23 @@ func (i2c *I2C) Configure(config I2CConfig) error { // SetBaudRate sets the communication speed for I2C. func (i2c *I2C) SetBaudRate(br uint32) error { - // TODO: implement - return errI2CNotImplemented + // disable I2C interface before any configuration changes + i2c.Bus.CR1.ClearBits(stm32.I2C_CR1_PE) + + switch br { + case 0: + br = 100 * KHz + case 10 * KHz, 100 * KHz, 400 * KHz, 500 * KHz: + default: + return errI2CNotImplemented + } + + i2c.Bus.TIMINGR.Set(i2c.getFreqRange(br)) + + // Disable Generalcall and NoStretch, Enable peripheral + i2c.Bus.CR1.Set(stm32.I2C_CR1_PE) + + return nil } func (i2c *I2C) Tx(addr uint16, w, r []byte) error { diff --git a/src/machine/machine_stm32f7x2.go b/src/machine/machine_stm32f7x2.go index 8755bc8fff..7da407071f 100644 --- a/src/machine/machine_stm32f7x2.go +++ b/src/machine/machine_stm32f7x2.go @@ -51,9 +51,20 @@ func (uart *UART) setRegisters() { //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { +func (i2c *I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX // for 27MHz PCLK1 (216MHz CPU Freq / 8). // TODO: Do calculations based on PCLK1 - return 0x00606A9B + switch br { + case 10 * KHz: + return 0x5010C0FF + case 100 * KHz: + return 0x00606A9B + case 400 * KHz: + return 0x00201625 + case 500 * KHz: + return 0x00100429 + default: + return 0 + } } diff --git a/src/machine/machine_stm32l0.go b/src/machine/machine_stm32l0.go index 844cfccb49..e3fcefb572 100644 --- a/src/machine/machine_stm32l0.go +++ b/src/machine/machine_stm32l0.go @@ -298,9 +298,20 @@ func (spi SPI) configurePins(config SPIConfig) { //---------- I2C related types and code // Gets the value for TIMINGR register -func (i2c I2C) getFreqRange() uint32 { +func (i2c I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX - // for 80MHz PCLK1. + // for 16MHz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x00303D5B + switch br { + case 10 * KHz: + return 0x40003EFF + case 100 * KHz: + return 0x00303D5B + case 400 * KHz: + return 0x0010061A + case 500 * KHz: + return 0x00000117 + default: + return 0 + } } diff --git a/src/machine/machine_stm32l4x2.go b/src/machine/machine_stm32l4x2.go index 497cf3e1d5..142a8f5f36 100644 --- a/src/machine/machine_stm32l4x2.go +++ b/src/machine/machine_stm32l4x2.go @@ -17,9 +17,20 @@ const APB2_TIM_FREQ = 80e6 // 80MHz //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { - // This is a 'magic' value calculated by STM32CubeMX +func (i2c *I2C) getFreqRange(br uint32) uint32 { + // These are 'magic' values calculated by STM32CubeMX // for 80MHz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x10909CEC + switch br { + case 10 * KHz: + return 0xF010F3FE + case 100 * KHz: + return 0x10909CEC + case 400 * KHz: + return 0x00702991 + case 500 * KHz: + return 0x00300E84 + default: + return 0 + } } diff --git a/src/machine/machine_stm32l4x5.go b/src/machine/machine_stm32l4x5.go index ec06544ba5..c8c550c3da 100644 --- a/src/machine/machine_stm32l4x5.go +++ b/src/machine/machine_stm32l4x5.go @@ -17,9 +17,20 @@ const APB2_TIM_FREQ = 120e6 // 120MHz //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { +func (i2c *I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX // for 120MHz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x307075B1 + switch br { + case 10 * KHz: + return 0x0 // does this even work? zero is weird here. + case 100 * KHz: + return 0x307075B1 + case 400 * KHz: + return 0x00B03FDB + case 500 * KHz: + return 0x005017C7 + default: + return 0 + } } diff --git a/src/machine/machine_stm32l4x6.go b/src/machine/machine_stm32l4x6.go index cf546303af..de878ebe32 100644 --- a/src/machine/machine_stm32l4x6.go +++ b/src/machine/machine_stm32l4x6.go @@ -17,9 +17,20 @@ const APB2_TIM_FREQ = 80e6 // 80MHz //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { +func (i2c *I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX // for 80MHz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x10909CEC + switch br { + case 10 * KHz: + return 0xF010F3FE + case 100 * KHz: + return 0x10909CEC + case 400 * KHz: + return 0x00702991 + case 500 * KHz: + return 0x00300E84 + default: + return 0 + } } diff --git a/src/machine/machine_stm32l5x2.go b/src/machine/machine_stm32l5x2.go index d439b8fd93..82ca1ecf6c 100644 --- a/src/machine/machine_stm32l5x2.go +++ b/src/machine/machine_stm32l5x2.go @@ -49,9 +49,20 @@ func (uart *UART) setRegisters() { //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { +func (i2c *I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX // for 110MHz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x40505681 + switch br { + case 10 * KHz: + return 0x0 // does this even work? zero is weird here. + case 100 * KHz: + return 0x40505681 + case 400 * KHz: + return 0x00A03AC8 + case 500 * KHz: + return 0x005015B6 + default: + return 0 + } } diff --git a/src/machine/machine_stm32wlx.go b/src/machine/machine_stm32wlx.go index d42ef2e383..b27c779feb 100644 --- a/src/machine/machine_stm32wlx.go +++ b/src/machine/machine_stm32wlx.go @@ -289,11 +289,22 @@ func (spi SPI) getBaudRate(config SPIConfig) uint32 { //---------- I2C related code // Gets the value for TIMINGR register -func (i2c *I2C) getFreqRange() uint32 { +func (i2c *I2C) getFreqRange(br uint32) uint32 { // This is a 'magic' value calculated by STM32CubeMX // for 48Mhz PCLK1. // TODO: Do calculations based on PCLK1 - return 0x20303E5D + switch br { + case 10 * KHz: + return 0x9010DEFF + case 100 * KHz: + return 0x20303E5D + case 400 * KHz: + return 0x2010091A + case 500 * KHz: + return 0x00201441 + default: + return 0 + } } //---------- UART related code