API GUIDE / SPI Slave / LL
G32S10 SPI Slave LL 接口
LL 层接口:寄存器结构体成员使用小写原寄存器名,寄存器规格名称仍为 SSLVCTRL、SSLVRXC、 SSLVTXC、SSLVRXD、SSLVTXD、SSLVRXN、SSLVTXN 和 SSLVFLR。
1. 资源模型与公开类型
1.1 寄存器块
struct spi_slv_regs {
__IO uint32_t sslvctrl;
__IO uint32_t sslvrxc;
__IO uint32_t sslvtxc;
__I uint32_t sslvrxd;
__O uint32_t sslvtxd;
__IO uint32_t sslvrxn;
__IO uint32_t sslvtxn;
__I uint32_t sslvflr;
};| 寄存器 | 偏移 | 访问属性 | 说明 |
|---|---|---|---|
SSLVCTRL | 0x00 | RW | 选择、环回、状态、复位、聚合 IRQ、CPOL/CPHA 和 RX/TX 使能 |
SSLVRXC | 0x04 | RW | RX 中断掩码、通道、端序、位宽和阈值 |
SSLVTXC | 0x08 | RW | TX 中断掩码、通道、端序、位宽和阈值 |
SSLVRXD | 0x0C | R | RX FIFO 数据寄存器,读取会弹出一个 FIFO entry |
SSLVTXD | 0x10 | W | TX FIFO 数据寄存器,写入会压入一个 FIFO entry |
SSLVRXN | 0x14 | RW | RX 总帧数设置/剩余帧数 |
SSLVTXN | 0x18 | RW | TX 总帧数设置/剩余帧数 |
SSLVFLR | 0x1C | R | TX/RX FIFO 已用和可用 entry 数 |
寄存器结构体成员使用小写原寄存器名,寄存器规格名称仍为 SSLVCTRL、SSLVRXC、SSLVTXC、SSLVRXD、SSLVTXD、SSLVRXN、SSLVTXN 和 SSLVFLR。
2. LL 接口规范
2.1 LL 通用约定
所有 LL 接口均为 static inline,不返回 SDK error_code_t,并遵循以下约定:
spi_slvx必须是有效且已具备模块时钟访问条件的SPI_SLV0或SPI_SLV1。LL 不校验空指针、实例、枚举、位宽、阈值或计数时序。
setter 直接写寄存器或执行 read-modify-write,调用方负责和 IRQ/其他执行上下文同步。
字段 setter 的
value必须满足文档范围;不能依赖寄存器 mask 自动截断来接受非法值。LL 不管理 CPM 模块时钟、BSP 引脚、SoC IRQ 控制器或 HAL 句柄状态。
2.2 选择与环回控制
| 接口 | 参数/返回 | 行为与约束 |
|---|---|---|
ll_spi_slv_toggle_select() | spi_slvx | 向 SSLVCTRL.SEL 写 1,切换一次新/旧 SPI_SLV 选择 |
ll_spi_slv_keep_select() | spi_slvx | 清 SEL,后续控制寄存器写入不再触发切换 |
ll_spi_slv_check_select() | 返回 0/1 | 读取 SEL 位当前值 |
ll_spi_slv_enable_loop() | spi_slvx | 置 SSLVCTRL.LOOP |
ll_spi_slv_disable_loop() | spi_slvx | 清 SSLVCTRL.LOOP |
ll_spi_slv_get_loop_status() | 返回 0/1 | 读取环回使能状态 |
SEL 是 write-1 toggle 位,不是普通的“选择值”字段。每次有意切换只写 1 一次;随后
必须通过 ll_spi_slv_keep_select() 保持其为 0,避免其他 SSLVCTRL read-modify-write
再次切换。
非环回初始化流程需要在复位初始化阶段临时置 LOOP=1,结束后再清零。即使保持环回,
从机也不能自行产生 SCLK 和 CS,仍需主机提供相应信号。
2.3 原始状态读取
| 接口 | 返回值 |
|---|---|
ll_spi_slv_get_raw_status() | SSLVCTRL[24:13] 原始 status mask |
ll_spi_slv_get_tx_rdflag() | TX read flag,置位返回 1 |
ll_spi_slv_get_tx_wrflag() | TX write flag,置位返回 1 |
ll_spi_slv_get_tx_rdempty_err() | TX FIFO read-empty error,置位返回 1 |
ll_spi_slv_get_tx_wrfull_err() | TX FIFO write-full error,置位返回 1 |
ll_spi_slv_get_tx_empty() | TX FIFO empty,置位返回 1 |
ll_spi_slv_get_tx_full() | TX FIFO full,置位返回 1 |
ll_spi_slv_get_rx_rdflag() | RX read flag,置位返回 1 |
ll_spi_slv_get_rx_wrflag() | RX write flag,置位返回 1 |
ll_spi_slv_get_rx_rdempty_err() | RX FIFO read-empty error,置位返回 1 |
ll_spi_slv_get_rx_wrfull_err() | RX FIFO write-full error,置位返回 1 |
ll_spi_slv_get_rx_empty() | RX FIFO empty,置位返回 1 |
ll_spi_slv_get_rx_full() | RX FIFO full,置位返回 1 |
这些接口读取 SSLVCTRL 只读状态,不执行清除。TX_WRFLAG 还用于 TX DMA request,RX_RDFLAG 还用于 RX DMA request。
2.4 复位、时钟、聚合 IRQ 与总线模式
| 接口 | 参数/返回 | 行为与约束 |
|---|---|---|
ll_spi_slv_set_reset() | value 0 至 63 | 写 SSLVCTRL.RESET,硬件复位完成后字段自动归零 |
ll_spi_slv_get_reset_value() | 返回 0 至 63 | 读取 RESET 当前计数值 |
ll_spi_slv_clear_irq_flags() | spi_slvx | 清 SSLVCTRL.IRQ_FLAG 聚合标志,不清独立状态源 |
ll_spi_slv_get_irq_flags() | 返回 0/1 | 读取聚合 IRQ 标志 |
ll_spi_slv_mask_ckg() | spi_slvx | 置 CKG_MASK,屏蔽/门控模块内部时钟 |
ll_spi_slv_unmask_ckg() | spi_slvx | 清 CKG_MASK,放开模块内部时钟 |
ll_spi_slv_get_ckg_mask() | 返回 0/1 | 读取内部时钟 mask |
ll_spi_slv_mask_irq() | spi_slvx | 置 active-high IRQ_MASK,屏蔽聚合 IRQ |
ll_spi_slv_unmask_irq() | spi_slvx | 清 IRQ_MASK,放开聚合 IRQ |
ll_spi_slv_get_irq_mask() | 返回 0/1 | 1 表示聚合 IRQ 已屏蔽 |
ll_spi_slv_set_pha() | value 0/1 | 设置 CPHA |
ll_spi_slv_get_pha() | 返回 0/1 | 读取 CPHA |
ll_spi_slv_set_pol() | value 0/1 | 设置 CPOL |
ll_spi_slv_get_pol() | 返回 0/1 | 读取 CPOL |
ll_spi_slv_enable_tx() | spi_slvx | 置 TX_EN |
ll_spi_slv_disable_tx() | spi_slvx | 清 TX_EN |
ll_spi_slv_get_tx_status() | 返回 0/1 | 读取 TX_EN |
ll_spi_slv_enable_rx() | spi_slvx | 置 RX_EN |
ll_spi_slv_disable_rx() | spi_slvx | 清 RX_EN |
ll_spi_slv_get_rx_status() | 返回 0/1 | 读取 RX_EN |
复位时间近似为:
reset_time = reset_count / internal_module_clock_hz
例如内部模块时钟为 100 MHz、reset_count=10 时,复位时间约为 100 ns。CKG_MASK 控制模块内部时钟门控,不代表从机能产生串行 SCLK。
2.5 RX 中断 mask
以下 LL 接口直接操作 SSLVRXC[31:26]。所有 mask 位均为 active-high:1 表示屏蔽,
0 表示放开。
| 接口 | 行为 |
|---|---|
ll_spi_slv_set_rx_irq_mask() | 一次设置全部 RX 原始 mask;入参使用已移位的 SSLVRXC_*_IRQ_MASK 位 |
ll_spi_slv_get_rx_irq_mask() | 返回全部已移位 RX 原始 mask 位 |
ll_spi_slv_set_rx_empty_irq_mask() / ll_spi_slv_get_rx_empty_irq_mask() | 设置/读取 RX empty mask |
ll_spi_slv_set_rx_full_irq_mask() / ll_spi_slv_get_rx_full_irq_mask() | 设置/读取 RX full mask |
ll_spi_slv_set_rx_rdflag_irq_mask() / ll_spi_slv_get_rx_rdflag_irq_mask() | 设置/读取 RX read-flag mask |
ll_spi_slv_set_rx_wrflag_irq_mask() / ll_spi_slv_get_rx_wrflag_irq_mask() | 设置/读取 RX write-flag mask |
ll_spi_slv_set_rx_rdempty_irq_mask() / ll_spi_slv_get_rx_rdempty_irq_mask() | 设置/读取 RX read-empty error mask |
ll_spi_slv_set_rx_wrfull_irq_mask() / ll_spi_slv_get_rx_wrfull_irq_mask() | 设置/读取 RX write-full error mask |
单 bit setter 的 value 只能为 0 或 1;getter 返回 0 或 1。
2.6 RX 格式与阈值
| 接口 | 参数/返回 | 行为与约束 |
|---|---|---|
ll_spi_slv_set_rx_ch() | value 0/1/2 | 设置 RX single/dual/quad;3 保留 |
ll_spi_slv_get_rx_ch() | 返回 0 至 3 | 读取 RX channel 原始字段 |
ll_spi_slv_set_rx_endian() | value 0 至 3 | 设置 RX 端序 |
ll_spi_slv_get_rx_endian() | 返回 0 至 3 | 读取 RX 端序字段 |
ll_spi_slv_set_rx_bitwidth() | value 4 至 32 | 设置 RX 实际帧 bit 数;0 至 3、33 至 63 保留 |
ll_spi_slv_get_rx_bitwidth() | 返回原始 6 bit 字段 | 读取 RX bitwidth |
ll_spi_slv_set_rx_rdthr() | value 0 至 255 | 设置 RX read threshold 原始 8 bit 字段 |
ll_spi_slv_get_rx_rdthr() | 返回 0 至 255 | 读取 RX read threshold |
ll_spi_slv_set_rx_wrthr() | value 0 至 255 | 设置 RX write threshold 原始 8 bit 字段 |
ll_spi_slv_get_rx_wrthr() | 返回 0 至 255 | 读取 RX write threshold |
RX_RDFLAG 的主要条件为 RX_FILL > RX_RDTHR,因此 RX_RDTHR=0 表示 FIFO 中大于
0 个 entry 时置位,RX_RDTHR=127 表示大于 127 个 entry 时置位。FIFO 深度为 128,
HAL 将四个阈值统一限制为 0 至 127;LL 虽可写完整 8 bit 字段,调用方仍应根据 FIFO
深度和规格定义选择有效值。
2.7 TX 中断 mask
以下 LL 接口直接操作 SSLVTXC[31:26],mask 语义同样为 1 屏蔽、0 放开。
| 接口 | 行为 |
|---|---|
ll_spi_slv_set_tx_irq_mask() | 一次设置全部 TX 原始 mask;入参使用已移位的 SSLVTXC_*_IRQ_MASK 位 |
ll_spi_slv_get_tx_irq_mask() | 返回全部已移位 TX 原始 mask 位 |
ll_spi_slv_set_tx_empty_irq_mask() / ll_spi_slv_get_tx_empty_irq_mask() | 设置/读取 TX empty mask |
ll_spi_slv_set_tx_full_irq_mask() / ll_spi_slv_get_tx_full_irq_mask() | 设置/读取 TX full mask |
ll_spi_slv_set_tx_rdflag_irq_mask() / ll_spi_slv_get_tx_rdflag_irq_mask() | 设置/读取 TX read-flag mask |
ll_spi_slv_set_tx_wrflag_irq_mask() / ll_spi_slv_get_tx_wrflag_irq_mask() | 设置/读取 TX write-flag mask |
ll_spi_slv_set_tx_rdempty_irq_mask() / ll_spi_slv_get_tx_rdempty_irq_mask() | 设置/读取 TX read-empty error mask |
ll_spi_slv_set_tx_wrfull_irq_mask() / ll_spi_slv_get_tx_wrfull_irq_mask() | 设置/读取 TX write-full error mask |
单 bit setter 的 value 只能为 0 或 1;getter 返回 0 或 1。
2.8 TX 格式与阈值
| 接口 | 参数/返回 | 行为与约束 |
|---|---|---|
ll_spi_slv_set_tx_ch() | value 0/1/2 | 设置 TX single/dual/quad;3 保留 |
ll_spi_slv_get_tx_ch() | 返回 0 至 3 | 读取 TX channel 原始字段 |
ll_spi_slv_set_tx_endian() | value 0 至 3 | 设置 TX 端序 |
ll_spi_slv_get_tx_endian() | 返回 0 至 3 | 读取 TX 端序字段 |
ll_spi_slv_set_tx_bitwidth() | value 4 至 32 | 设置 TX 实际帧 bit 数;0 至 3、33 至 63 保留 |
ll_spi_slv_get_tx_bitwidth() | 返回原始 6 bit 字段 | 读取 TX bitwidth |
ll_spi_slv_set_tx_rdthr() | value 0 至 255 | 设置 TX read threshold 原始 8 bit 字段 |
ll_spi_slv_get_tx_rdthr() | 返回 0 至 255 | 读取 TX read threshold |
ll_spi_slv_set_tx_wrthr() | value 0 至 255 | 设置 TX write threshold 原始 8 bit 字段 |
ll_spi_slv_get_tx_wrthr() | 返回 0 至 255 | 读取 TX write threshold |
TX_WRFLAG 的主要条件为 TX_UNFILL > TX_WRTHR,该标志同时可触发 TX DMA
request。规格中 TX_RDTHR 的编码语义从“大于 1 个数据”开始,即编码 0 对应大于
1 个数据、编码 1 对应大于 2 个数据;不能把它解释为编码 0 对应大于 0。HAL 统一只
接受 0 至 127 的阈值,LL 调用方需要按具体阈值字段的规格语义使用原始值。
2.9 FIFO 数据、传输计数与水位
| 接口 | 参数/返回 | 行为与约束 |
|---|---|---|
ll_spi_slv_read_data() | 返回 32 bit 数据 | 读取 SSLVRXD 并弹出一个 RX FIFO entry;必须先确认 RX FIFO 非空 |
ll_spi_slv_write_data() | value 32 bit | 写 SSLVTXD 并压入一个 TX FIFO entry;必须先确认 TX FIFO 有空间 |
ll_spi_slv_set_rx_num() | value 32 bit | 设置 RX 总帧数;必须在 RX_EN=0 时写入 |
ll_spi_slv_get_rx_num() | 返回 32 bit | 读取 RX 当前剩余帧数 |
ll_spi_slv_set_tx_num() | value 32 bit | 设置 TX 总帧数;必须在 TX_EN=0 时写入 |
ll_spi_slv_get_tx_num() | 返回 32 bit | 读取 TX 当前剩余帧数 |
ll_spi_slv_get_tfifo_num() | 返回 0 至 128 | 读取 TX FIFO 已填充 entry 数 |
ll_spi_slv_get_tfifo_space() | 返回 0 至 128 | 读取 TX FIFO 未填充 entry 数 |
ll_spi_slv_get_rfifo_num() | 返回 0 至 128 | 读取 RX FIFO 已填充 entry 数 |
ll_spi_slv_get_rfifo_space() | 返回 0 至 128 | 读取 RX FIFO 未填充 entry 数 |
LL 的 RX/TX 计数 setter 分别只约束对应方向;HAL 的 拒绝同时写两个寄存器。
3. 寄存器位域与接口映射
3.1 SSLVCTRL
| 位域 | 位 | 主要接口 | 说明 |
|---|---|---|---|
SEL | 31 | toggle_select / keep_select / check_select | write-1 toggle |
LOOP | 30 | enable_loop / disable_loop / get_loop_status | 环回控制 |
| TX/RX 状态 | 24:13 | get_raw_status 和各状态 getter | 只读状态 |
RESET | 12:7 | set_reset / get_reset_value | 6 bit 复位计数 |
IRQ_FLAG | 6 | clear_irq_flags / get_irq_flags | 聚合 IRQ 状态 |
CKG_MASK | 5 | mask_ckg / unmask_ckg / get_ckg_mask | 内部时钟门控 mask |
IRQ_MASK | 4 | mask_irq / unmask_irq / get_irq_mask | 聚合 IRQ active-high mask |
CPHA | 3 | set_pha / get_pha | SPI 相位 |
CPOL | 2 | set_pol / get_pol | SPI 极性 |
TX_EN | 1 | enable_tx / disable_tx / get_tx_status | TX 路径使能 |
RX_EN | 0 | enable_rx / disable_rx / get_rx_status | RX 路径使能 |
3.2 SSLVRXC 与 SSLVTXC
| 位域 | 位 | 说明 |
|---|---|---|
EMPTY_IRQ_MASK | 31 | FIFO empty IRQ mask,1 屏蔽 |
FULL_IRQ_MASK | 30 | FIFO full IRQ mask,1 屏蔽 |
RDFLAG_IRQ_MASK | 29 | read flag IRQ mask,1 屏蔽 |
WRFLAG_IRQ_MASK | 28 | write flag IRQ mask,1 屏蔽 |
RDEMPTY_ERR_IRQ_MASK | 27 | read-empty error IRQ mask,1 屏蔽 |
WRFULL_ERR_IRQ_MASK | 26 | write-full error IRQ mask,1 屏蔽 |
CHANNEL | 25:24 | 0 single、1 dual、2 quad、3 保留 |
ENDIAN | 23:22 | 数据端序编码 |
BITWIDTH | 21:16 | 实际帧位宽,4 至 32 有效 |
RDTHR | 15:8 | read threshold 原始字段 |
WRTHR | 7:0 | write threshold 原始字段 |
3.3 SSLVFLR
| 位域 | 位 | LL 接口 |
|---|---|---|
TX_FILL | 31:24 | ll_spi_slv_get_tfifo_num() |
TX_UNFILL | 23:16 | ll_spi_slv_get_tfifo_space() |
RX_FILL | 15:8 | ll_spi_slv_get_rfifo_num() |
RX_UNFILL | 7:0 | ll_spi_slv_get_rfifo_space() |