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

    • AD23N SDK 概述与芯片平台
    • 工程结构与模块划分
  • 快速开始

    • 开发环境搭建与工具链
    • 编译构建指南
    • 烧录与固件升级工具
  • 应用框架与产品工作流

    • 应用入口与模式调度
    • 音乐播放应用
    • MIDI 解码与键盘演奏
    • 录音应用
    • LINEIN 与扩音应用
    • USB 从设备应用
    • 待机、软关机与空闲检测
    • 公共 UI 与 LED 显示
  • 音频子系统

    • 音频解码器框架
    • 音频编码器框架
    • 音效算法库
    • 音频管理与输出通路
  • 存储与文件系统

    • 文件系统层
    • NOR Flash 与虚拟机存储
    • 设备与设备管理
  • 系统服务与运行时

    • 消息机制与事件分发
    • 按键扫描与输入处理
    • 电源管理与低功耗控制
    • 定时器与系统任务
  • 外设驱动与平台

    • CPU 平台与启动流程
    • USB 协议栈与主机/设备驱动
    • SPI 与通用外设接口
  • 固件升级与构建工具

    • 固件升级机制
    • 编译后处理与镜像打包
    • 构建系统与命令行工具

USB 从设备应用

本页介绍 AD23N 平台上「USB 从设备(Device/Slave)应用」的完整实现:从 usb_slave_app() 主循环、HID 按键转发、红外按键表,到 USB 配置接口与编译开关,涵盖该功能在固件中的端到端行为。

Purpose and Scope

本页聚焦 SDK 中 sdk/app/src/mbox_flash/usb_slave/ 目录所实现的 USB 从设备应用层,即当设备作为 USB Device 接入主机(PC)时,由固件驱动的应用行为:

  • usb_slave_app() 主循环:USB 启动、消息轮询、退出/切换逻辑
  • usb_slave_key_msg_filter() 按键过滤与 HID 键码转发(USB 音频按键:播放/暂停、上一首/下一首、音量加减)
  • 红外遥控按键表(IRFF00_USB_SLAVE_* 系列宏)
  • 底层 usb_config.h 提供的 USB 配置/中断注册接口

本页不涉及:USB 协议栈内部实现(HID/MSD 类驱动、usb_stack.h)、USB Host 主机模式(usb_host.h)、USB PHY 物理层(usb_phy.h)以及音频解码链路。这些属于 SDK 底层库(sdk/include_lib/device/usb/)与独立模块,由各自的库文档/源码说明。本页仅描述应用层如何调用这些接口。

Overview

AD23N 是杰理科技(Jieli)面向音频/存储类应用的 MCU 平台。其 SDK 中,USB 模块支持 双角色:既可作 Host(读 U 盘),也可作 Device/从设备(被 PC 识别为 U 盘或音频设备)。本页所描述的「USB 从设备应用」即设备角色(Device Mode)下的应用层封装。

该应用的核心职责:

  1. 模式进入:通过 usb_device_mode(0, 0) 将 USB 控制器切到设备模式,再调用 usb_start() 枚举 USB 设备。
  2. 大容量存储(MSD):若编译配置启用了 MASSSTORAGE_CLASS,主循环中会反复调用 USB_MassStorage(NULL) 维持 U 盘功能;可选的 TCFG_USB_EXFLASH_UDISK_ENABLE 会把外部 Flash(ext_flsh)映射为 U 盘介质。
  3. HID 音频控制:当启用 HID_CLASS 时,本机的物理按键/红外遥控事件被翻译为 USB HID 音频控制键码(播放/暂停、上一首、下一首、音量加、音量减),通过 usb_hid_control() 上报给主机,实现「按键控制 PC 播放器」的典型使用场景。
  4. 上下文保存/恢复:进入时保存 DAC 采样率与音量,退出时恢复,保证切到其他工作模式(音乐、蓝牙等)后音频环境不被破坏。
  5. 消息驱动的退出/切换:通过 MSG_PC_OUT(拔线)与 MSG_CHANGE_WORK_MODE(用户切模式)消息退出从设备模式。

编译上,整个模块由 TCFG_PC_EN 控制编译,USB 功能本身由 HAS_USB_EN 宏使能(Makefile 中默认 -DHAS_USB_EN=0,实际由工程配置覆盖)。

Architecture

flowchart TD
    subgraph sg_App["应用层 (app/src/mbox_flash/usb_slave)"]
        App["usb_slave_app()"]
        KeyFilter["usb_slave_key_msg_filter()"]
        HIDApi["hid_key_api()"]
    end

    subgraph sg_Key["输入子系统"]
        KeyTable["key_table_sel()"]
        IRTable["IRFF00_USB_SLAVE_* 红外键表"]
        MsgQ["消息队列 get_msg()"]
    end

    subgraph sg_Drv["USB 驱动/类层"]
        USBStack["usb_start() / usb_stop() / usb_pause()"]
        DeviceMode["usb_device_mode(0,0)"]
        HIDCtrl["usb_hid_control()"]
        MassStorage["USB_MassStorage()"]
        USBConfig["usb_config() / usb_release() (usb_config.h)"]
    end

    subgraph sg_Media["存储介质"]
        ExtFlash["ext_flsh (外部 Flash)"]
    end

    subgraph sg_Audio["音频环境"]
        DAC["dac_sr / dac_vol"]
    end

    App -->|"注册/注销"| KeyTable
    KeyTable --> IRTable
    App --> MsgQ
    App --> USBStack
    App --> DeviceMode
    App --> HIDApi
    HIDApi --> HIDCtrl
    App --> MassStorage
    MassStorage --> ExtFlash
    App --> DAC
    USBConfig -.->|"底层配置接口"| USBStack
    KeyFilter --> HIDApi

架构说明:

  • usb_slave_app() 是整个从设备应用的状态机主体:它按顺序完成 USB 初始化、注册按键表、打开存储介质、启动 USB,然后进入无限消息循环。
  • 输入路径有两条:物理按键/红外遥控经 key_table_sel() 注册的过滤表 usb_slave_key_msg_filter() 转换为系统消息;hid_key_api() 再把播放/音量类消息转换为 USB HID 音频控制键码上报主机。
  • 存储路径:USB_MassStorage() 依赖 ext_flsh 设备(由 TCFG_USB_EXFLASH_UDISK_ENABLE 控制),并通过 IOCTL_SET_READ_USE_CACHE 等 ioctl 优化读性能。
  • 音频路径:进入/退出时保存并恢复 DAC 采样率与音量,避免模式切换后音频参数残留。

主循环实现分析

启动序列:usb_slave_app()

函数入口首先保存当前音频环境(DAC 采样率与音量),随后注册按键过滤表、切换 USB 设备模式、按需打开外部 Flash 作为 U 盘介质,最后启动 USB 枚举:

void usb_slave_app(void)
{
    u32 dac_sr = dac_sr_read();
    u8 temp_vol = dac_vol('r', 0);
    key_table_sel(usb_slave_key_msg_filter);

    /* usb_sof_trim(NULL, NULL); */
    usb_device_mode(0, 0);
#if TCFG_USB_EXFLASH_UDISK_ENABLE
    void *device = dev_open("ext_flsh", 0);
    if (device != NULL) {
        dev_ioctl(device, IOCTL_SET_READ_USE_CACHE, 1);
        dev_ioctl(device, IOCTL_SET_CACHE_SYNC_ISR_EN, 0);
    } else {
        log_info("dev open err\n");
    }
#endif
    usb_start();

Source: usb_slave.c

关键设计意图:

  • 先保存、后修改:dac_sr_read() / dac_vol('r', 0) 在改动前记录采样率与音量,配合函数末尾的恢复代码,保证模式切换是「无痕」的。
  • key_table_sel(usb_slave_key_msg_filter):把按键消息过滤器注册为当前模式的键表,之后所有按键/红外事件都先经过该过滤函数;退出时以 key_table_sel(NULL) 注销,避免消息泄漏到其他模式。
  • usb_device_mode(0, 0):强制 USB 控制器进入 Device 模式(参数 0 表示 USB 控制器编号)。usb_sof_trim 被注释掉,说明该平台未启用 SOF 时钟微调。
  • 缓存开启策略:对 ext_flsh 打开读缓存(IOCTL_SET_READ_USE_CACHE=1)但关闭 ISR 内缓存同步(IOCTL_SET_CACHE_SYNC_ISR_EN=0),这是典型的「大块顺序读优先」配置——U 盘场景下读多写少,读缓存显著提升传输速率,而关闭 ISR 同步可减少中断负载。
  • usb_start():真正启动 USB 设备枚举,之后主机才能识别到设备。

消息循环与退出路径

    int msg[2];
    u32 err;
    while (1) {
#if (USB_DEVICE_CLASS_CONFIG & MASSSTORAGE_CLASS)
        USB_MassStorage(NULL);
#endif
        err = get_msg(2, &msg[0]);
        bsp_loop();
        if (MSG_NO_ERROR != err) {
            msg[0] = NO_MSG;
            log_info("get msg err 0x%x\n", err);
        }

        switch (msg[0]) {
#if (USB_DEVICE_CLASS_CONFIG & MASSSTORAGE_CLASS)
        case MSG_SDMMCA_IN:
            log_info("MSG_SDMMCA_IN");
            break;
        case MSG_SDMMCA_OUT:
            log_info("MSG_SDMMCA_OUT");
            break;
#endif

            /* #if TCFG_CFG_TOOL_ENABLE */
#if (USB_DEVICE_CLASS_CONFIG & HID_CLASS)
        case MSG_PREV_FILE:
            log_info("PR\n");
            hid_key_api(USB_AUDIO_PREFILE, 1);
            break;
        case MSG_NEXT_FILE:
            log_info("NE\n");
            hid_key_api(USB_AUDIO_NEXTFILE, 1);
            break;
        case MSG_PP:
            log_info("PP\n");
            hid_key_api(USB_AUDIO_PP, 1);
            break;
        case MSG_VOL_DOWN:
            log_info("DO\n");
            hid_key_api(USB_AUDIO_VOLDOWN, 1);
            break;
        case MSG_VOL_UP:
            log_info("UP\n");
            hid_key_api(USB_AUDIO_VOLUP, 1);
            break;
#else
        case MSG_VOL_DOWN:
        case MSG_VOL_UP:
            break;
#endif
        case MSG_PC_OUT:
            log_info("MSG_PC_OUT\n");
            usb_stop();
            work_mode++;
        case MSG_CHANGE_WORK_MODE:
            usb_pause();
            goto __out_t_usb_slave;
        case MSG_500MS:
        default:
            ap_handle_hotkey(msg[0]);
            break;
        }
    }
__out_t_usb_slave:
#if TCFG_USB_EXFLASH_UDISK_ENABLE
    if (device != NULL) {
        dev_close(device);
    }
#endif
    dac_vol(0, temp_vol);
    dac_sr_api(dac_sr);
    key_table_sel(NULL);
}

Source: usb_slave.c

循环的每个迭代:

  1. USB_MassStorage(NULL):维持 U 盘类处理(仅当 MASSSTORAGE_CLASS 编译进配置)。传入 NULL 表示使用默认 USB 设备实例。
  2. get_msg(2, &msg[0]):从系统消息队列取消息(最多 2 个参数)。出错时置 NO_MSG 并打印错误码。
  3. bsp_loop():喂狗/后台任务,保证在长阻塞场景下系统不超时。
  4. switch 分发:
    • MSG_SDMMCA_IN/OUT:SD 卡插入/拔出提示(仅日志)。
    • MSG_PREV_FILE/NEXT_FILE/MSG_PP/MSG_VOL_DOWN/MSG_VOL_UP:在启用 HID_CLASS 时映射为 USB 音频 HID 键码并上报;未启用 HID 时音量键被静默丢弃。
    • MSG_PC_OUT:PC 拔线消息——先 usb_stop() 停 USB,再 work_mode++ 递增工作模式;注意该 case 没有 break,会顺势落入 MSG_CHANGE_WORK_MODE 分支,执行 usb_pause() 并 goto 退出标签。这是刻意的 fall-through:拔线即视为需要退出从设备模式。
    • MSG_CHANGE_WORK_MODE:用户主动切换模式,暂停 USB 后退出。
    • MSG_500MS/默认:交给 ap_handle_hotkey() 处理通用热键。

退出路径(__out_t_usb_slave)严格逆序清理:关闭 ext_flsh → 恢复音量 → 恢复采样率 → 注销按键表。清理顺序与初始化顺序完全对称,这是嵌入式模式切换代码的规范写法,避免资源泄漏与状态残留。

HID 按键转发

#if (USB_DEVICE_CLASS_CONFIG & HID_CLASS)
static void hid_key_api(u32 key, u8 flag)
{
    usb_hid_control(key);
    if (flag) {
        usb_hid_control(0);
    }
}
#endif

Source: usb_slave.c

hid_key_api(key, flag) 每次调用发送两次 HID 控制:先按下键码,再(flag 非零时)发送 0 释放键码。这种「按下+释放」成对上报是 HID 键盘/媒体键的标准行为——主机只有收到释放事件后才会把媒体键当作一次完整按键,否则会视为长按重复触发。

核心流程

从设备模式的完整生命周期(进入 → 运行 → 退出):

sequenceDiagram
    participant U as 用户/主机PC
    participant A as usb_slave_app()
    participant K as 按键/红外子系统
    participant H as HID类驱动
    participant M as MSD类驱动
    participant F as ext_flsh

    U->>A: 进入 USB 从设备模式
    A->>A: 保存 dac_sr / dac_vol
    A->>K: key_table_sel(usb_slave_key_msg_filter)
    A->>A: usb_device_mode(0, 0)
    A->>F: dev_open("ext_flsh") + 开启读缓存
    A->>A: usb_start() 枚举设备
    U->>M: 主机读写 U 盘 (SCSI 命令)
    M->>F: 数据读写
    F-->>M: 数据
    M-->>U: 传输完成
    U->>K: 按下媒体键 (播放/上一首/音量...)
    K->>A: get_msg() 返回 MSG_PP/MSG_VOL_UP 等
    A->>H: hid_key_api(USB_AUDIO_XX, 1)
    H->>U: HID 上报 (按下+释放)
    U->>A: 拔线 (MSG_PC_OUT) 或切模式
    A->>A: usb_stop() / usb_pause()
    A->>F: dev_close(device)
    A->>A: 恢复 dac_vol / dac_sr
    A->>K: key_table_sel(NULL) 注销
    A-->>U: 退出,进入下一工作模式

流程要点:

  • 从设备应用是消息驱动 + 轮询模型:主循环通过 get_msg() 阻塞等待系统消息,同时每次迭代执行 USB_MassStorage() 维持存储类事务、bsp_loop() 维持系统心跳。
  • HID 控制属于「旁路」路径:按键消息不直接操作本地音频,而是被翻译成 USB 媒体键码发送给主机,由主机端播放器响应——这正是「音箱按键控制 PC 音乐」产品的核心交互。
  • 退出有两个触发源:MSG_PC_OUT(物理拔线,由 USB 驱动检测产生)与 MSG_CHANGE_WORK_MODE(用户主动切换)。两者都会走同一个清理出口,保证清理逻辑只有一份。

按键与红外遥控映射

usb_slave_key_msg_filter() 声明于 usb_slave.h:

u16 usb_slave_key_msg_filter(u8 key_status, u8 key_num, u8 key_type);
void usb_slave_app(void);

Source: usb_slave.h

该过滤器作为按键子系统回调,把 key_status(短按/长按/连击等)、key_num(键号)、key_type(类型)翻译为系统消息(MSG_*),供主循环 switch 消费。

usb_slave_key.c 在 KEY_IR_EN 开启时定义了完整的红外(IR)键表,将 21 个 IR 键位映射到不同按键形态下的消息:

#define IRFF00_USB_SLAVE_SHORT_UP		\
                                /*00*/    MSG_PP,\
							/*01*/    MSG_NEXT_WORKMODE,\
							/*02*/    MSG_MUTE,\
							/*03*/    MSG_PP,\
							/*04*/    MSG_PREV_FILE,\
							/*05*/    MSG_NEXT_FILE,\
							/*06*/    NO_MSG,\
							/*07*/    MSG_VOL_DOWN,\
							/*08*/    MSG_VOL_UP,\
							/*09*/    MSG_0,\
                                /*10*/    MSG_NEXT_PLAYMODE,\
							/*11*/    MSG_NEXT_DEVICE,\
							/*12*/    MSG_1,\
							/*13*/    MSG_2,\
							/*14*/    MSG_3,\
							/*15*/    MSG_4,\
							/*16*/    MSG_5,\
							/*17*/    MSG_6,\
							/*18*/    MSG_7,\
							/*19*/    MSG_8,\
							/*20*/    MSG_9

Source: usb_slave_key.c

同文件还定义了 IRFF00_USB_SLAVE_LONG、IRFF00_USB_SLAVE_HOLD、IRFF00_USB_SLAVE_LONG_UP 以及(KEY_DOUBLE_CLICK_EN 开启时的)IRFF00_USB_SLAVE_DOUBLE_KICK / IRFF00_USB_SLAVE_TRIPLE_KICK 等变体,分别覆盖长按、长按保持、长按抬起、双击、三击形态。长按/保持形态下仅 04/05 键(上一曲/下一曲快退快进)和 07/08(音量)有效,其余键位为 NO_MSG。

设计意图:IR 键表把「遥控器按键形态」与「业务消息」解耦。短按直接对应播放/切歌/音量等即时操作;长按/保持用于快进快退这类需要持续触发的操作;数字键(MSG_0~MSG_9)与 MSG_NEXT_WORKMODE 等则为用户提供进入其他模式/选曲的入口。整个表随模式通过 key_table_sel() 动态切换,因此同一遥控器在不同工作模式下可复用相同的 IR 键码而映射不同的行为。

配置选项

USB 从设备应用的编译与行为由以下宏控制:

宏类型默认值说明
HAS_USB_ENbool0(Makefile 中 -DHAS_USB_EN=0)USB 功能总开关;usb_slave.h 中 #if HAS_USB_EN 门控整个模块的头文件与接口
TCFG_PC_ENbool由 app_config.h 工程配置决定USB 从设备应用(PC 模式)编译开关,usb_slave.c 整个文件在 #if TCFG_PC_EN 内
USB_DEVICE_CLASS_CONFIG位掩码由工程配置决定决定设备枚举的类组合:MASSSTORAGE_CLASS 启用 U 盘,HID_CLASS 启用 HID 音频控制
TCFG_USB_EXFLASH_UDISK_ENABLEbool由工程配置决定启用后把 ext_flsh(外部 Flash)作为 U 盘介质,并打开读缓存
KEY_IR_ENbool由工程配置决定是否编译红外遥控键表(usb_slave_key.c 的 IR 表)
KEY_DOUBLE_CLICK_ENbool由工程配置决定是否编译双击/三击 IR 键表变体

宏开关依据:Makefile、usb_slave.h、usb_slave_key.c

Makefile 将 usb_slave.c 与 usb_slave_key.c 编入固件,并加入头文件搜索路径 -Iapp/src/mbox_flash/usb_slave(见 Makefile 与 Makefile)。

API 参考

应用层接口(usb_slave.h)

void usb_slave_app(void)

启动并驻留 USB 从设备应用。保存音频上下文 → 注册按键表 → 切设备模式 → 打开 U 盘介质 → usb_start() → 进入消息循环,直到收到 MSG_PC_OUT / MSG_CHANGE_WORK_MODE 后清理退出。

  • 参数:无
  • 返回:无(函数在消息循环内;仅通过 goto __out_t_usb_slave 返回)
  • 前置条件:HAS_USB_EN 与 TCFG_PC_EN 均使能
  • 副作用:修改工作模式(work_mode++)、DAC 采样率/音量被临时保存并恢复

u16 usb_slave_key_msg_filter(u8 key_status, u8 key_num, u8 key_type)

按键消息过滤器回调,由 key_table_sel() 注册。将按键事件映射为系统消息,返回值为映射后的消息 ID(如 MSG_PP、MSG_VOL_UP)。

  • 参数:key_status(按键形态:短按/长按/保持/抬起/双击/三击)、key_num(键号 0~20)、key_type(按键类型)
  • 返回:u16 消息 ID,NO_MSG 表示忽略该按键

驱动配置接口(usb_config.h)

usb_config.h 声明了 USB 驱动的配置与中断注册接口,供应用/类层使用:

函数作用
u32 usb_config(const usb_dev usb_id)配置指定 USB 控制器
u32 usb_release(const usb_dev usb_id)释放指定 USB 控制器
void *usb_get_ep_buffer(const usb_dev usb_id, u32 ep)获取端点缓冲区(Device 模式)
void *usb_h_get_ep_buffer(const usb_dev usb_id, u32 ep)获取端点缓冲区(Host 模式)
void usb_h_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id)注册 Host 中断
void usb_g_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id)注册 Device(gadget)中断
void usb_sof_isr_reg(const usb_dev usb_id, u8 priority, u8 cpu_id)注册 SOF 帧起始中断
void usb_otg_sof_check_init(const usb_dev id)初始化 OTG SOF 检测
void usb_host_config(usb_dev usb_id) / usb_host_free(usb_dev usb_id)Host 模式配置/释放

Source: usb_config.h

这些接口统一了 Host/Device 双角色的中断与缓冲区管理:usb_g_isr_reg(gadget)对应从设备应用,usb_h_isr_reg(host)对应主机模式,SOF 中断则用于时钟同步(如 USB 音频时钟恢复)。

失败模式与边界情况

消息队列错误

主循环中 get_msg() 返回非 MSG_NO_ERROR 时,消息被强制置为 NO_MSG 并打印 get msg err 0x%x,然后继续循环。这种「容错继续」策略保证瞬时错误不会导致从设备应用崩溃,但连续错误会表现为按键无响应——排查时应优先检查消息队列是否被高优先级中断/其他模块淹没。

存储介质打开失败

TCFG_USB_EXFLASH_UDISK_ENABLE 开启后若 dev_open("ext_flsh") 失败,代码仅打印 dev open err 并继续启动 USB(不提前退出)。此时设备仍可作为 HID 设备工作,但 U 盘功能不可用;且由于 device == NULL,退出路径中的 dev_close(device) 被 if (device != NULL) 保护,不会空指针崩溃。这是「部分降级」设计:USB 枚举不因存储介质缺失而失败。

拔线时序(MSG_PC_OUT fall-through)

MSG_PC_OUT 分支故意不 break 而落入 MSG_CHANGE_WORK_MODE 分支执行 usb_pause() 并退出,顺序是:usb_stop()(停止 USB)→ work_mode++(切换模式)→ usb_pause()(暂停)→ 清理退出。work_mode++ 后无 break 的设计意味着「拔线即切到下一个工作模式」,避免设备停留在空转状态。若后续工程希望拔线后停留本模式,需在该 case 中显式 break 并单独处理。

未启用 HID 时的音量键

当 USB_DEVICE_CLASS_CONFIG 不含 HID_CLASS 时,MSG_VOL_DOWN/MSG_VOL_UP 被空 case 静默丢弃(见 #else 分支)。这是有意的:从设备模式下若无 HID 类,本地音量调节既不能影响主机,也无本地音频播放,直接忽略是合理行为。

编译门控风险

模块依赖多个宏的组合:HAS_USB_EN(功能总开关)、TCFG_PC_EN(应用编译)、KEY_IR_EN(红外表)。Makefile 默认 HAS_USB_EN=0,若工程仅开启 TCFG_PC_EN 而未覆盖 HAS_USB_EN,则 usb_slave.h 中的声明与包含全部失效,链接期会暴露未定义符号——配置时务必三处宏一致。

性能与运维考量

  • 读缓存配置:U 盘读路径通过 IOCTL_SET_READ_USE_CACHE=1 开启 Flash 读缓存,并用 IOCTL_SET_CACHE_SYNC_ISR_EN=0 关闭中断内同步,减少中断上下文开销、提升大块顺序读吞吐;代价是缓存一致性依赖上层时机控制,写入类场景需评估。
  • 主循环负载:每次迭代都执行 USB_MassStorage(NULL),该调用在无 SCSI 命令时应快速返回;bsp_loop() 保证看门狗/低优先级后台任务不被饿死。从设备应用整体为单线程轮询模型,无并发数据竞争,但 USB_MassStorage 与 usb_hid_control 共享 USB 硬件,须保证类驱动自身的事务串行化。
  • SOF 微调被注释:usb_sof_trim(NULL, NULL) 被注释表明当前工程不依赖 SOF 频率校准(通常用于 USB 音频时钟同步场景),如需 USB Audio 时钟精度,可取消注释并结合 usb_sof_isr_reg 使用。

扩展点

  1. 新增媒体键:在 usb_slave.c 的 switch 中增加 MSG_* case,调用 hid_key_api(USB_AUDIO_XXX, 1) 上报新键码;键码集合见 usb/usr/usb_audio_interface.h。
  2. 自定义按键映射:修改 usb_slave_key.c 的 IRFF00_USB_SLAVE_* 表,可任意调整 IR 键位在不同按键形态下的消息;也可扩展 usb_slave_key_msg_filter() 增加对矩阵按键(非 IR)的处理。
  3. 更换 U 盘介质:TCFG_USB_EXFLASH_UDISK_ENABLE 决定介质来源;不开启时 USB_MassStorage 使用默认介质(如 SD 卡/内置 Flash),需按平台类驱动配置。
  4. 退出行为定制:MSG_PC_OUT 分支的 fall-through 与 work_mode++ 逻辑可定制,例如拔线后停留在本模式等待重新插入。
  5. 多 USB 控制器:usb_device_mode(0, 0) 首参为控制器编号;usb_config.h 的接口均带 usb_dev usb_id 参数,支持多控制器平台的扩展。

相关链接

  • usb_slave.c — 应用主循环实现
  • usb_slave.h — 应用接口声明
  • usb_slave_key.c — 红外按键表
  • usb_config.h — USB 驱动配置接口
  • usb_audio_interface.h — USB 音频 HID 键码定义
  • usb_stack.h — USB 设备协议栈头文件
  • Makefile — 编译开关与源文件注册
Prev
LINEIN 与扩音应用
Next
待机、软关机与空闲检测