串行外设接口(SPI)
1、简介
SPI(Serial Peripheral Interface,串行外设接口)是Motorola公司推出的一种同步串行接口技术,是一种高速的、全双工、同步的通信总线。SPI以主从方式工作,通常有一个主设备和一个或多个从设备,通过4根信号线完成通信:
- SCLK:串行时钟线,由主设备输出
- MOSI(SDO):主设备数据输出,从设备数据输入
- MISO(SDI):主设备数据输入,从设备数据输出
- CS:片选信号,由主设备控制
CI14LP芯片的SPI控制器支持:
- 主/从模式(SPI_MASTER / SPI_SLAVE)
- SPI / SSP / Microwire 三种传输帧格式
- 4种相位极性组合(CPHA/CPOL)
- 同时收发/只发/只收/EEPROM Read四种传输模式
- 4~32bit数据位宽
- DMA传输(收发FIFO触发深度可配)
- 中断模式
SPI频率可配范围(主频相关):
| 主频 |
SPI可配频率范围 |
| 73.728M |
73K ~ 9.216M |
| 49.152M |
49K ~ 6.144M |
| 24.576M |
25K ~ 3.072M |
| 12.288M |
13K ~ 1.536M |
2、API
2.1 基础配置
| 函数名 |
描述 |
| spi_init |
SPI初始化(结构体方式一次性配置主从/格式/频率/位宽等) |
| spi_enable |
SPI控制器使能 |
| spi_set_freq |
设置SPI时钟频率 |
| spi_set_mode |
设置主从模式 |
| spi_set_format |
设置传输帧格式(SPI/SSP/Microwire) |
| spi_set_phase_polarity |
设置相位和极性(CPHA/CPOL) |
| spi_set_data_width |
设置数据位宽(4~32bit) |
| spi_set_trans_mode |
设置传输模式(收发/只发/只收/EEPROM读) |
| spi_set_cs_mode |
设置片选模式 |
| spi_txfifo_empty_maskclk |
TX FIFO空时是否屏蔽时钟 |
| spi_rxfifo_full_maskclk |
RX FIFO满时是否屏蔽时钟 |
| spi_rx_sample_enable |
接收采样使能 |
| spi_rx_sample_delay |
接收采样延迟配置 |
2.2 DMA配置
| 函数名 |
描述 |
| spi_dma_mode_en |
SPI DMA模式使能(RX/TX方向) |
| spi_dma_txfifo_threshold |
DMA TX FIFO触发深度配置(1~16) |
| spi_dma_rxfifo_threshold |
DMA RX FIFO触发深度配置(2~8) |
2.3 传输数据量查询
| 函数名 |
描述 |
| spi_get_txfifo_valid_cnt |
获取TX FIFO中有效数据个数 |
| spi_get_rxfifo_valid_cnt |
获取RX FIFO中有效数据个数 |
| spi_set_dframe_num |
设置单次传输数据帧个数 |
| spi_already_trans_dframe |
查询已传输的数据帧个数 |
2.4 中断处理
| 函数名 |
描述 |
| spi_irq_mask_config |
SPI中断屏蔽配置 |
| spi_get_irq_raw_status |
获取原始中断状态(屏蔽前) |
| spi_get_irq_mask_status |
获取屏蔽后中断状态 |
| spi_clear_irq |
清除中断标志 |
| spi_get_status |
查询SPI状态(忙/FIFO空/FIFO满) |
| wait_spi_translate_flag |
等待SPI传输完成(超时参数) |
2.5 数据传输
| 函数名 |
描述 |
| spi_send_recv |
收发数据(轮询方式,结构体配置) |
| spi_polling_send_data |
轮询方式发送单笔数据 |
| spi_polling_recv_data |
轮询方式接收单笔数据 |
| spi_tx_data |
写发送FIFO(需确保FIFO不满) |
| spi_rx_data |
读接收FIFO(需确保FIFO非空) |
| spi_dma_mode_send |
DMA方式发送数据 |
| spi_dma_mode_recv |
DMA方式接收数据 |
2.6 Microwire配置
| 函数名 |
描述 |
| spi_microwire_init |
Microwire模式初始化(结构体配置) |
| spi_microwire_handshake_en |
握手使能 |
| spi_microwire_set_ctrlbits |
控制字长度设置(1~16bit) |
| spi_microwire_trans_type |
传输类型(顺序/非顺序) |
| microwire_trans_direction |
传输方向(发送/接收) |
3、关键类型
| 类型 |
说明 |
| spi_format_t |
帧格式:SPI_FORMAT_SPI / SSP / MICROWIRE |
| spi_phase_polarity_t |
相位极性:SPI_CPHA_1_CPOL_LOW、SPI_CPHA_2_CPOL_LOW、SPI_CPHA_1_CPOL_HIGH、SPI_CPHA_2_CPOL_HIGH |
| spi_mode_t |
主从模式:SPI_MASTER、SPI_SLAVE |
| spi_trans_mode_t |
传输模式:SPI_TRANS_TX_RX(同时收发)、SPI_TRANS_TX_ONLY、SPI_TRANS_RX_ONLY、SPI_TRANS_EEPROM_READ |
| spi_irq_t |
中断类型:TX/RX FIFO上溢、下溢中断,DMA触发中断,SPI_IRQ_ALL |
| spi_status_t |
状态:SPI_STATUS_SPI_BUSY、TXFIFO_FULL、TXFIFO_EMPTY、RXFIFO_FULL、RXFIFO_EMPTY |
| spi_dma_t |
DMA方向:SPI_DMA_RX、SPI_DMA_TX |
| spi_microwire_type_t |
Microwire类型:SPI_MICROWIRE_NONSEQUENTIAL(每帧带控制信号)、SPI_MICROWIRE_SEQUENTIAL(仅首帧带控制信号) |
| spi_microwire_dir_t |
Microwire方向:SPI_MICROWIRE_DIR_SEND、SPI_MICROWIRE_DIR_RECV |
| spi_config_t |
初始化结构体:mode、format、phase_polarity、trans_mode、current_freq、data_width、dma、txfifo_threshold、rxfifo_threshold、irq、rxfull_maskclk、txempty_maskclk、slave_tx_en |
| microwire_config_t |
Microwire配置结构体:ctrl_bits、handshake_flag、type |
4、示例
1) 以下代码初始化SPI为主机模式,发送并接收数据:
#include "ci14lp_spi.h"
spi_config_t spi_config;
void spi_demo(void)
{
uint32_t send_buf[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
uint32_t recv_buf[8] = {0};
//SPI主机模式配置
spi_config.mode = SPI_MASTER; //主机模式
spi_config.format = SPI_FORMAT_SPI; //SPI帧格式
spi_config.phase_polarity = SPI_CPHA_1_CPOL_LOW; //模式0
spi_config.trans_mode = SPI_TRANS_TX_RX; //同时收发
spi_config.current_freq = 1 * SPI_FREQ_MHZ; //1MHz
spi_config.data_width = 8; //8bit数据宽度
spi_config.dma = DISABLE; //不使用DMA
spi_config.irq = DISABLE; //不使用中断
spi_config.slave_tx_en = ENABLE;
spi_init(&spi_config);
//发送8笔数据并接收8笔数据
spi_send_recv(&spi_config, send_buf, 8, recv_buf, 8);
}
2) 以下代码以DMA方式接收SPI数据(外挂SPI器件读取场景):
#include "ci14lp_spi.h"
uint32_t spi_recv_buf[64] = {0};
void spi_dma_recv_demo(void)
{
//使能SPI RX方向DMA
spi_dma_mode_en(SPI_DMA_RX, ENABLE);
spi_dma_rxfifo_threshold(4);
//DMA方式接收64笔数据
spi_dma_mode_recv((uint32_t)spi_recv_buf, 64);
}
5、其它
- SPI时钟为主频的4分之1再分频得到,分频范围为2-254,且只支持偶数分频。
- 使用SPI引脚前需要通过GPIO复用接口(
gpio_set_pad_reuse)将对应管脚配置为SPI功能。
- flash专用SPI控制器(DTRC)与本通用SPI相互独立,参见外设API-SPIFLASH。
6、API 参考
本模块接口声明于 driver\ci14lp_chip_driver\inc\ci14lp_spi.h,实现位于 driver\ci14lp_chip_driver\src\ci14lp_spi.c。