在线时间1365 小时
UID3338155
注册时间2017-7-26
NXP金币1653
TA的每日心情 | 奋斗 3 小时前 |
---|
签到天数: 595 天 [LV.9]以坛为家II
金牌会员
- 积分
- 7071
- 最后登录
- 2024-4-28
|
本帖最后由 andeyqi 于 2024-1-8 09:13 编辑
之前通过S32K146 硬件I2C适配了RT-thread 的I2C的驱动框架(https://www.nxpic.org.cn/module/forum/thread-802563-1-1.html),但是S32K146 平台在只有一路硬件I2C控制器,如果要使用大于一路I2C,剩下的只能通过GPIO 来模拟,模拟I2C主要依赖PIN驱动,我们已经适配了PIN驱动(https://www.nxpic.org.cn/module/forum/thread-802577-1-1.html),基于PIN 驱动的基础上适配GPIO模拟I2C驱动只需要实现如下几个GPIO相关的函数即可.- #define SET_SDA(ops, val) ops->set_sda(ops->data, val)
- #define SET_SCL(ops, val) ops->set_scl(ops->data, val)
- #define GET_SDA(ops) ops->get_sda(ops->data)
- #define GET_SCL(ops) ops->get_scl(ops->data)
复制代码
有了PIN 驱动的基础上述函数的实现就很容易了。
- /**
- * @brief This function sets the sda pin.
- * @param data, state
- * @retval None
- */
- static void s32k1xx_set_sda(void *data, rt_int32_t state)
- {
- struct s32k1xx_soft_i2c_config* cfg = (struct s32k1xx_soft_i2c_config*)data;
-
- rt_pin_mode(cfg->sda, PIN_MODE_OUTPUT_OD);
-
- if (state)
- {
- rt_pin_write(cfg->sda, PIN_HIGH);
- }
- else
- {
- rt_pin_write(cfg->sda, PIN_LOW);
- }
- }
复制代码- /**
- * @brief This function sets the scl pin.
- * @param data, state
- * @retval None
- */
- static void s32k1xx_set_scl(void *data, rt_int32_t state)
- {
- struct s32k1xx_soft_i2c_config* cfg = (struct s32k1xx_soft_i2c_config*)data;
-
- rt_pin_mode(cfg->scl, PIN_MODE_OUTPUT_OD);
-
- if (state)
- {
- rt_pin_write(cfg->scl, PIN_HIGH);
- }
- else
- {
- rt_pin_write(cfg->scl, PIN_LOW);
- }
- }
复制代码
- /**
- * @brief This function gets the sda pin state.
- * @param data
- * @retval None
- */
- static rt_int32_t s32k1xx_get_sda(void *data)
- {
- struct s32k1xx_soft_i2c_config* cfg = (struct s32k1xx_soft_i2c_config*)data;
-
- rt_pin_mode(cfg->sda, PIN_MODE_INPUT);
-
- return rt_pin_read(cfg->sda);
- }
复制代码
- /**
- * @brief This function gets the scl pin state.
- * @param data
- * @retval None
- */
- static rt_int32_t s32k1xx_get_scl(void *data)
- {
- struct s32k1xx_soft_i2c_config* cfg = (struct s32k1xx_soft_i2c_config*)data;
- rt_pin_mode(cfg->scl,PIN_MODE_INPUT);
- return rt_pin_read(cfg->scl);
- }
复制代码 从S32K146 的特性头文件可知PORT口 不支持开漏模式,读取scl/sda 接口需要将GPIO切换为输入模式,读取数据前需要切换为输出模式。
- static const struct rt_i2c_bit_ops s32k1xx_bit_ops_default =
- {
- .data = RT_NULL,
- .set_sda = s32k1xx_set_sda,
- .set_scl = s32k1xx_set_scl,
- .get_sda = s32k1xx_get_sda,
- .get_scl = s32k1xx_get_scl,
- .udelay = s32k1xx_udelay,
- .delay_us = 1,
- .timeout = 100
- };
- /**
- * @brief I2C initialization function
- * @param None
- * @retval RT_EOK indicates successful initialization.
- */
- int rt_hw_soft_i2c_init(void)
- {
- rt_size_t obj_num = sizeof(i2c_obj) / sizeof(struct s32k1xx_i2c);
- rt_err_t result;
- for (int i = 0; i < obj_num; i++)
- {
- i2c_obj[i].ops = s32k1xx_bit_ops_default;
- i2c_obj[i].ops.data = (void*)&soft_i2c_config[i];
- i2c_obj[i].i2c2_bus.priv = &i2c_obj[i].ops;
- s32k1xx_i2c_gpio_init(&i2c_obj[i]);
- result = rt_i2c_bit_add_bus(&i2c_obj[i].i2c2_bus, soft_i2c_config[i].bus_name);
- RT_ASSERT(result == RT_EOK);
- s32k1xx_i2c_bus_unlock(&soft_i2c_config[i]);
- LOG_D("software simulation %s init done, pin scl: %d, pin sda %d",
- soft_i2c_config[i].bus_name,
- soft_i2c_config[i].scl,
- soft_i2c_config[i].sda);
- }
- return RT_EOK;
- }
- INIT_APP_EXPORT(rt_hw_soft_i2c_init);
复制代码- 在RT-thread 系统中开启soft i2c 驱动框架
通过menuconfig 配置软件I2C pin 脚
|
|