7.5.5. 设计说明

7.5.5.1. 源码说明

GPIO HAL 层相关 .c.h 文件分别位于 luban-lite\bsp\artinchip\hal\gpioluban-lite\bsp\artinchip\include\hal 目录。 Driver 层相关 .c.h 文件分别位于 luban-lite\bsp\artinchip\drv\gpioluban-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 方式的应用场景。

../../../_images/sw_system2.png
  1. GPIO HAL 层。提供了 PinMux 和通用 GPIO 功能寄存器级的功能封装。

  2. 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 流程

../../../_images/gpio_irq.png

Luban-Lite 对 GPIO Irq 做了一个二级中断的封装:

  1. 一级中断。每个 GPIO Group 共享一个物理中断号,每个 GPIO Group 最多包含 32 个 GPIO Pin 脚。

  2. 二级中断。每个 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)

注意事项