杰理 SDK 文档中心
首页
首页
  • 项目概览

    • 项目概述与能力地图
    • 构建系统与编译流程
    • 芯片系列与规格
  • 应用示例

    • SPP 与 BLE 双模透传
    • AT 指令串口协议
    • HID 设备应用
    • 蓝牙 Mesh 应用
    • 公共组件与第三方协议
  • 芯片平台支持

    • 外设驱动
    • 电源与充电管理
    • 启动与链接脚本
    • 配置工具与 OTA 资源
  • 协议栈与系统库

    • 蓝牙控制器
    • BTStack 协议栈接口
    • 系统内核与服务
    • OTA 升级机制
  • 文档与参考

    • 蓝牙 AT 协议参考
    • 开发文档与认证信息

外设驱动

本页介绍 fw-AC630N_BT_SDK 中面向 AC630N(bd29 内核)芯片的外设驱动体系:UART、ADC、PWM/LED、SPI Flash、SDIO 等设备驱动的分层结构、核心 API、初始化流程与配置方式。

Purpose and Scope

本页覆盖 AC630N 蓝牙 SDK 中**外设驱动(Peripheral Drivers)**这一完整能力,包括:

  • 驱动分层架构:应用层 → 设备抽象层(include_lib/driver/device/)→ CPU 驱动层(include_lib/driver/cpu/bd29/asm/ 与 cpu/bd29/)→ 硬件寄存器
  • UART 串口驱动:控制器数量、平台数据配置宏、设备操作接口
  • ADC 采样驱动:通道映射、PMU 电源通道、采样与电压换算 API
  • PWM/LED 驱动:闪烁模式、亮度控制、时钟源配置
  • SPI Flash 与 SDIO 主机初始化等存储类外设
  • 设备操作抽象(struct device_operations)与设备注册机制

以下内容不属于本页范围,由其他目录页覆盖:蓝牙协议栈(GATT/SPP)、音频编解码、电源管理策略、系统时钟与中断控制器。本页只描述外设本身的驱动实现与使用方式。

Overview

AC630N 是杰理科技(Jieli Tech)面向 TWS 耳机、音箱等低功耗蓝牙音频应用的 SoC。其 SDK 采用经典的三层驱动模型:

  1. 设备抽象层(include_lib/driver/device/):定义统一设备接口(如 device/uart.h、device/spiflash.h),通过 struct device_operations 描述设备的打开、读、写、控制、关闭等标准操作,使上层应用可以以统一方式访问不同外设。
  2. CPU 驱动层(include_lib/driver/cpu/bd29/asm/ + cpu/bd29/):针对 bd29 内核实现具体外设,如 uart_dev.c 实现 UART 控制器寄存器级驱动,adc_api.h 声明 ADC 采样 API,pwm_led.h 提供 LED 呼吸/闪烁控制。
  3. 应用层(apps/):如 apps/spp_and_le/at_uart.c 基于 UART 设备接口实现 AT 命令交互。

这种分层设计的意图在于:上层业务代码只依赖稳定的设备接口,不感知具体芯片的寄存器细节,从而保证 SDK 跨芯片(bd19/bd29 等)的可移植性;底层驱动通过 device_operations 结构体向设备框架注册,由设备框架统一管理生命周期(init → open → read/write/ioctrl → close)。

flowchart TD
    subgraph sg_App["应用层 apps/"]
        APP["应用代码<br/>spp_and_le/at_uart.c"]
    end

    subgraph sg_Dev["设备抽象层 include_lib/driver/device/"]
        UART_IF["device/uart.h"]
        SPIFLASH_IF["device/spiflash.h"]
        SDIO_IF["device/sdio_host_init.h"]
        OPS["device/device.h<br/>struct device_operations"]
    end

    subgraph sg_Cpu["CPU 驱动层 cpu/bd29/"]
        UART_IMPL["uart_dev.c / uart_test.c"]
        ADC_API["asm/adc_api.h"]
        PWM_LED["asm/pwm_led.h"]
        CRC16["asm/crc16.h (spi_crc16)"]
    end

    subgraph sg_HW["硬件外设"]
        HW_UART["UART0 / UART1 / UART2"]
        HW_ADC["ADC 通道<br/>PA1..SYS_PLL / PMU"]
        HW_PWM["PWM / LED 引脚"]
        HW_FLASH["SPI Flash / SD 卡"]
    end

    APP -->|"统一设备接口"| UART_IF
    UART_IF --> OPS
    UART_IMPL -->|"注册 uart_dev_ops"| OPS
    ADC_API --> HW_ADC
    PWM_LED --> HW_PWM
    SPIFLASH_IF --> HW_FLASH
    SDIO_IF --> HW_FLASH
    UART_IMPL --> HW_UART

上图中各层职责:

  • 设备抽象层是"契约":device_operations 定义了每个外设必须提供的标准操作集,device/uart.h 等文件给出上层可见的数据结构与操作声明。
  • CPU 驱动层是"实现":uart_dev.c 完成寄存器配置、FIFO 收发、中断处理;adc_api.h 封装 ADC 通道选择与采样;pwm_led.h 封装 LED 时序控制。它们向框架导出 uart_dev_ops 等操作表。
  • 硬件层是最终操作对象:AC630N 提供 3 个 UART 控制器、多路 ADC 输入、PWM 引脚以及 SPI Flash/SD 存储接口。

UART 串口驱动

硬件资源与平台数据

AC630N(bd29)提供 3 个 UART 控制器(UART_NUM = 3)与 4 个输出端口(UART_OUTPORT_NUM = 4),定义于 CPU 驱动层头文件:

#define UART_NUM 		3
#define UART_OUTPORT_NUM 	4

#include "device/uart.h"
#include "device/device.h"

Source: uart.h

UART_OUTPORT_NUM 表示可映射的输出引脚端口数量,意味着同一个 UART 控制器可以通过引脚重映射接到不同的 IO 上,便于 PCB 布局灵活布线。

平台数据配置宏

SDK 通过一组平台数据宏(platform data macro)在编译期静态声明 UART 配置。每个控制器对应一对 BEGIN/END 宏,宏内部自动填充该 UART 的中断号:

#define UART0_PLATFORM_DATA_BEGIN(data) \
	static const struct uart_platform_data data = {

#define UART0_PLATFORM_DATA_END()  \
	.irq 					= IRQ_UART0_IDX, \
};

#define UART1_PLATFORM_DATA_BEGIN(data) \
	static const struct uart_platform_data data = {

#define UART1_PLATFORM_DATA_END()  \
	.irq 					= IRQ_UART1_IDX, \
};

#define UART2_PLATFORM_DATA_BEGIN(data) \
	static const struct uart_platform_data data = {

#define UART2_PLATFORM_DATA_END()  \
	.irq 					= IRQ_UART2_IDX, \
};

Source: uart.h

设计意图:把"哪个中断属于哪个控制器"这类芯片强相关的细节固化在宏中,板级代码(board 配置)只需在 BEGIN/END 之间填写波特率、IO 引脚等板级参数,既避免遗漏必填字段,又保持板级配置的简洁。struct uart_platform_data 的具体字段定义在 include_lib/driver/device/uart.h(设备抽象层),供板级与应用层共同引用。

设备操作注册

UART 驱动向设备框架导出一个 device_operations 实例:

extern const struct device_operations uart_dev_ops;

Source: uart.h

uart_dev_ops 在 cpu/bd29/uart_dev.c 中实现,封装了 open/read/write/ioctrl/close 等标准操作。上层通过设备框架以统一方式访问 UART,例如 AT 命令模块 apps/spp_and_le/at_uart.c 就是基于该接口实现串口命令交互的。cpu/bd29/uart_test.c 则提供了驱动自测入口,演示设备打开、收发、控制命令的完整调用序列。

初始化入口

extern int uart_init(const struct uart_platform_data *);

Source: uart.h

uart_init 接收平台数据指针,完成控制器时钟使能、引脚功能复用(mux)、波特率分频、FIFO 与中断初始化。系统启动早期由驱动初始化流程调用,返回 0 表示成功。

ADC 采样驱动

通道映射

ADC 驱动把所有可采样输入统一编码为 32 位通道号,低 4 位为模拟输入引脚/内部信号,高 16 位为 PMU 子通道:

//AD channel define
#define AD_CH_PA1    (0x0)
#define AD_CH_PA3    (0x1)
#define AD_CH_PA5    (0x2)
#define AD_CH_PA7    (0x3)
#define AD_CH_PA8    (0x4)
#define AD_CH_DP1    (0x5)
#define AD_CH_DM1    (0x6)
#define AD_CH_PB1    (0x7)
#define AD_CH_PB2    (0x8)
#define AD_CH_PB4    (0x9)
#define AD_CH_DP0    (0xA)
#define AD_CH_DM0    (0xB)
#define AD_CH_DB6    (0xC)
#define AD_CH_PMU    (0xD)
#define AD_CH_BT     (0xE)
#define AD_CH_SYS_PLL     (0xF)

Source: adc_api.h

可见 ADC 输入既包含普通 GPIO 引脚(PA1/PA3/PA5/PA7/PA8、PB1/PB2/PB4、DB6),也包含差分输入(DP0/DM0、DP1/DM1)以及内部信号(PMU 电源域、蓝牙射频、系统 PLL)。

PMU 电源监控通道

电源类监控通过 AD_CH_PMU 与 PMU 子通道组合实现:

#define ADC_PMU_CH_VBG       (0x0<<16)
#define ADC_PMU_CH_VDC13     (0x1<<16)
#define ADC_PMU_CH_SYSVDD    (0x2<<16)
#define ADC_PMU_CH_DTEMP     (0x3<<16)
#define ADC_PMU_CH_PROGF     (0x4<<16)
#define ADC_PMU_CH_VBAT      (0x5<<16)     //1/4vbat
#define ADC_PMU_CH_LDO5V     (0x6<<16)     //1/4 LDO5V
#define ADC_PMU_CH_WVDD      (0x7<<16)

#define AD_CH_PMU_VBG   (AD_CH_PMU | ADC_PMU_CH_VBG)
#define AD_CH_VDC13     (AD_CH_PMU | ADC_PMU_CH_VDC13)
#define AD_CH_SYSVDD    (AD_CH_PMU | ADC_PMU_CH_SYSVDD)
#define AD_CH_DTEMP     (AD_CH_PMU | ADC_PMU_CH_DTEMP)
#define AD_CH_PROGF     (AD_CH_PMU | ADC_PMU_CH_PROGF)
#define AD_CH_VBAT      (AD_CH_PMU | ADC_PMU_CH_VBAT)
#define AD_CH_LDO5V     (AD_CH_PMU | ADC_PMU_CH_LDO5V)
#define AD_CH_WVDD      (AD_CH_PMU | ADC_PMU_CH_WVDD)

Source: adc_api.h

设计意图:电池电压(VBAT)按 1/4 分压采样,以适配 ADC 满量程;AD_CH_LDOREF 别名指向 AD_CH_PMU_VBG,供内部基准校准使用。这样上层只需传一个通道号常量,无需关心分压比与子通道编码细节。

采样控制 API

extern void adc_init();
extern void adc_vbg_init();
extern void adc_pmu_ch_select(u32 ch);
extern void adc_pmu_detect_en(u32 ch);
void adc_dump(void);
u32 adc_get_value(u32 ch);
u32 adc_add_sample_ch(u32 ch);
u32 adc_remove_sample_ch(u32 ch);
u32 adc_get_voltage(u32 ch);

Source: adc_api.h

  • adc_init():初始化 ADC 硬件(时钟、采样时序)。
  • adc_vbg_init():初始化带隙基准(VBG),为电压换算提供基准值。
  • adc_pmu_ch_select(ch) / adc_pmu_detect_en(ch):选择/使能 PMU 内部通道检测。
  • adc_add_sample_ch(ch) / adc_remove_sample_ch(ch):动态增删轮询采样通道。SDK 的 ADC 采用周期轮询机制,ADC_MAX_CH 定义为 10,即最多同时轮询 10 个通道;新增通道返回状态码,可用于判断是否超出容量。
  • adc_get_value(ch):返回指定通道的原始采样值(ADC 码)。
  • adc_get_voltage(ch):返回换算后的电压值(基于 VBG 基准与分压系数),上层(如电量显示)应优先使用此接口。
  • adc_dump():调试用,打印各通道采样状态。

此外还提供电源目标档位换算接口 get_sysvdd_aims_level(aims_mv)、get_vdc13_aims_level(aims_mv)、get_mvddio_aims_level(aims_mv),以及低电量检测 adc_check_vbat_lowpower() 与基准校准标志 set_change_vbg_value_flag(),供电源管理模块调用。

PWM/LED 驱动

PWM 驱动在 AC630N 上主要面向 LED 指示灯控制,提供基于 PWM 的亮度调节与多种闪烁时序。其 API 按功能可分为四组。

初始化与开关

void pwm_led_init(const struct led_platform_data *user_data);
void pwm_led_set_on(void);
void pwm_led_set_off(void);

Source: pwm_led.h(另见同文件 set_on/set_off 声明 L161-L162)

pwm_led_init 接收 struct led_platform_data(LED 引脚映射、默认亮度等板级参数),完成 PWM 定时器与 IO 初始化。pwm_led_set_on/off 用于全局开关 PWM 模块——例如进入低功耗前关闭 PWM 以节省电流。

闪烁模式与显示时序

void pwm_led_mode_set(u8 fre_mode);                    // LED 闪烁模式切换
void pwm_led_display_mode_reset(void);                 // 闪烁状态复位, 重新开始一个周期
void pwm_led_one_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
                               u32 period, u32 start_light_time, u32 light_time);
void pwm_led_double_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright,
                                  u32 period, u32 first_light_time, u32 gap_time, u32 second_light_time);

Sources: pwm_led.h L136、pwm_led.h L146、pwm_led.h L180-L181、pwm_led.h L196-L197

设计意图:驱动把"闪烁模式"抽象为可编程时序参数,而不是硬编码若干固定模式。上层(如连接状态指示)只需指定周期、亮灯时间、灭灯间隔,即可表达"单闪/双闪/呼吸"等任意时序:

  • period:闪烁周期总长
  • start_light_time / first_light_time:周期内首次点亮持续时间
  • gap_time:双闪模式下两次点亮之间的间隔
  • light_time / second_light_time:点亮时长
  • led0_bright / led1_bright:两路 LED 的 PWM 亮度占空比参数

pwm_led_display_mode_reset() 用于在状态切换时立即从头开始一个周期,避免闪烁相位漂移造成观感混乱。

时钟与 IO 驱动能力

void pwm_led_clk_set(enum pwm_led_clk_source src);
void pwm_led_io_max_drive_set(u8 strength);

Sources: pwm_led.h L143、pwm_led.h L158

pwm_led_clk_set 选择 PWM 计数时钟源(影响可实现的闪烁频率精度与功耗);pwm_led_io_max_drive_set 调节 LED IO 的最大驱动电流档位,用于适配不同规格的 LED 灯珠(驱动能力过强会增大功耗,过弱则亮度不足)。

存储类外设:SPI Flash 与 SDIO

SDK 将存储设备同样纳入设备抽象层:

  • include_lib/driver/device/spiflash.h:SPI Flash 设备接口,供代码下载、参数存储、升级镜像存放等场景使用。
  • include_lib/driver/device/sdio_host_init.h:SDIO 主机初始化接口,用于外接 SD 卡等存储介质。
  • include_lib/driver/cpu/bd29/asm/crc16.h 中提供与 SPI 数据完整性相关的校验接口:
void spi_crc16_set(u16 crc);
u16 spi_crc16_get(void);

Source: crc16.h

CRC16 校验用于 SPI Flash 读写链路的错误检测(例如 OTA 升级包校验、参数区写后回读校验),spi_crc16_set 注入校验初值,spi_crc16_get 读取计算后的校验结果。

核心流程

外设初始化时序

sequenceDiagram
    participant SYS as "系统启动 (sys_init)"
    participant UART as "uart_init / uart_dev_ops"
    participant ADC as "adc_init / adc_vbg_init"
    participant PWM as "pwm_led_init"
    participant FLASH as "spiflash 设备"
    participant APP as "应用 (apps/)"

    SYS->>UART: 传递 uart_platform_data<br/>(波特率/IO/IRQ 宏)
    UART-->>SYS: 注册 uart_dev_ops 到设备框架
    SYS->>ADC: adc_init() + adc_vbg_init()
    ADC-->>SYS: 建立 VBG 基准与轮询通道表
    SYS->>PWM: 传递 led_platform_data
    PWM-->>SYS: PWM 定时器与 LED IO 就绪
    SYS->>FLASH: 打开 SPI Flash 设备
    APP->>UART: dev_open/read/write (AT 命令)
    APP->>ADC: adc_get_voltage(AD_CH_VBAT)
    APP->>PWM: pwm_led_one_flash_display(...)

启动顺序的意图:先基准、后应用——ADC 的电压换算依赖 VBG 基准,因此 adc_vbg_init 必须在任何 adc_get_voltage 调用之前完成;UART 的中断号由平台数据宏保证与控制器一一对应,避免手动填写中断号出错。

ADC 轮询采样流程

flowchart TD
    Start([应用需要采样]) --> Add["adc_add_sample_ch(ch)"]
    Add --> Cap{"通道数 < ADC_MAX_CH?"}
    Cap -->|"否"| Fail["返回失败, 通道未加入"]
    Cap -->|"是"| Poll["ADC 周期轮询采样"]
    Poll --> Ready{"采样完成?"}
    Ready -->|"是"| Val["adc_get_value(ch) 原始码"]
    Val --> Volt["adc_get_voltage(ch)<br/>基于 VBG 换算电压"]
    Volt --> Done([上层使用: 电量/按键/检测])
    Ready -->|"否"| Poll

该流程说明 ADC 采用集中轮询 + 按需读取模型:所有通道由同一个采样任务周期驱动,上层通过 adc_add_sample_ch 注册关注通道、adc_remove_sample_ch 注销,避免多任务同时操作 ADC 寄存器造成竞争。这也解释了 ADC_MAX_CH = 10 的容量上限——轮询周期内可容纳的通道数是有限的,注册过多通道会拉长单轮采样周期,影响低时延应用。

使用示例

UART 平台数据声明(板级配置)

在板级 board 配置文件中,通过平台数据宏静态声明 UART0 的配置(波特率、引脚等字段由 struct uart_platform_data 定义,此处展示宏骨架及其自动填充的中断号):

UART0_PLATFORM_DATA_BEGIN(uart0_data)
    .baudrate = 115200,
    /* .tx_pin / .rx_pin 等板级字段按实际硬件填写 */
UART0_PLATFORM_DATA_END()

extern int uart_init(const struct uart_platform_data *);
/* 初始化时: uart_init(&uart0_data); */

Source: uart.h(宏定义)与 uart.h L51(init 声明)

UART0_PLATFORM_DATA_END() 会自动补上 .irq = IRQ_UART0_IDX,这是该宏设计的关键价值:板级代码永远不会写错中断号。

ADC 电压采样(典型调用序列)

电池电压检测是 ADC 最典型的应用。先使能通道,待采样就绪后取电压:

/* 使能 VBAT 通道采样(1/4 分压) */
adc_add_sample_ch(AD_CH_VBAT);

/* 采样完成后获取换算电压 */
u32 vbat_mv = adc_get_voltage(AD_CH_VBAT);

/* 不再需要时移出轮询通道表 */
adc_remove_sample_ch(AD_CH_VBAT);

Source: adc_api.h(API 声明)与 adc_api.h L29(AD_CH_VBAT 定义)

注意 AD_CH_VBAT 是 AD_CH_PMU | ADC_PMU_CH_VBAT 的组合值(0xD | (0x5<<16)),上层无需关心分压系数,驱动在 adc_get_voltage 内部完成换算。

LED 单闪/双闪指示

连接状态指示常用双闪(如配对模式"快闪两下、停顿"):

/* 单闪: 周期 1s, 前 0.1s 点亮 */
pwm_led_one_flash_display(0, 80, 0, 1000, 100, 100);

/* 双闪: 周期 2s, 亮 100ms, 间隔 200ms, 再亮 100ms */
pwm_led_double_flash_display(0, 80, 0, 2000, 100, 200, 100);

/* 状态切换时复位闪烁相位 */
pwm_led_display_mode_reset();

Sources: pwm_led.h L180-L181、pwm_led.h L196-L197、pwm_led.h L146

配置选项

配置项类型默认值说明
UART_NUM宏(int)3AC630N 可用的 UART 控制器数量
UART_OUTPORT_NUM宏(int)4UART 可映射的输出端口(引脚复用)数量
UARTx_PLATFORM_DATA_BEGIN/END宏—UARTx 平台数据声明骨架,END 自动填充 IRQ_UARTx_IDX
uart_platform_data.irq枚举(int)IRQ_UARTx_IDX控制器对应中断号(由宏自动写入)
ADC_MAX_CH宏(int)10ADC 轮询通道表最大容量
AD_CH_*宏(u32)见头文件ADC 输入通道编码(低 4 位引脚/信号,高 16 位 PMU 子通道)
ADC_PMU_CH_*宏(u32)0x0<<16 ~ 0x7<<16PMU 电源监控子通道,VBAT/LDO5V 为 1/4 分压
led_platform_datastruct板级定义LED 引脚映射与默认亮度参数
PWM 时序参数u32/u16调用方指定period、light_time、gap_time、led0/1_bright 等

API 参考

UART

int uart_init(const struct uart_platform_data *data)

  • 描述:初始化指定 UART 控制器(时钟、引脚、波特率、FIFO、中断)。
  • 参数:data — 板级 UART 平台数据(由 UARTx_PLATFORM_DATA_BEGIN/END 宏生成)。
  • 返回:0 成功;非 0 失败。

const struct device_operations uart_dev_ops

  • 描述:UART 设备操作表,经设备框架供上层以统一接口调用(open/read/write/ioctrl/close)。

ADC

void adc_init(void)

  • 描述:初始化 ADC 硬件与轮询采样任务。系统启动早期调用。

void adc_vbg_init(void)

  • 描述:初始化带隙基准(VBG),必须在任何电压换算前完成。

void adc_pmu_ch_select(u32 ch) / void adc_pmu_detect_en(u32 ch)

  • 参数:ch — ADC_PMU_CH_* 子通道。
  • 描述:选择/使能 PMU 内部通道检测(VBAT、SYSVDD、DTEMP 等)。

u32 adc_add_sample_ch(u32 ch) / u32 adc_remove_sample_ch(u32 ch)

  • 参数:ch — AD_CH_* 通道编码。
  • 返回:非 0 表示操作成功(0 可能表示通道已满或未注册)。
  • 描述:将通道加入/移出周期轮询采样表;加入时受 ADC_MAX_CH 容量限制。

u32 adc_get_value(u32 ch)

  • 参数:ch — AD_CH_* 通道编码。
  • 返回:ADC 原始采样码。

u32 adc_get_voltage(u32 ch)

  • 参数:ch — AD_CH_* 通道编码。
  • 返回:换算后的电压值(mV 量纲,基于 VBG 基准与分压系数)。

u8 get_sysvdd_aims_level(u16 aims_mv) / get_vdc13_aims_level(u16 aims_mv) / get_mvddio_aims_level(u16 aims_mv)

  • 参数:aims_mv — 目标电压(mV)。
  • 返回:达到该目标所需的电源档位值,供电源管理 LDO/DCDC 配置。

u32 adc_check_vbat_lowpower(void)

  • 返回:电池低电量状态标志,供低功耗策略判断。

PWM/LED

void pwm_led_init(const struct led_platform_data *user_data)

  • 参数:user_data — LED 板级配置(引脚、默认亮度)。
  • 描述:初始化 PWM 定时器与 LED IO。

void pwm_led_mode_set(u8 fre_mode)

  • 参数:fre_mode — 闪烁频率模式。
  • 描述:切换 LED 闪烁模式(不同频率档位)。

void pwm_led_clk_set(enum pwm_led_clk_source src)

  • 参数:src — PWM 计数时钟源。
  • 描述:选择 PWM 时钟源,影响可实现的频率精度与功耗。

void pwm_led_one_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright, u32 period, u32 start_light_time, u32 light_time)

  • 描述:配置单闪时序:周期 period,起始延时 start_light_time 后点亮 light_time;led0_bright/led1_bright 为两路 PWM 亮度。

void pwm_led_double_flash_display(u8 led_index, u16 led0_bright, u16 led1_bright, u32 period, u32 first_light_time, u32 gap_time, u32 second_light_time)

  • 描述:配置双闪时序:亮 first_light_time → 灭 gap_time → 亮 second_light_time,总周期 period。

void pwm_led_set_on(void) / void pwm_led_set_off(void) / void pwm_led_io_max_drive_set(u8 strength)

  • 描述:PWM 模块全局开关;IO 最大驱动电流档位设置。

SPI Flash 校验

void spi_crc16_set(u16 crc) / u16 spi_crc16_get(void)

  • 描述:设置/读取 SPI 链路 CRC16 校验值,用于 Flash 读写完整性验证。

故障模式、边界情况与并发

故障模式

故障场景表现处理方式
ADC 通道表溢出adc_add_sample_ch 在注册第 11 个通道时失败调用方需检查返回值;ADC_MAX_CH = 10 是硬上限,应优先移除低频通道
UART 中断号错配收发无响应或数据错乱由 UARTx_PLATFORM_DATA_END() 宏强制注入 IRQ_UARTx_IDX,从机制上消除手写错误
VBG 基准未初始化adc_get_voltage 换算值异常(偏大/偏小)严格保证启动顺序:adc_vbg_init() 先于任何电压读取
SPI Flash 读写丢数据OTA 升级失败、参数丢失使用 spi_crc16_set/get 做写后回读校验,发现 CRC 不匹配则重写或报错
LED 闪烁相位漂移状态切换后闪烁节拍错乱调用 pwm_led_display_mode_reset() 复位时序,从头开始新周期

边界情况与并发

  • ADC 轮询模型天然串行:所有通道由单一轮询任务驱动,上层不直接操作 ADC 寄存器,因此无需加锁即可多任务共享 ADC;代价是单通道采样频率受通道总数制约。低时延应用应控制注册通道数。
  • UART 中断上下文:uart_dev_ops 的读写接口在中断驱动下工作,上层在中断回调中做耗时操作会阻塞串口吞吐,应只做数据搬运、把业务处理放到任务上下文(如 AT 命令解析即采用此模式,见 apps/spp_and_le/at_uart.c)。
  • 低功耗约束:PWM 在睡眠前应通过 pwm_led_set_off() 关闭,否则 PWM 时钟会阻止进入深睡眠并持续耗电;ADC 的 VBAT 检测是低功耗唤醒后首要任务之一,需在唤醒早期重新使能通道。
  • PMU 通道分压:ADC_PMU_CH_VBAT 与 ADC_PMU_CH_LDO5V 按 1/4 分压,电压换算必须考虑该系数;直接使用 adc_get_value 拿原始码做阈值判断会得到错误结论,应使用 adc_get_voltage。

性能与运维注意事项

  • ADC 采样周期:轮询周期与注册通道数成正比。电量显示等低频需求建议间隔读取,不要把高频采样通道与低频通道混在同一轮询表中。
  • UART 波特率与 FIFO:波特率在 uart_platform_data 中静态配置,运行期修改波特率需要重新走 ioctrl 流程;AT 调试口与业务口建议分用不同控制器(共 3 个)。
  • PWM 亮度与功耗权衡:pwm_led_io_max_drive_set 的驱动能力越高,LED 越亮但功耗越大;量产固件应按灯珠规格书设定档位,避免过驱动导致电池续航下降。
  • 驱动自测:cpu/bd29/uart_test.c 提供 UART 驱动自测代码,硬件调试时可借此快速区分"驱动问题"与"硬件连接问题"。
  • 配置工具:cpu/bd29/tools/AC630N_config_tool/conf/source/board/uart_v1.lua 表明 UART 配置也参与芯片配置工具(board 配置脚本)的生成流程,修改串口映射时应保持 C 平台数据与配置脚本一致。

扩展点

  • 新增外设驱动:实现 struct device_operations(open/read/write/ioctrl/close),在 CPU 驱动层注册后即可被设备框架与上层统一使用——UART 驱动正是这一模式的范例。
  • 新增 UART 控制器复用:UART_OUTPORT_NUM = 4 提供引脚重映射能力;扩展板级平台数据即可让同一控制器输出到不同 IO。
  • 扩展 ADC 通道:通道编码空间(低 4 位 + 高 16 位 PMU 子通道)留有扩展余量;新增内部信号只需追加 AD_CH_*/ADC_PMU_CH_* 宏定义与采样分支。
  • 扩展 LED 时序:pwm_led_*_display 系列接口以参数化时序表达闪烁模式,新指示需求(如三闪、呼吸渐变)可在此基础上新增参数化接口,无需改动底层 PWM 定时器。

相关链接

  • UART 设备抽象层:device/uart.h
  • UART CPU 驱动实现:cpu/bd29/uart_dev.c、cpu/bd29/uart_test.c
  • UART 应用示例(AT 命令):apps/spp_and_le/at_uart.c
  • ADC 驱动 API:asm/adc_api.h
  • PWM/LED 驱动 API:asm/pwm_led.h
  • SPI Flash 设备:device/spiflash.h、CRC16:asm/crc16.h
  • SDIO 主机初始化:device/sdio_host_init.h
  • 外设驱动头文件汇总:include_lib/driver/cpu/bd29/asm/uart.h

说明:本文档基于已读取的驱动头文件与目录结构撰写。部分实现细节(如 uart_dev.c 中寄存器级操作、struct uart_platform_data 的完整字段列表)位于预编译库或未在本轮探索范围内读取的实现文件中,如需深入可在对应源码文件中进一步核实。

Next
电源与充电管理