#夏日挑战赛#【FFH】BearPi_Micro南向开发I2C驱动代码深耕 原创 精华
#夏日挑战赛#【FFH】BearPi_Micro南向开发I2C驱动代码深耕
本文正在参加星光计划3.0–夏日挑战赛
I2C
@[toc]
I2C驱动结构概括
接口层将驱动封装起来,用户可直接调用接口层函数进行驱动的使用,用户便可不再需要配置I2C的具体设置
核心层是鸿蒙系统用于操作、控制、管理I2C设备
适配层则为鸿蒙系统用于兼容不同芯片设备,开发新芯片驱动时可以在此设置芯片的驱动相关底层数据
I2C启动的系统结构
启动代码在i2c_if.c
,所以使用前需要引用#include "i2c_if.h"
接口层
用户需要使用I2C时,只需要知道I2C控制器的序号,便可通过以下I2C控制器API驱动函数打开I2C
DevHandle I2cOpen(int16_t number);
其中参数number:I2C控制器序号
核心层
在此启动函数中调用到了核心层I2cCntlrGet(number);
函数,最终调用到了static struct I2cCntlr *I2cManagerFindCntlr(int16_t number);
此层为核心层,是鸿蒙系统开启I2C的操作,开发时不需要关注这部分
static struct I2cCntlr *I2cManagerFindCntlr(int16_t number)
{
struct I2cCntlr *cntlr = NULL;
struct I2cManager *manager = g_i2cManager;
//检查I2C控制器序号是否合法
//检查I2C控制器
//检查I2C锁控制器
cntlr = manager->cntlrs[number];
return cntlr;
}
适配层
想要使核心层正确打开芯片的I2C,就需要小熊派芯片的I2C一些重要数值传递给核心层,例如设备号、总线号,IO口位置,寄存器位置等
小熊派的I2C的私人配置数据都放在了i2c_config.hcs
(文件地址:bearpi-hm_micro_small\device\st\bearpi_hm_micro\liteos_a\hdf_config\i2c\i2c_config.hcs)
root {
platform {
i2c_config {
match_attr = "st_stm32mp157_i2c"; /*需要和device_info.hcs中的deviceMatchAttr值一致
使device_info.hsc可以正确调用私人配置数据*/
template i2c_controller {
bus = 1;
reg_pbase = 0x40012000; //物理基地址
reg_size = 0x400; //寄存器位宽
timing = 0x10909CEC;
own_address1 = 0;
addressing_mode = 0x00000001;
dual_address_mode = 0x00000000;
own_address2 = 0;
own_address_2_masks = 0x00;
general_call_mode = 0x00000000;
no_stretch_mode = 0x00000000;
}
controller_0x40012000 :: i2c_controller {
bus = 1; //i2c控制器序号,用于打开i2c
reg_pbase = 0x40012000;
/***********************/
/* [port,pin]
<port> 0:GPIOA 1:GPIOB 3:GPIOC ......GPIOF便是5
<pin> 0:PIN0 1:PIN1 2:PIN2 ......
*/
i2cClkIomux = [5, 14]; //PF14,SCL
i2cDataIomux = [5, 15]; //PF15,SDA
/***********************/
}
controller_0x40013000 :: i2c_controller {
bus = 2;
reg_pbase = 0x40013000;
i2cClkIomux = [7, 4]; //PH4
i2cDataIomux = [7, 5]; //PH5
}
controller_0x40015000 :: i2c_controller {
bus = 5;
reg_pbase = 0x40015000;
i2cClkIomux = [0, 11]; //PA11
i2cDataIomux = [0, 12]; //PA12
}
}
}
}
通过查询小熊派的E53接口的原理图,可以知道E53接口上的I2C在GPIOF14和GPIOF15
此处对应了小熊派私人配置中的物理基地址配置 i2cClkIomux = [5, 14]; i2cDataIomux = [5, 15];
I2C的结构体
I2cCntlr控制成员在定义驱动入口的对象初始化的时候,就需要被实例化。
调用核心层I2cCntlrAdd
函数,使用芯片的私人配置实例化I2cCntlr。
I2cCntlr成员
struct I2cCntlr {
struct OsalMutex lock;
void *owner;
int16_t busId;
void *priv;//存储设备属性
const struct I2cMethod *ops;//I2cMethod的实例化对象的挂载
const struct I2cLockMethod *lockOps;//I2cLockMethod的实例化对象的挂载
};
I2cCntlr成员I2cMethod和I2cLockMethod
struct I2cMethod {
int32_t (*transfer)(struct I2cCntlr *cntlr, struct I2cMsg *msgs, int16_t count);
};
struct I2cLockMethod {//锁机制操作结构体
int32_t (*lock)(struct I2cCntlr *cntlr);//加锁
void (*unlock)(struct I2cCntlr *cntlr); //解锁
};
实例化I2cCntlr例子
在stm32mp1_i2c.c定义驱动入口的对象中Init实例化I2cCntlr
Init函数中其中实例化自定义的结构体,实际上也是实例化了I2cCntlr。
好,期待作者更多文章
大佬带带我🥺