📄 spi.c
字号:
//*------------------------------------------------------------------------------------------------
//* 文件名 : spi.c
//* 功能描述 : SPI接口驱动
//* 作者 : 焦海波
//* 版本 : 0.1
//* 建立日期、时间 : 2008/05/04 14:52
//* 最近修改日期、时间 :
//* 修改原因 :
//*------------------------------------------------------------------------------------------------
//*------------------------------------------ 头文件 ----------------------------------------------
#include "/uCOS-II/ucos_ii.h"
#include "/at91sam7x256/include/AT91SAM7X256.h"
#include "/at91sam7x256/include/lib_AT91SAM7X256.h"
#define OS_GLOBALS
#include "spi.h"
//*-------------------------------------- 函数原型声明区 ------------------------------------------
static void __irqSPIHandler(void);
//*------------------------------------- 常量、变量定义区 -----------------------------------------
static const SPI0_DEV_DESCRIPTOR SPI[2] = {
{AT91C_BASE_SPI0, SPI0_PINS, AT91C_ID_SPI0, AT91C_PA16_SPI0_MISO, SPI_IRQ_PRIOR, __irqSPIHandler},
{AT91C_BASE_SPI1, SPI1_PINS, AT91C_ID_SPI1, AT91C_PA24_SPI1_MISO, SPI_IRQ_PRIOR, __irqSPIHandler}
};
static ST_SPI_DEV_RW *__pstRWOpt;
//*================================================================================================
//* 函 数 区
//*================================================================================================
//*------------------------------------------------------------------------------------------------
//* 函数名称 : __ilSPIPinsConfig
//* 功能描述 : SPI相关引脚配置函数
//* 入口参数 : <u32Pins>[in] 相关外设引脚
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
__inline void __ilSPIPinsConfig(INT32U u32Pins)
{
//* 首先禁止相关引脚中断
AT91C_BASE_PIOA->PIO_IDR = u32Pins;
AT91C_BASE_PIOA->PIO_PPUDR = u32Pins;
AT91C_BASE_PIOA->PIO_ASR = u32Pins;
AT91C_BASE_PIOA->PIO_PDR = u32Pins;
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : __ilSPIConfig
//* 功能描述 : SPI相关控制寄存器配置
//* 入口参数 : <u8SPIDevID>[in] SPI接口占用的外设ID号
//* : <pSPI>[in] SPI相关控制寄存器的基址
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
__inline void __ilSPIConfig(INT8U u8SPIDevID, AT91PS_SPI pSPI)
{
//* 使能SPI输入时钟
AT91C_BASE_PMC->PMC_PCER = 1 << u8SPIDevID;
//* 软件复位SPI
pSPI->SPI_CR = AT91C_SPI_SWRST;
//* 为主机模式,禁止模式故障检测,禁止片选
pSPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
//* 禁止PDC收发
pSPI->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
//* 使能SPI
pSPI->SPI_CR = AT91C_SPI_SPIEN;
//* 禁止SPI时钟
AT91C_BASE_PMC->PMC_PCDR = 1 << u8SPIDevID;
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : __irqSPIHandler
//* 功能描述 : SPI中断服务子函数
//* 入口参数 : 无
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
static void __irqSPIHandler(void)
{
INT32U __uSPIStatus;
__uSPIStatus = SPI[__pstRWOpt->u8SPIPort].pSPI->SPI_SR;
if(__uSPIStatus & AT91C_SPI_RXBUFF)
{
//* 禁止PDC收发器
SPI[__pstRWOpt->u8SPIPort].pSPI->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
//* 禁止SPI时钟输入
AT91C_BASE_PMC->PMC_PCDR = 1<< SPI[__pstRWOpt->u8SPIPort].u8SPIID;
//* 禁止SPI接收结束中断
SPI[__pstRWOpt->u8SPIPort].pSPI->SPI_IDR = AT91C_SPI_RXBUFF;
//* 调用SPI设备用户注册的回调函数
if(__pstRWOpt->pfunCallBack != NULL)
__pstRWOpt->pfunCallBack(__pstRWOpt->pvArg);
}
u8IsNotRecvEnd = OS_FALSE;
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : SPIConfig
//* 功能描述 : 初始配置SPI0
//* 入口参数 : <u8SPIPort>[in] 指定配置的SPI端口号(0代表SPIO,1代表SPI1)
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
void SPIConfig(INT8U u8SPIPort)
{
__ilSPIPinsConfig(SPI[u8SPIPort].u32Pins);
AT91C_BASE_PIOA->PIO_PPUER = SPI[u8SPIPort].u32NeedPullUpPin;
__ilSPIConfig(SPI[u8SPIPort].u8SPIID, SPI[u8SPIPort].pSPI);
//* 向AIC注册SPI中断
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
SPI[u8SPIPort].u8SPIID,
SPI[u8SPIPort].u8IRQPrior,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,
SPI[u8SPIPort].pfunSPIIsr);
AT91C_BASE_AIC->AIC_IECR = 1 << SPI[u8SPIPort].u8SPIID;
//* 禁止所有SPI中断
SPI[u8SPIPort].pSPI->SPI_IDR = 0xFFFFFFFF;
u8IsNotRecvEnd = OS_TRUE;
}
//*------------------------------------------------------------------------------------------------
//* 函数名称 : ReadAndWriteSPIDev
//* 功能描述 : 通过SPI口对相关设备进行读写操作
//* 入口参数 : <u8SPIPort>[in] 指定配置的SPI端口号(0代表SPIO,1代表SPI1)
//* : <pstOpt>[in] 指向具体读写操作指令的指针(ST_SPI_DEV_RW结构体)
//* 出口参数 : 无
//*------------------------------------------------------------------------------------------------
void ReadAndWriteSPIDev(ST_SPI_DEV_RW *pstOpt)
{
INT32U __u32SPIModeVal;
//* 使能SPI时钟输入
AT91C_BASE_PMC->PMC_PCER = 1 << SPI[pstOpt->u8SPIPort].u8SPIID;
//* 首先禁止SPI PDC收发器
SPI[pstOpt->u8SPIPort].pSPI->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
//* 修改SPI模式寄存器,片选指定的SPI设备
__u32SPIModeVal = SPI[pstOpt->u8SPIPort].pSPI->SPI_MR;
__u32SPIModeVal |= AT91C_SPI_PCS;
__u32SPIModeVal &= ~(1 << (pstOpt->u8NPCSPin + 16));
SPI[pstOpt->u8SPIPort].pSPI->SPI_MR = __u32SPIModeVal;
//* 初始化SPI PDC收发器
SPI[pstOpt->u8SPIPort].pSPI->SPI_RPR = (INT32U)pstOpt->pbCmd;
SPI[pstOpt->u8SPIPort].pSPI->SPI_RCR = pstOpt->u8CmdLen;
SPI[pstOpt->u8SPIPort].pSPI->SPI_TPR = (INT32U)pstOpt->pbCmd;
SPI[pstOpt->u8SPIPort].pSPI->SPI_TCR = pstOpt->u8CmdLen;
SPI[pstOpt->u8SPIPort].pSPI->SPI_RNPR = (INT32U)pstOpt->pbData;
SPI[pstOpt->u8SPIPort].pSPI->SPI_RNCR = pstOpt->u32DataLen;
SPI[pstOpt->u8SPIPort].pSPI->SPI_TNPR = (INT32U)pstOpt->pbData;
SPI[pstOpt->u8SPIPort].pSPI->SPI_TNCR = pstOpt->u32DataLen;
//* PDC传输、发送使能
SPI[pstOpt->u8SPIPort].pSPI->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
//* 使能SPI接收结束中断
__pstRWOpt = pstOpt;
SPI[pstOpt->u8SPIPort].pSPI->SPI_IER = AT91C_SPI_RXBUFF;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -