From e9117269ef7c2da632d7f5af64b1a2758f69c5ac Mon Sep 17 00:00:00 2001 From: jonasius Date: Tue, 25 Jun 2024 19:07:22 +0200 Subject: [PATCH] Add experimental detection of separate USB-PD I2C bus for S99 v1.5 and S60P v1.2 --- source/Core/BSP/Sequre/BSP.cpp | 68 -------------------------- source/Core/BSP/Sequre/Software_I2C.h | 22 +++++++-- source/Core/BSP/Sequre/configuration.h | 4 ++ source/Core/BSP/Sequre/preRTOS.cpp | 12 ++++- source/Core/Drivers/FS2711.cpp | 36 ++++++++++++-- source/Core/Drivers/FS2711.hpp | 2 + 6 files changed, 66 insertions(+), 78 deletions(-) diff --git a/source/Core/BSP/Sequre/BSP.cpp b/source/Core/BSP/Sequre/BSP.cpp index b32f239e..c1c02e48 100644 --- a/source/Core/BSP/Sequre/BSP.cpp +++ b/source/Core/BSP/Sequre/BSP.cpp @@ -122,75 +122,7 @@ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { } void unstick_I2C() { -#ifdef SCL_Pin - GPIO_InitTypeDef GPIO_InitStruct; - int timeout = 100; - int timeout_cnt = 0; - // 1. Clear PE bit. - hi2c1.Instance->CR1 &= ~(0x0001); - /**I2C1 GPIO Configuration - PB6 ------> I2C1_SCL - PB7 ------> I2C1_SDA - */ - // 2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level (Write 1 to GPIOx_ODR). - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - - GPIO_InitStruct.Pin = SCL_Pin; - HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - - GPIO_InitStruct.Pin = SDA_Pin; - HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); - HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET); - - while (GPIO_PIN_SET != HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin)) { - // Move clock to release I2C - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET); - asm("nop"); - asm("nop"); - asm("nop"); - asm("nop"); - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - - timeout_cnt++; - if (timeout_cnt > timeout) { - return; - } - } - - // 12. Configure the SCL and SDA I/Os as Alternate function Open-Drain. - GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - - GPIO_InitStruct.Pin = SCL_Pin; - HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct); - - GPIO_InitStruct.Pin = SDA_Pin; - HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct); - - HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET); - HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET); - - // 13. Set SWRST bit in I2Cx_CR1 register. - hi2c1.Instance->CR1 |= 0x8000; - - asm("nop"); - - // 14. Clear SWRST bit in I2Cx_CR1 register. - hi2c1.Instance->CR1 &= ~0x8000; - - asm("nop"); - - // 15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register - hi2c1.Instance->CR1 |= 0x0001; - - // Call initialization function. - HAL_I2C_Init(&hi2c1); -#endif } uint8_t getButtonA() { return HAL_GPIO_ReadPin(KEY_A_GPIO_Port, KEY_A_Pin) == GPIO_PIN_RESET ? 1 : 0; } diff --git a/source/Core/BSP/Sequre/Software_I2C.h b/source/Core/BSP/Sequre/Software_I2C.h index d80bbfcb..a28d0ce0 100644 --- a/source/Core/BSP/Sequre/Software_I2C.h +++ b/source/Core/BSP/Sequre/Software_I2C.h @@ -5,19 +5,32 @@ * Author: Ralim */ -#ifndef BSP_MINIWARE_SOFTWARE_I2C_H_ -#define BSP_MINIWARE_SOFTWARE_I2C_H_ +#ifndef BSP_SEQURE_SOFTWARE_I2C_H_ +#define BSP_SEQURE_SOFTWARE_I2C_H_ #include "BSP.h" #include "configuration.h" #include "stm32f1xx_hal.h" -#ifdef I2C_SOFT_BUS_2 +#ifdef I2C_SOFT_BUS_1 +#define SOFT_SCL1_HIGH() HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_SET) +#define SOFT_SCL1_LOW() HAL_GPIO_WritePin(SCL_GPIO_Port, SCL_Pin, GPIO_PIN_RESET) +#define SOFT_SDA1_HIGH() HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_SET) +#define SOFT_SDA1_LOW() HAL_GPIO_WritePin(SDA_GPIO_Port, SDA_Pin, GPIO_PIN_RESET) +#define SOFT_SDA1_READ() (HAL_GPIO_ReadPin(SDA_GPIO_Port, SDA_Pin) == GPIO_PIN_SET ? 1 : 0) +#define SOFT_SCL1_READ() (HAL_GPIO_ReadPin(SCL_GPIO_Port, SCL_Pin) == GPIO_PIN_SET ? 1 : 0) + +#endif /* I2C_SOFT_BUS_1 */ + +#ifdef I2C_SOFT_BUS_2 #define SOFT_SCL2_HIGH() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_SET) #define SOFT_SCL2_LOW() HAL_GPIO_WritePin(SCL2_GPIO_Port, SCL2_Pin, GPIO_PIN_RESET) #define SOFT_SDA2_HIGH() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_SET) #define SOFT_SDA2_LOW() HAL_GPIO_WritePin(SDA2_GPIO_Port, SDA2_Pin, GPIO_PIN_RESET) #define SOFT_SDA2_READ() (HAL_GPIO_ReadPin(SDA2_GPIO_Port, SDA2_Pin) == GPIO_PIN_SET ? 1 : 0) #define SOFT_SCL2_READ() (HAL_GPIO_ReadPin(SCL2_GPIO_Port, SCL2_Pin) == GPIO_PIN_SET ? 1 : 0) + +#endif /* I2C_SOFT_BUS_2 */ + // clang-format off #define SOFT_I2C_DELAY() \ { \ @@ -27,7 +40,6 @@ } // clang-format on -#endif // 40 ~= 100kHz; 15 gives around 250kHz or so which is fast _and_ stable -#endif /* BSP_MINIWARE_SOFTWARE_I2C_H_ */ +#endif /* BSP_SEQURE_SOFTWARE_I2C_H_ */ diff --git a/source/Core/BSP/Sequre/configuration.h b/source/Core/BSP/Sequre/configuration.h index 501cb85c..78da9d8a 100644 --- a/source/Core/BSP/Sequre/configuration.h +++ b/source/Core/BSP/Sequre/configuration.h @@ -194,6 +194,8 @@ #define HAS_POWER_DEBUG_MENU #define TEMP_NTC #define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues +#define I2C_PROBE_POW_PD // For now we are doing software I2C to get around hardware chip issues +#define I2C_SOFT_BUS_1 // For now we are doing software I2C to get around hardware chip issues #define OLED_I2CBB2 #define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place @@ -227,6 +229,8 @@ #define HAS_POWER_DEBUG_MENU #define TEMP_NTC #define I2C_SOFT_BUS_2 // For now we are doing software I2C to get around hardware chip issues +#define I2C_PROBE_POW_PD // For now we are doing software I2C to get around hardware chip issues +#define I2C_SOFT_BUS_1 // For now we are doing software I2C to get around hardware chip issues #define OLED_I2CBB2 #define MODEL_HAS_DCDC // We dont have DC/DC but have reallly fast PWM that gets us roughly the same place diff --git a/source/Core/BSP/Sequre/preRTOS.cpp b/source/Core/BSP/Sequre/preRTOS.cpp index 3a8fa4f4..411d53b2 100644 --- a/source/Core/BSP/Sequre/preRTOS.cpp +++ b/source/Core/BSP/Sequre/preRTOS.cpp @@ -6,10 +6,14 @@ */ #include "BSP.h" +#include "I2CBB1.hpp" #include "I2CBB2.hpp" #include "Pins.h" #include "Setup.h" #include +#if defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 +#include "FS2711.hpp" +#endif void preRToSInit() { /* Reset of all peripherals, Initializes the Flash interface and the Systick. @@ -19,5 +23,11 @@ void preRToSInit() { BSPInit(); #ifdef I2C_SOFT_BUS_2 I2CBB2::init(); -#endif +#if defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 + // Detect FS2711 I2C bus num + if (FS2711::detect_i2c_bus_num() == 1) { + I2CBB1::init(); + } +#endif /* defined(I2C_PROBE_POW_PD) && POW_PD_EXT == 2 */ +#endif /* I2C_SOFT_BUS_2 */ } diff --git a/source/Core/Drivers/FS2711.cpp b/source/Core/Drivers/FS2711.cpp index d80a1623..246c0597 100644 --- a/source/Core/Drivers/FS2711.cpp +++ b/source/Core/Drivers/FS2711.cpp @@ -1,5 +1,6 @@ #include "FS2711.hpp" #include "FS2711_defines.h" +#include "I2CBB1.hpp" #include "I2CBB2.hpp" #include "Settings.h" #include "Utils.h" @@ -17,17 +18,44 @@ extern int32_t powerSupplyWattageLimit; +uint8_t I2C_PORT = 2; fs2711_state_t FS2711::state; -inline void i2c_write(uint8_t addr, uint8_t data) { I2CBB2::Mem_Write(FS2711_ADDR, addr, &data, 1); } +void i2c_write(uint8_t addr, uint8_t data) { + if (I2C_PORT == 2) { + I2CBB2::Mem_Write(FS2711_ADDR, addr, &data, 1); + } else if (I2C_PORT == 1) { + I2CBB1::Mem_Write(FS2711_ADDR, addr, &data, 1); + } +} -inline uint8_t i2c_read(uint8_t addr) { +uint8_t i2c_read(uint8_t addr) { uint8_t data = 0; - I2CBB2::Mem_Read(FS2711_ADDR, addr, &data, 1); + if (I2C_PORT == 2) { + I2CBB2::Mem_Read(FS2711_ADDR, addr, &data, 1); + } else if (I2C_PORT == 1) { + I2CBB1::Mem_Read(FS2711_ADDR, addr, &data, 1); + } return data; } -inline bool i2c_probe(uint8_t addr) { return I2CBB2::probe(addr); } +bool i2c_probe(uint8_t addr) { + if (I2C_PORT == 2) { + I2CBB2::probe(addr); + } else if (I2C_PORT == 1) { + I2CBB1::probe(addr); + } + return false; + } + +uint8_t FS2711::detect_i2c_bus_num() { + if (I2CBB2::probe(FS2711_ADDR)) { + I2C_PORT = 2; + } else { + I2C_PORT = 1; + } + return I2C_PORT; +} void FS2711::start() { memset(&state, 0, sizeof(fs2711_state_t)); diff --git a/source/Core/Drivers/FS2711.hpp b/source/Core/Drivers/FS2711.hpp index 9fb2ae83..11a6943d 100644 --- a/source/Core/Drivers/FS2711.hpp +++ b/source/Core/Drivers/FS2711.hpp @@ -19,6 +19,8 @@ typedef struct { class FS2711 { public: + static uint8_t detect_i2c_bus_num(); + static bool probe(); static void start();