7.5.5. 设计说明¶
7.5.5.1. 源码说明¶
GPIO HAL 层相关 .c 和 .h 文件分别位于 luban-lite\bsp\artinchip\hal\gpio 和 luban-lite\bsp\artinchip\include\hal 目录。
Driver 层相关 .c 和 .h 文件分别位于 luban-lite\bsp\artinchip\drv\gpio 和 luban-lite\bsp\artinchip\include\drv 目录。
主要源文件说明如下:
| 文件 | 说明 | 
|---|---|
| aic_hal_gpio.h | GPIO hal 层 api 的头文件 | 
| aic_hal_gpio.c | GPIO hal 层 api 的实现 | 
| aic_drv_gpio.h | GPIO drv 层 api 的头文件 | 
| aic_drv_gpio.c | GPIO driver 注册以及 gpio drv 层 api 的实现 | 
| aic_hal_gpio_def_v10.c | GPIO V1.0 的配置 | 
| aic_hal_gpio_def_v11.c | GPIO V1.1 的配置 | 
| aic_hal_gpio_def_v12.c | GPIO V1.2 的配置 | 
7.5.5.2. 模块架构¶
GPIO 驱动 Driver 层采用 RT-Thread 的 PIN设备驱动框架,如果只使用HAL层也可以支持 baremetal 方式的应用场景。
 
- GPIO HAL 层。提供了 PinMux 和通用 GPIO 功能寄存器级的功能封装。 
- GPIO Driver 层。 - Rt-Thread。通用 GPIO 功能注册成 RTT Pin driver,PinMux 直接以 API 的形式提供。 
- BareMental。客户自定义 Driver 直接调用 GPIO HAL 层 Api。 
 
7.5.5.2.1. RTT Pin 驱动¶
Rt-Thread 调用 rt_device_pin_register() 把通用 GPIO 功能注册成 Pin Driver,Pin Driver 提供了以下功能:
- 模式配置。配置输入、输出模式,输入上下拉配置。 
- 读取端口状态。读取输入端口的电平状态。 
- 设置端口状态。配置输出端口的电平状态。 
- GPIO 中断配置。注册中断,使能中断。 
因为一个系统只允许注册一个 Pin Device,所以在调用的时候除了先使用 rt_device_find() 查找 Device 的形式来调用功能,也可以直接使用一组 rt_pin_xxx() 的函数直接来调用功能。
7.5.5.3. 关键流程设计¶
7.5.5.3.1. 初始化流程¶
Rt-Thread 系统初始化时会自动调用 GPIO 驱动初始化函数:
Reset_Handler
    → entry()
        → rtthread_startup()
            → rt_hw_board_init()
                → rt_components_board_init()
                    → drv_pin_init()
drv_pin_init() 注册了 RTT Pin 驱动:
const static struct rt_pin_ops _drv_pin_ops =
{
    drv_pin_mode,
    drv_pin_write,
    drv_pin_read,
#ifdef AIC_GPIO_IRQ_DRV_EN
    drv_pin_attach_irq,
    drv_pin_detach_irq,
    drv_pin_irq_enable,
#else
    RT_NULL,
    RT_NULL,
    RT_NULL,
#endif
    drv_pin_get,
};
int drv_pin_init(void)
{
    int ret = RT_EOK;
    ret = rt_device_pin_register("pin", &_drv_pin_ops, RT_NULL);
    return ret;
}
INIT_BOARD_EXPORT(drv_pin_init);
7.5.5.3.2. GPIO Irq 流程¶
 
Luban-Lite 对 GPIO Irq 做了一个二级中断的封装:
- 一级中断。每个 GPIO Group 共享一个物理中断号,每个 GPIO Group 最多包含 32 个 GPIO Pin 脚。 
- 二级中断。每个 GPIO Pin 脚中断也虚拟成标准的 Luban-Lite 中断,但是实际上是 GPIO Group ISR 做了一次中转。 
7.5.5.4. 接口设计¶
7.5.5.4.1. Driver 层接口设计¶
以下接口是 Pin 设备驱动框架的标准接口。
struct rt_pin_ops
{
    void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
    void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
    int (*pin_read)(struct rt_device *device, rt_base_t pin);
    rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
                    rt_uint32_t mode, void (*hdr)(void *args), void *args);
    rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
    rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
    rt_base_t (*pin_get)(const char *name);
};
7.5.5.4.2. drv_pin_mode¶
| 函数原型 | void drv_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode) | 
|---|---|
| 功能说明 | 设置 Pin 模式,包括输入/输出模式、上下拉模式 | 
| 参数定义 | pin:Pin id mode: 输入/输出模式、上下拉模式 (PIN_MODE_xxx 格式的宏) | 
| 注意事项 | 
7.5.5.4.3. drv_pin_write¶
| 函数原型 | void drv_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value) | 
|---|---|
| 功能说明 | 设置输出 Pin 的电平状态 | 
| 参数定义 | pin:Pin id value: 电平状态 0/1 | 
| 注意事项 | 
7.5.5.4.4. drv_pin_read¶
| 函数原型 | int drv_pin_read(struct rt_device *device, rt_base_t pin) | 
|---|---|
| 功能说明 | 设置输出 Pin 的电平状态 | 
| 参数定义 | pin:Pin id | 
| 返回值 | 电平状态 0/1 | 
| 注意事项 | 
7.5.5.4.5. drv_pin_attach_irq¶
| 函数原型 | rt_err_t drv_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) | 
|---|---|
| 功能说明 | Pin 注册中断 | 
| 参数定义 | pin:Pin id mode: 中断触发模式,边沿还是电平触发 (PIN_IRQ_MODE_xxx 格式的宏) hdr:pin 中断处理函数 args:中断处理时的自定义参数 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.4.6. drv_pin_detach_irq¶
| 函数原型 | rt_err_t drv_pin_detach_irq(struct rt_device *device, rt_int32_t pin) | 
|---|---|
| 功能说明 | Pin 注销中断 | 
| 参数定义 | pin:Pin id | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.4.7. drv_pin_irq_enable¶
| 函数原型 | rt_err_t drv_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) | 
|---|---|
| 功能说明 | 使能 Pin 中断 | 
| 参数定义 | pin:Pin id enabled: 1 = en, 0 = dis | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.4.8. drv_pin_get¶
| 函数原型 | rt_base_t drv_pin_get(const char *name) | 
|---|---|
| 功能说明 | 根据 Pin Name 获取 Pin Id | 
| 参数定义 | name:Pin Name 字符串 (“PA.1” 类似格式) | 
| 返回值 | Pin Id | 
| 注意事项 | 
7.5.5.5. HAL 层接口设计¶
7.5.5.5.1. hal_gpio_set_func¶
| 函数原型 | int hal_gpio_set_func(unsigned int group, unsigned int pin, unsigned int func) | 
|---|---|
| 功能说明 | 设置 Pin 的 Function 模式 | 
| 参数定义 | group:group id pin:offset in group func: 0 = 关闭, 1 = 通用 gpio, 2~8 = 专用功能 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.2. hal_gpio_get_func¶
| 函数原型 | int hal_gpio_get_func(unsigned int group, unsigned int pin, unsigned int *pfunc) | 
|---|---|
| 功能说明 | 获取 Pin 的 Function 模式 | 
| 参数定义 | group:group id pin:offset in group func: 0 = 关闭, 1 = 通用 gpio, 2~8 = 专用功能 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.3. hal_gpio_direction_input¶
| 函数原型 | int hal_gpio_direction_input(unsigned int group, unsigned int pin) | 
|---|---|
| 功能说明 | 设置 Pin 为输入模式 | 
| 参数定义 | group:group id pin:offset in group | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.4. hal_gpio_direction_output¶
| 函数原型 | int hal_gpio_direction_output(unsigned int group, unsigned int pin) | 
|---|---|
| 功能说明 | 设置 Pin 为输出模式 | 
| 参数定义 | group:group id pin:offset in group | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.5. hal_gpio_set_bias_pull¶
| 函数原型 | int hal_gpio_set_bias_pull(unsigned int group, unsigned int pin, unsigned int pull) | 
|---|---|
| 功能说明 | 设置 Pin 的上下拉模式 | 
| 参数定义 | group:group id pin:offset in group pull: 0 = 关闭, 2 = 下拉, 3 = 上拉 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.6. hal_gpio_set_drive_strength¶
| 函数原型 | int hal_gpio_set_drive_strength(unsigned int group, unsigned int pin, unsigned int strength) | 
|---|---|
| 功能说明 | 设置 Pin 的驱动能力 | 
| 参数定义 | group:group id pin:offset in group strength: 0 ~ 7 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.7. hal_gpio_set_debounce¶
| 函数原型 | int hal_gpio_set_debounce(unsigned int group, unsigned int pin, unsigned int debounce) | 
|---|---|
| 功能说明 | 设置 Pin 的防抖能力 | 
| 参数定义 | group:group id pin:offset in group debounce: 0 ~ 0xFFF | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
7.5.5.5.8. hal_gpio_set_irq_mode¶
| 函数原型 | int hal_gpio_set_irq_mode(unsigned int group, unsigned int pin, unsigned int irq_mode) | 
|---|---|
| 功能说明 | 设置 Pin 的防抖能力 | 
| 参数定义 | group:group id pin:offset in group irq_mode: 0 = 下降沿,1 = 上升沿,2 = 低电平,3 = 高电平,4 = 双沿 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 |