SPI硬件控制主要涉及寄存器操作。
这里仅说明下控制寄存器相关内容。
SPIx_CON: SPIx control register (16bit addressing)寄存器说明:
15 PND r
中断请求标志,当 1Byte 传输完成或 DMA 传输完成时会被硬件置 1。
有 3 种方法清除此标志
向 PCLR 写入‘1’
写 SPIBUF 寄存器来启动一次传输
写 SPICNT 寄存器来启动一次 DMA
14 PCLR w
软件在此位写入‘1’将清除 PND 中断请求标志。
13 IE rw
SPI 中断使能
0: 禁止 SPI 中断
1: 允许中断允许
12 DIR rw
在单向模式或 DMA 操作时设置传输的方向
0: 发送数据
1: 接收数据
11-10 DATW r
SPI 数据宽度设置
00: 1bit 数据宽度
01: 2bit 数据宽度
10: 4bit 数据宽度
11:NA,不可设置为此项
(注:SPI0 支持 1bit,2bit 和 4bit 模式,SPI1/SPI2 只支持 1bit 模式)
9 reserved r
0
8 reserved r
0
7 CSID rw
SPICS 信号极性选择
0: SPICS 空闲时为 0 电平
1: SPICS 空闲时为 1 电平第 9 章 SPI
6 CKID rw
SPICK 信号极性选择
0: SPICK 空闲时为 0 电平
1: SPICK 空闲时为 1 电平
5 UE rw
更新数据边沿选择
0: 在 SPICK 的上升沿更新数据
1: 在 SPICK 的下降沿更新数据
4 SE rw
采样数据边沿选择
0: 在 SPICK 的上升沿采样数据
1: 在 SPICK 的下降沿采样数据
3 BIDIR rw
单向/双向模式选择
0: 单向模式,数据单向传输,同一时刻只能发送或者接收数据。
数据传输方向因收发而改变,所以由硬件控制,不受写 IO 口 DIR 影响。
1: 双向模式,数据双向传输,同时收发数据,但 DMA 只支持一个方向的数
据传输。 数据传输方向设置后不改变,所以由软件控制,通过写 IO 口 DIR 控制
2 CSE rw
SPICS 信号使能
0: 不使用 SPICS 信号
1: 使用 SPICS 信号
1 SLAVE rw
从机模式
0 SPIE rw
SPI 接口使能
0: 关闭 SPI 接口
1: 打开 SPI 接口
根据寄存器相关说明,定义相关宏,方便代码使用:
enum spi_mode {
SPI_MODE_BIDIR_1BIT, //支持SPIx(x=0,1,2),全双工,di接收,do发送
SPI_MODE_UNIDIR_1BIT, //支持SPIx(x=0,1,2),半双工,do分时发送/接收
SPI_MODE_UNIDIR_2BIT, //支持SPIx(x=0),半双工,di & do共2bit分时发送/接收
SPI_MODE_UNIDIR_4BIT, //支持SPIx(x=0),半双工,di & do & d2 & d3共4bit分时发送/接收
};
SPI支持多种位宽。SPI1、2仅支持1bit位宽。
enum spi_role {
SPI_ROLE_MASTER,//主机,0
SPI_ROLE_SLAVE,//从机,1
};
主动机宏定义。
对于寄存器的操作:
#define spi_enable(reg) ((reg)->CON |= BIT(0))//使能
#define spi_disable(reg) ((reg)->CON &= ~BIT(0))//禁能
#define spi_role_slave(reg) ((reg)->CON |= BIT(1))//从机模式
#define spi_role_master(reg) ((reg)->CON &= ~BIT(1))//主机模式
#define spi_cs_en(reg) ((reg)->CON |= BIT(2))//片选使能
#define spi_cs_dis(reg) ((reg)->CON &= ~BIT(2))//片选禁能
#define spi_bidir(reg) ((reg)->CON |= BIT(3))//双向模式
#define spi_unidir(reg) ((reg)->CON &= ~BIT(3))//单向模式
#define spi_smp_edge_rise(reg) ((reg)->CON &= ~BIT(4))//上升沿采样
#define spi_smp_edge_fall(reg) ((reg)->CON |= BIT(4))//下降沿采样
#define spi_ud_edge_rise(reg) ((reg)->CON &= ~BIT(5))//上升沿更新数据
#define spi_ud_edge_fall(reg) ((reg)->CON |= BIT(5))//下降沿更新数据
#define spi_clk_idle_h(reg) ((reg)->CON |= BIT(6))//CK空闲为高电平
#define spi_clk_idle_l(reg) ((reg)->CON &= ~BIT(6))//CK空闲为低电平
#define spi_cs_idle_h(reg) ((reg)->CON |= BIT(7))//CS空闲为高电平
#define spi_cs_idle_l(reg) ((reg)->CON &= ~BIT(7))//CS空闲为低电平
#define spi_data_width(reg, x) ((reg)->CON = (reg->CON&~(3<<10))|((x)<<10))//位宽1、2、4bit
#define spi_dir_in(reg) ((reg)->CON |= BIT(12))//接收
#define spi_dir_out(reg) ((reg)->CON &= ~BIT(12))//发送
#define spi_ie_en(reg) ((reg)->CON |= BIT(13))//允许中断
#define spi_ie_dis(reg) ((reg)->CON &= ~BIT(13))//禁止中断
#define spi_clr_pnd(reg) ((reg)->CON |= BIT(14))//清除中断标志
#define spi_pnd(reg) ((reg)->CON & BIT(15))//中断标志
#define spi_w_reg_con(reg, val) ((reg)->CON = (val))//写控制寄存器
#define spi_r_reg_con(reg) ((reg)->CON)//读控制寄存器
#define spi_w_reg_buf(reg, val) ((reg)->BUF = (val))//写buf寄存器
#define spi_r_reg_buf(reg) ((reg)->BUF)//读buf寄存器
#define spi_w_reg_baud(reg, baud) ((reg)->BAUD = (baud))//写波特率寄存器
#define spi_r_reg_baud(reg) ((reg)->BAUD)//读波特率寄存器
#define spi_w_reg_dma_addr(reg, addr) ((reg)->ADR = (addr))//写DMA起始地址
#define spi_w_reg_dma_cnt(reg, cnt) ((reg)->CNT = (cnt))//写DMA传输个数
至此,SPI硬件相关内容分析完成,主要包括:
1、芯片SPI数量;
2、每个SPI包含的组;
3、每个组包含哪些IO;
4、寄存器说明;
5、寄存器的访问宏定义。
设计时根据芯片资源情况,查看哪些SPI可以使用,分别是哪些组、哪些接口。
对于SPI的选择配置:
#define TCFG_HW_SPI0_ENABLE ENABLE_THIS_MOUDLE
//A组IO: DI: PD2 DO: PD1 CLK: PD0 D2:PB7 D3:PD5
//B组IO: DI: PA14 DO: PD1 CLK: PD0 D2:PA15 D3:PD5
//C组IO: DI: PA6 DO: PA8 CLK: PA3 D2:PA7 D3:PA2
//D组IO: DI: PB8 DO: PB10 CLK: PB5 D2:PB9 D3:PB4
#define TCFG_HW_SPI0_PORT ‘C’
#define TCFG_HW_SPI0_BAUD 48000000L
#define TCFG_HW_SPI0_MODE SPI_MODE_BIDIR_1BIT //SPI_MODE_UNIDIR_1BIT//
#define TCFG_HW_SPI0_ROLE SPI_ROLE_MASTER
#define TCFG_HW_SPI1_ENABLE 0//ENABLE_THIS_MOUDLE
//A组IO: DI: PB2 DO: PB1 CLK: PB0
//B组IO: DI: PC3 DO: PC5 CLK: PC4
#define TCFG_HW_SPI1_PORT ‘A’
#define TCFG_HW_SPI1_BAUD 4000000L
#define TCFG_HW_SPI1_MODE SPI_MODE_BIDIR_1BIT
#define TCFG_HW_SPI1_ROLE SPI_ROLE_MASTER
#define TCFG_HW_SPI2_ENABLE 0//ENABLE_THIS_MOUDLE
//A组IO: DI: PB8 DO: PB10 CLK: PB9
//B组IO: DI: PA13 DO: DM CLK: DP
#define TCFG_HW_SPI2_PORT ‘A’
#define TCFG_HW_SPI2_BAUD 2000000L
#define TCFG_HW_SPI2_MODE SPI_MODE_BIDIR_1BIT
#define TCFG_HW_SPI2_ROLE SPI_ROLE_MASTER
这里提供了SPI0、SPI1、SPI2的选择配置,包括SPI0、SPI1以及SPI2的使能、组的选择、波特率的配置、位宽配置、主从机配置。
该宏定义使用于以下结构体:
struct spi_platform_data {
u8 port; //端口,可选’A’, ‘B’
u8 mode; //模式,位宽和全双工、半双工配置,选项为enum spi_mode中的枚举常量
u8 role; //角色,主从机,选项为enum spi_role中的枚举常量
u32 clk; //波特率
};
#if TCFG_HW_SPI0_ENABLE
const struct spi_platform_data spi0_p_data = {
.port = TCFG_HW_SPI0_PORT,
.mode = TCFG_HW_SPI0_MODE,
.clk = TCFG_HW_SPI0_BAUD,
.role = TCFG_HW_SPI0_ROLE,
};
#endif
#if TCFG_HW_SPI1_ENABLE
const struct spi_platform_data spi1_p_data = {
.port = TCFG_HW_SPI1_PORT,
.mode = TCFG_HW_SPI1_MODE,
.clk = TCFG_HW_SPI1_BAUD,
.role = TCFG_HW_SPI1_ROLE,
};
#endif
#if TCFG_HW_SPI2_ENABLE
const struct spi_platform_data spi2_p_data = {
.port = TCFG_HW_SPI2_PORT,
.mode = TCFG_HW_SPI2_MODE,
.clk = TCFG_HW_SPI2_BAUD,
.role = TCFG_HW_SPI2_ROLE,
};
#endif
以上为SPI的平台级配置。通过该配置来进行相应SPI接口的初始化操作。
9899



被折叠的 条评论
为什么被折叠?



