AiPi-Eyes-S1是安信可开源团队专门为Ai-M61-32S设计的一款开发板,支持WiFi6、BLE5.3。所搭载的Ai-M61-32S 模组具有丰富的外设接口,具体包括 DVP、MJPEG、Dispaly、AudioCodec、USB2.0、SDU、以太网 (EMAC)、SD/MMC(SDH)、SPI、UART、I2C、I2S、PWM、GPDAC、GPADC、ACOMP 和 GPIO 等。
AiPi-Eyes-S1集成了SPI屏幕接口,DVP摄像头接口,外置ES8388音频编解码芯片以及预留TF卡座,并且引出USB接口,可接入USB摄像头。
从零开始学习小安派:
博流系列的芯片驱动分为两类,LHAL 和 SOC,使用 LHAL 库驱动外设十分方便,因为其对通用外设进行了统一的封装,在使用博流的不同芯片时他们的接口一致,方便使用和移植。而 SOC 则是作为特殊部分使用,如 GLB、HBN、PDS、AON 等等。
一、了解 LHAL 库和小安派-Eyes-S1 外设
LHAL 库配备了一个结构体作为通用外设的配置工具——struct bflb_device_s
struct bflb_device_s {
const char *name;uint32_t reg_base;
uint8_t irq_num;
uint8_t idx;
uint8_t sub_idx;
uint8_t dev_type;
void *user_data;
};
parameter | description |
name | 外设名称 |
reg_base | 外设寄存器基地址 |
irq_num | 外设中断号 |
idx | 外设 id |
idx | 外设 id,例如 UART0、UART1 |
sub_idx | 外设子 id,例如 DMA0_CH0、DMA0_CH1 |
dev_type | 外设类型 |
user_data | 用户变量 |
name | 外设名称 |
name | 外设名称 |
对芯片的所有操作其实都是基于对寄存器的配置,所以该结构体的成员中较为重要的为 reg_base 和 irq_num ,有了这两个才能操作外设寄存器和外设中断。
在配置之前,我们也得先初始化结构体获得它的句柄,有两种方式
1.bflb_device_get_by_name 通过 name 获取
2.bflb_device_get_by_id 通过 dev_type 和 idx 获取
获得的句柄会在一个 table 表中,详情可以看 lhal/config/xxx/device_table.c 文件。
小安派-Eyes-S1 所支持的外设 LHAL 库 API 有如下:√ 表示已支持,× 表示未支持,-表示没有该外设
parameter | BL616/BL618 |
ADC | √ |
CAM | × |
CKS | √ |
DAC | √ |
DMA | √ |
EFUSE | √ |
EMAC | √ |
FLASH | √ |
GPIO | √ |
I2C | √ |
IR | √ |
MJPEG | √ |
PWM_v1 | - |
PWM_v2 | √ |
RTC | √ |
SEC_AES | √ |
SEC_SHA | √ |
SEC_TRNG | √ |
SEC_PKA | √ |
SPI | √ |
TIMER | √ |
UART | √ |
USB_v1 | - |
USB_v2 | √ |
WDG | √ |
1.头文件 bflb_gpio.h
2.gpio mode
gpio 的模式可以设置为四种,分别是输入、输出、模拟、复用
#define GPIO_INPUT (0 << GPIO_MODE_SHIFT)
#define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT)
#define GPIO_ANALOG (2 << GPIO_MODE_SHIFT)
#define GPIO_ALTERNATE (3 << GPIO_MODE_SHIFT)
3.gpio pupd
gpio 可以选择上拉、下拉、浮空
#define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT)
#define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT)
#define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT)
4.gpio smt
gpio 滤波开关
#define GPIO_SMT_DIS (0 << GPIO_SMT_SHIFT)
#define GPIO_SMT_EN (1 << GPIO_SMT_SHIFT)
5.gpio drive
gpio 输出能力选择
#define GPIO_DRV_0 (0 << GPIO_DRV_SHIFT)
#define GPIO_DRV_1 (1 << GPIO_DRV_SHIFT)
#define GPIO_DRV_2 (2 << GPIO_DRV_SHIFT)
#define GPIO_DRV_3 (3 << GPIO_DRV_SHIFT)
6.gpio init trig mode
gpio 外部中断的触发模式
#define GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE 0
#define GPIO_INT_TRIG_MODE_SYNC_RISING_EDGE 1
#define GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL 2
#define GPIO_INT_TRIG_MODE_SYNC_HIGH_LEVEL 3
#if defined(BL702)
#define GPIO_INT_TRIG_MODE_ASYNC_FALLING_EDGE 4
#define GPIO_INT_TRIG_MODE_ASYNC_RISING_EDGE 5
#define GPIO_INT_TRIG_MODE_ASYNC_LOW_LEVEL 6
#define GPIO_INT_TRIG_MODE_ASYNC_HIGH_LEVEL 7
#else
#define GPIO_INT_TRIG_MODE_SYNC_FALLING_RISING_EDGE 4
#define GPIO_INT_TRIG_MODE_ASYNC_FALLING_EDGE 8
#define GPIO_INT_TRIG_MODE_ASYNC_RISING_EDGE 9
#define GPIO_INT_TRIG_MODE_ASYNC_LOW_LEVEL 10
#define GPIO_INT_TRIG_MODE_ASYNC_HIGH_LEVEL 11
#endif
7.gpio uart function
每个 gpio 都可以选择到 Uart 的任意一个功能,当然区别是在初始化时的选择
#define GPIO_UART_FUNC_UART0_RTS 0
#define GPIO_UART_FUNC_UART0_CTS 1
#define GPIO_UART_FUNC_UART0_TX 2
#define GPIO_UART_FUNC_UART0_RX 3
#define GPIO_UART_FUNC_UART1_RTS 4
#define GPIO_UART_FUNC_UART1_CTS 5
#define GPIO_UART_FUNC_UART1_TX 6
#define GPIO_UART_FUNC_UART1_RX 7
#if defined(BL808) || defined(BL606P)
#define GPIO_UART_FUNC_UART2_RTS 8
#define GPIO_UART_FUNC_UART2_CTS 9
#define GPIO_UART_FUNC_UART2_TX 10
#define GPIO_UART_FUNC_UART2_RX 11
#endif
三、gpio 的初始化及使用
1.bflb_gpio_init
说明: gpio 的初始化函数
void bflb_gpio_init(struct bflb_device_s *dev, uint8_t pin, uint32_t cfgset);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
cfgset | gpio 配置项:gpio mode、gpio function、gpio pupd、gpio smt、gpio drive,多个配置需要使用"与"连接 |
2.bflb_gpio_deinit
说明: 反初始化 gpio,默认为输入浮空状态
void bflb_gpio_deinit(struct bflb_device_s *dev, uint8_t pin);
parameter
| description |
dev | 设备句柄 |
pin | gpio pin |
3.bflb_gpio_set
说明: gpio 输出高电平
void bflb_gpio_set(struct bflb_device_s *dev, uint8_t pin);
4.bflb_gpio_reset
说明: gpio 输出低电平
void bflb_gpio_reset(struct bflb_device_s *dev, uint8_t pin);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
5.bflb_gpio_read
说明: 读取 gpio 电平
bool bflb_gpio_read(struct bflb_device_s *dev, uint8_t pin);
parameter | description |
dev | 设备句柄 |
pin | gpio pin |
return | true 为 高电平,false 为低电平 |
四、示例——GPIO 输出点亮 LED 灯、GPIO 输入采集电平并打印
直接用 SDK 里的 GPIO 示例稍作修改。并逐步解释代码实现。
查看原理图,这里已经标注了预留的接口,需要飞线(幸好找到一个合适的座子)
1.main
#include "bflb_gpio.h"
#include "bflb_mtimer.h"
#include "board.h"