fix(软件模拟I2C):修改宏定义,方便后续兼容

1. 移动地址长度宏到 bsp_soft_i2c.h 文件内
2. 根据 GD32F30X_XX 和 STM32F10X_XX 生成对应的宏 SOFT_I2C_GD32F3_USED 和 SOFT_I2C_STM32F1_USED
3. 修改 bsp_soft_i2c_private.h 文件内的宏函数结构
4. 修改 bsp_soft_i2c.c 内时钟延展等待计数为可修改的宏 SOFT_I2C_WAIT_CNT

Signed-off-by: ArthurCai <arthurcai_c@163.com>
This commit is contained in:
ArthurCai 2024-01-29 22:39:05 +08:00
parent 166c5b9111
commit 3d500401a9
3 changed files with 105 additions and 43 deletions

View File

@ -25,8 +25,7 @@
* @return void * @return void
*/ */
SOFT_I2C_STATIC_INLINE void soft_i2c_gpio_clk_enable(P_SOFT_I2C_GPIO_COMM_T p_gpio) { SOFT_I2C_STATIC_INLINE void soft_i2c_gpio_clk_enable(P_SOFT_I2C_GPIO_COMM_T p_gpio) {
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) || \ #if defined(SOFT_I2C_GD32F3_USED) || defined(SOFT_I2C_STM32F1_USED)
defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
SOFT_I2C_ENABLE_GPIO_CLK(p_gpio->gpioClk); SOFT_I2C_ENABLE_GPIO_CLK(p_gpio->gpioClk);
#else #else
return; return;
@ -45,10 +44,10 @@ SOFT_I2C_STATIC_INLINE void soft_i2c_gpio_clk_enable(P_SOFT_I2C_GPIO_COMM_T p_gp
* @endcode * @endcode
*/ */
static void soft_i2c_set_od_mode(P_SOFT_I2C_GPIO_COMM_T p_gpio) { static void soft_i2c_set_od_mode(P_SOFT_I2C_GPIO_COMM_T p_gpio) {
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) #if defined(SOFT_I2C_GD32F3_USED)
// GD32F30x芯片 // GD32F30x芯片
gpio_init(p_gpio->gpioPort, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, p_gpio->gpioPin); gpio_init(p_gpio->gpioPort, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, p_gpio->gpioPin);
#elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL) #elif defined(SOFT_I2C_STM32F1_USED)
// STM32F10x芯片 // STM32F10x芯片
GPIO_InitTypeDef initStruct; GPIO_InitTypeDef initStruct;
initStruct.GPIO_Pin = (uint16_t)p_gpio->gpioPin; initStruct.GPIO_Pin = (uint16_t)p_gpio->gpioPin;
@ -71,8 +70,7 @@ static void soft_i2c_set_od_mode(P_SOFT_I2C_GPIO_COMM_T p_gpio) {
* @return void * @return void
*/ */
SOFT_I2C_STATIC_INLINE void soft_i2c_write_gpio(P_SOFT_I2C_GPIO_COMM_T p_gpio, uint8_t val) { SOFT_I2C_STATIC_INLINE void soft_i2c_write_gpio(P_SOFT_I2C_GPIO_COMM_T p_gpio, uint8_t val) {
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) || \ #if defined(SOFT_I2C_GD32F3_USED) || defined(SOFT_I2C_STM32F1_USED)
defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
if (val) { if (val) {
SOFT_I2C_SET_PIN(p_gpio->gpioPort, p_gpio->gpioPin); SOFT_I2C_SET_PIN(p_gpio->gpioPort, p_gpio->gpioPin);
} else { } else {
@ -92,8 +90,7 @@ SOFT_I2C_STATIC_INLINE void soft_i2c_write_gpio(P_SOFT_I2C_GPIO_COMM_T p_gpio, u
* @retval 0 , 1 * @retval 0 , 1
*/ */
SOFT_I2C_STATIC_INLINE uint8_t soft_i2c_read_gpio(P_SOFT_I2C_GPIO_COMM_T p_gpio) { SOFT_I2C_STATIC_INLINE uint8_t soft_i2c_read_gpio(P_SOFT_I2C_GPIO_COMM_T p_gpio) {
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) || \ #if defined(SOFT_I2C_GD32F3_USED) || defined(SOFT_I2C_STM32F1_USED)
defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
return (SOFT_I2C_READ_PIN(p_gpio->gpioPort, p_gpio->gpioPin)) ? 1 : 0; return (SOFT_I2C_READ_PIN(p_gpio->gpioPort, p_gpio->gpioPin)) ? 1 : 0;
#else #else
return 0xFF; return 0xFF;
@ -119,17 +116,19 @@ static void soft_i2c_delay_us(void) {
*/ */
static void soft_i2c_delay_800ns(void) { static void soft_i2c_delay_800ns(void) {
uint32_t i = 0; uint32_t i = 0;
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) #if defined(SOFT_I2C_GD32F3_USED)
uint32_t j = 0; uint32_t j = 0;
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
for (j = 0; j < (SOFT_I2C_DELAY_CYCLE * 4) / 5; j++) { for (j = 0; j < (SOFT_I2C_DELAY_CYCLE * 4) / 5; j++) {
__asm("NOP"); __asm("NOP");
} }
} }
#elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL) #elif defined(SOFT_I2C_STM32F1_USED)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
__asm("NOP"); __asm("NOP");
} }
#else
return;
#endif #endif
} }
#pragma pop #pragma pop
@ -196,7 +195,7 @@ static soft_i2c_err_t soft_i2c_stop(P_SOFT_I2C_T p_i2c) {
soft_i2c_delay_us(); soft_i2c_delay_us();
soft_i2c_write_gpio(&p_i2c->scl, SOFT_I2C_LEVEL_HIGH); soft_i2c_write_gpio(&p_i2c->scl, SOFT_I2C_LEVEL_HIGH);
#if defined(__SOFT_I2C_CLOCK_STRECH_EN__) #if defined(__SOFT_I2C_CLOCK_STRECH_EN__)
uint32_t waitCnt = 0xFFF; ///< 等待计数 uint32_t waitCnt = SOFT_I2C_WAIT_CNT; ///< 等待计数
SOFT_I2C_WAIT_SCL_RELEASE(p_i2c, waitCnt); // 等待SCL释放 SOFT_I2C_WAIT_SCL_RELEASE(p_i2c, waitCnt); // 等待SCL释放
if (waitCnt == 0) { if (waitCnt == 0) {
return SOFT_I2C_ERR_TIMEOUT; return SOFT_I2C_ERR_TIMEOUT;
@ -221,7 +220,7 @@ static soft_i2c_err_t soft_i2c_stop(P_SOFT_I2C_T p_i2c) {
* @endcode * @endcode
*/ */
static soft_i2c_err_t soft_i2c_wait_ack(P_SOFT_I2C_T p_i2c) { static soft_i2c_err_t soft_i2c_wait_ack(P_SOFT_I2C_T p_i2c) {
uint32_t waitCnt = 0xFFF; ///< 等待计数 uint32_t waitCnt = SOFT_I2C_WAIT_CNT; ///< 等待计数
soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_LEVEL_HIGH); // 开启线与 soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_LEVEL_HIGH); // 开启线与
soft_i2c_write_gpio(&p_i2c->scl, SOFT_I2C_LEVEL_HIGH); // 拉起SCL soft_i2c_write_gpio(&p_i2c->scl, SOFT_I2C_LEVEL_HIGH); // 拉起SCL
#if defined(__SOFT_I2C_CLOCK_STRECH_EN__) #if defined(__SOFT_I2C_CLOCK_STRECH_EN__)
@ -282,8 +281,8 @@ static void soft_i2c_ack_respond(P_SOFT_I2C_T p_i2c, uint8_t ackVal) {
static soft_i2c_err_t soft_i2c_send_byte(P_SOFT_I2C_T p_i2c, uint8_t byte) { static soft_i2c_err_t soft_i2c_send_byte(P_SOFT_I2C_T p_i2c, uint8_t byte) {
uint8_t loopCnt = 0; ///< 循环计数 uint8_t loopCnt = 0; ///< 循环计数
#if defined(__SOFT_I2C_CLOCK_STRECH_EN__) #if defined(__SOFT_I2C_CLOCK_STRECH_EN__)
uint32_t waitCnt = 0xFFF; ///< 等待计数 uint32_t waitCnt = SOFT_I2C_WAIT_CNT; ///< 等待计数
bool isFirstBit = true; ///< 是否第一位 bool isFirstBit = true; ///< 是否第一位
#endif #endif
for (loopCnt = 0; loopCnt < 8; loopCnt++) { for (loopCnt = 0; loopCnt < 8; loopCnt++) {
soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_GET_MSB_BIT(byte)); // 写入数据 soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_GET_MSB_BIT(byte)); // 写入数据
@ -323,8 +322,8 @@ static soft_i2c_err_t soft_i2c_send_byte(P_SOFT_I2C_T p_i2c, uint8_t byte) {
static soft_i2c_err_t soft_i2c_read_byte(P_SOFT_I2C_T p_i2c, uint8_t *p_data) { static soft_i2c_err_t soft_i2c_read_byte(P_SOFT_I2C_T p_i2c, uint8_t *p_data) {
uint8_t loopCnt = 0; ///< 循环计数 uint8_t loopCnt = 0; ///< 循环计数
#if defined(__SOFT_I2C_CLOCK_STRECH_EN__) #if defined(__SOFT_I2C_CLOCK_STRECH_EN__)
uint32_t waitCnt = 0xFFF; ///< 等待计数 uint32_t waitCnt = SOFT_I2C_WAIT_CNT; ///< 等待计数
bool isFirstBit = true; ///< 是否第一位 bool isFirstBit = true; ///< 是否第一位
#endif #endif
soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_LEVEL_HIGH); // 开启线与 soft_i2c_write_gpio(&p_i2c->sda, SOFT_I2C_LEVEL_HIGH); // 开启线与
for (loopCnt = 0; loopCnt < 8; loopCnt++) { for (loopCnt = 0; loopCnt < 8; loopCnt++) {
@ -450,8 +449,7 @@ soft_i2c_err_t soft_i2c_init(P_SOFT_I2C_T p_i2c) {
return SOFT_I2C_ERR_PARAM; return SOFT_I2C_ERR_PARAM;
} }
// 2. 初始化结构体内监控变量 // 2. 初始化结构体内监控变量
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) || \ #if defined(SOFT_I2C_GD32F3_USED) || defined(SOFT_I2C_STM32F1_USED)
defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
p_i2c->isValid = true; // 芯片有效 p_i2c->isValid = true; // 芯片有效
#else #else
p_i2c->isValid = false; // 芯片无效 p_i2c->isValid = false; // 芯片无效
@ -491,7 +489,8 @@ soft_i2c_err_t soft_i2c_init(P_SOFT_I2C_T p_i2c) {
* @endcode * @endcode
*/ */
soft_i2c_err_t soft_i2c_write(P_SOFT_I2C_T p_i2c, uint32_t slaveAddr, uint32_t regAddr, uint32_t regAddrLen, uint8_t *p_data, uint32_t dataLen) { soft_i2c_err_t soft_i2c_write(P_SOFT_I2C_T p_i2c, uint32_t slaveAddr, uint32_t regAddr, uint32_t regAddrLen, uint8_t *p_data, uint32_t dataLen) {
if (p_i2c == NULL || p_data == NULL || p_i2c->isValid == false || p_i2c->isInit == false || dataLen == 0) { if (p_i2c == NULL || p_data == NULL || p_i2c->isValid == false || p_i2c->isInit == false || \
dataLen == 0 || regAddrLen < SOFT_I2C_REG_ADDR_LEN_1 || regAddrLen > SOFT_I2C_REG_ADDR_LEN_2) {
return SOFT_I2C_ERR_PARAM; return SOFT_I2C_ERR_PARAM;
} }
SOFT_I2C_DEF_MSG(w_msg, slaveAddr, regAddr, regAddrLen, p_data, dataLen, SOFT_I2C_WRITE); SOFT_I2C_DEF_MSG(w_msg, slaveAddr, regAddr, regAddrLen, p_data, dataLen, SOFT_I2C_WRITE);
@ -517,7 +516,8 @@ soft_i2c_err_t soft_i2c_write(P_SOFT_I2C_T p_i2c, uint32_t slaveAddr, uint32_t r
* @endcode * @endcode
*/ */
soft_i2c_err_t soft_i2c_read(P_SOFT_I2C_T p_i2c, uint32_t slaveAddr, uint32_t regAddr, uint32_t regAddrLen, uint8_t *p_data, uint32_t dataLen) { soft_i2c_err_t soft_i2c_read(P_SOFT_I2C_T p_i2c, uint32_t slaveAddr, uint32_t regAddr, uint32_t regAddrLen, uint8_t *p_data, uint32_t dataLen) {
if (p_i2c == NULL || p_data == NULL || p_i2c->isValid == false || p_i2c->isInit == false || dataLen == 0) { if (p_i2c == NULL || p_data == NULL || p_i2c->isValid == false || p_i2c->isInit == false || \
dataLen == 0 || regAddrLen < SOFT_I2C_REG_ADDR_LEN_1 || regAddrLen > SOFT_I2C_REG_ADDR_LEN_2) {
return SOFT_I2C_ERR_PARAM; return SOFT_I2C_ERR_PARAM;
} }
SOFT_I2C_DEF_MSG(r_msg, slaveAddr, regAddr, regAddrLen, p_data, dataLen, SOFT_I2C_READ); SOFT_I2C_DEF_MSG(r_msg, slaveAddr, regAddr, regAddrLen, p_data, dataLen, SOFT_I2C_READ);

View File

@ -17,12 +17,18 @@
/* 根据不同的芯片包含不同的文件 */ /* 根据不同的芯片包含不同的文件 */
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) #if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD)
#include "gd32f30x.h" #define SOFT_I2C_GD32F3_USED ///< 使用GD32F3芯片
#elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL) #elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
#include "stm32f10x.h" #define SOFT_I2C_STM32F1_USED ///< 使用STM32F1芯片
#else #else
#error "Please select the target chip model!" #error "Please select the target chip model!"
#endif #endif
#if defined(SOFT_I2C_GD32F3_USED)
#include "gd32f30x.h"
#elif defined(SOFT_I2C_STM32F1_USED)
#include "stm32f10x.h"
#endif
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -33,6 +39,8 @@
#define SOFT_I2C_STATIC_INLINE static __inline ///< 静态内联函数 #define SOFT_I2C_STATIC_INLINE static __inline ///< 静态内联函数
#elif defined(__GNUC__) #elif defined(__GNUC__)
#define SOFT_I2C_STATIC_INLINE static inline ///< 静态内联函数 #define SOFT_I2C_STATIC_INLINE static inline ///< 静态内联函数
#else
#define SOFT_I2C_STATIC_INLINE
#endif #endif
/** /**
@ -55,6 +63,18 @@ typedef uint32_t soft_i2c_err_t; ///< 返回值类型
* @} * @}
*/ */
/**
* @brief I2C
* @addtogroup SOFT_I2C_REG_ADDR_LEN
* @{
*/
#define SOFT_I2C_REG_ADDR_LEN_1 (1U) ///< 1字节寄存器地址长度
#define SOFT_I2C_REG_ADDR_LEN_2 (2U) ///< 2字节寄存器地址长度
/**
* @}
*/
#if defined(SOFT_I2C_GD32F3_USED) || defined(SOFT_I2C_STM32F1_USED)
/** /**
* @brief I2C * @brief I2C
* *
@ -62,8 +82,11 @@ typedef uint32_t soft_i2c_err_t; ///< 返回值类型
*/ */
#define SOFT_I2C_EXT(name) \ #define SOFT_I2C_EXT(name) \
extern void *const name extern void *const name
#else
#define SOFT_I2C_EXT(name)
#endif
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD) #if defined(SOFT_I2C_GD32F3_USED)
/** /**
* @brief I2C * @brief I2C
* *
@ -80,8 +103,9 @@ typedef uint32_t soft_i2c_err_t; ///< 返回值类型
{GPIO##sda_port, GPIO_PIN_##sda_pin, SOFT_I2C_GPIO##sda_port##_CLK}, \ {GPIO##sda_port, GPIO_PIN_##sda_pin, SOFT_I2C_GPIO##sda_port##_CLK}, \
SOFT_I2C_IDLE \ SOFT_I2C_IDLE \
}; \ }; \
void *const name = &soft_i2c_##name void *const name = &soft_i2c_##name \
#elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL)
#elif defined(SOFT_I2C_STM32F1_USED)
/** /**
* @brief I2C * @brief I2C
* *
@ -98,7 +122,10 @@ typedef uint32_t soft_i2c_err_t; ///< 返回值类型
{GPIO##sda_port##_BASE, GPIO_Pin_##sda_pin, SOFT_I2C_GPIO##sda_port##_CLK}, \ {GPIO##sda_port##_BASE, GPIO_Pin_##sda_pin, SOFT_I2C_GPIO##sda_port##_CLK}, \
SOFT_I2C_IDLE \ SOFT_I2C_IDLE \
}; \ }; \
void *const name = &soft_i2c_##name void *const name = &soft_i2c_##name \
#else
#define SOFT_I2C_DEF(name, scl_port, scl_pin, sda_port, sda_pin)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -22,17 +22,9 @@
* @addtogroup SOFT_I2C_COMM_DEF * @addtogroup SOFT_I2C_COMM_DEF
* @{ * @{
*/ */
#define SOFT_I2C_SET_PIN(port, pin) \ #if defined(SOFT_I2C_GD32F3_USED)
(*(volatile uint32_t *)(uint32_t)((port) + 0x10U)) = (uint32_t)(pin)
#define SOFT_I2C_RESET_PIN(port, pin) \
(*(volatile uint32_t *)(uint32_t)((port) + 0x14U)) = (uint32_t)(pin)
#define SOFT_I2C_READ_PIN(port, pin) \
(*(volatile uint32_t *)(uint32_t)((port) + 0x08U)) & (uint32_t)(pin)
#define SOFT_I2C_ENABLE_GPIO_CLK(gpioClk) \
(*(volatile uint32_t *)(uint32_t)(0x40021000U + 0x18U)) |= (uint32_t)(gpioClk)
#if defined(GD32F30X_HD) || defined(GD32F30X_CL) || defined(GD32F30X_XD)
#define SOFT_I2C_DELAY_CYCLE (10U) ///< 延时周期数 #define SOFT_I2C_DELAY_CYCLE (10U) ///< 延时周期数
#elif defined(STM32F10X_HD) || defined(STM32F10X_MD) || defined(STM32F10X_CL) #elif defined(SOFT_I2C_STM32F1_USED)
#define SOFT_I2C_DELAY_CYCLE (1U) ///< 延时周期数 #define SOFT_I2C_DELAY_CYCLE (1U) ///< 延时周期数
#else #else
#define SOFT_I2C_DELAY_CYCLE (1U) ///< 延时周期数 #define SOFT_I2C_DELAY_CYCLE (1U) ///< 延时周期数
@ -43,22 +35,65 @@
#define SOFT_I2C_NACK SOFT_I2C_LEVEL_HIGH ///< I2C非应答信号(高电平) #define SOFT_I2C_NACK SOFT_I2C_LEVEL_HIGH ///< I2C非应答信号(高电平)
#define SOFT_I2C_WRITE (0U) ///< 写操作 #define SOFT_I2C_WRITE (0U) ///< 写操作
#define SOFT_I2C_READ (1U) ///< 读操作 #define SOFT_I2C_READ (1U) ///< 读操作
#define SOFT_I2C_REG_ADDR_LEN_1 (1U) ///< 1字节寄存器地址长度 #define SOFT_I2C_WAIT_CNT (0xFFFU) ///< 等待计数(用于时钟延展)
#define SOFT_I2C_REG_ADDR_LEN_2 (2U) ///< 2字节寄存器地址长度
/* /*
* @} * @}
*/ */
/**
* @brief I2C
*
* @param [in] port
* @param [in] pin
*/
#define SOFT_I2C_SET_PIN(port, pin) \
(*(volatile uint32_t *)(uint32_t)((port) + 0x10U)) = (uint32_t)(pin)
/**
* @brief I2C
*
* @param [in] port
* @param [in] pin
*/
#define SOFT_I2C_RESET_PIN(port, pin) \
(*(volatile uint32_t *)(uint32_t)((port) + 0x14U)) = (uint32_t)(pin)
/**
* @brief I2C
*
* @param [in] port
* @param [in] pin
*/
#define SOFT_I2C_READ_PIN(port, pin) \
(*(volatile uint32_t *)(uint32_t)((port) + 0x08U)) & (uint32_t)(pin)
/**
* @brief I2C 使
*
* @param [in] gpioClk @ref SOFT_I2C_GPIO_CLK_E
*/
#define SOFT_I2C_ENABLE_GPIO_CLK(gpioClk) \
(*(volatile uint32_t *)(uint32_t)(0x40021000U + 0x18U)) |= (uint32_t)(gpioClk)
/** /**
* @brief I2C * @brief I2C
* @addtogroup SOFT_I2C_BIT_OPERATION * @addtogroup SOFT_I2C_BIT_OPERATION
* @{ * @{
*/ */
#define SOFT_I2C_GET_MSB_BIT(data) (((data) >> 7) & 0x01) ///< 获取最高位
#define SOFT_I2C_GET_LOW_BYTE(data) (uint8_t)((data) & 0xFF) ///< 获取低字节 /**
/* * @brief I2C
* @} *
*/ * @param [in] data
*/
#define SOFT_I2C_GET_MSB_BIT(data) (((data) >> 7) & 0x01)
/**
* @brief I2C
*
* @param [in] data
*/
#define SOFT_I2C_GET_LOW_BYTE(data) (uint8_t)((data) & 0xFF)
/** /**
* @brief I2C SCL * @brief I2C SCL