一个SPI可以有几个从设备
在zynq开发和外部ad相连时,经常需要spi进行寄存器配置,连线一定要注意,MOSI和MISO信号为SDI和SDO。
在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。
备注:只选一个ss,可以不用指定。(感觉,还没测试)
这是xspips.c中定义的函数,发送和接收有 XSpiPs_Transfer 和 XSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。
一、轮询模式
米联客参考代码,SpiPs_Init中部分和官方例程流程一样,SpiPs_Read和SpiPs_Send为精简版感觉,也可以直接使用xspips.c中 XSpiPs_PolledTransfer 函数替代。
int SpiPs_Init(u16 SpiDeviceId)
{
int Status;
XSpiPs_Config *SpiConfig;
/*
* Initialize the SPI driver so that it's ready to use
*/
SpiConfig = XSpiPs_LookupConfig(SpiDeviceId);
if (NULL == SpiConfig) {
return XST_FAILURE;
}
Status = XSpiPs_CfgInitialize((&SpiInstance), SpiConfig,
SpiConfig->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* The SPI device is a slave by default and the clock phase
* have to be set according to its master. In this example, CPOL is set
* to quiescent high and CPHA is set to 1.
*/
Status = XSpiPs_SetOptions((&SpiInstance), XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XSpiPs_SetClkPrescaler(&SpiInstance, XSPIPS_CLK_PRESCALE_4);
XSpiPs_SetSlaveSelect((&SpiInstance),0X00);
/*
* Enable the device.
*/
XSpiPs_Enable((&SpiInstance));
return XST_SUCCESS;
}
void SpiPs_Read(u8 *ReadBuffer,int ByteCount)
{
int Count;
u32 StatusReg;
do{
StatusReg = XSpiPs_ReadReg(SpiInstance.Config.BaseAddress,
XSPIPS_SR_OFFSET);
}while(!(StatusReg & XSPIPS_IXR_RXNEMPTY_MASK));
/*
* Reading the Rx Buffer
*/
for(Count = 0; Count < ByteCount; Count++){
ReadBuffer[Count] = SpiPs_RecvByte(
SpiInstance.Config.BaseAddress);
}
}
void SpiPs_Send(u8 *SendBuffer, int ByteCount)
{
u32 StatusReg;
int TransCount = 0;
/*
* Fill the TXFIFO with as many bytes as it will take (or as
* many as we have to send).
*/
while ((ByteCount > 0) &&
(TransCount < XSPIPS_FIFO_DEPTH)) {
SpiPs_SendByte(SpiInstance.Config.BaseAddress,
*SendBuffer);
SendBuffer++;
++TransCount;
ByteCount--;
}
/*
* Wait for the transfer to finish by polling Tx fifo status.
*/
do {
StatusReg = XSpiPs_ReadReg(
SpiInstance.Config.BaseAddress,
XSPIPS_SR_OFFSET);
} while ((StatusReg & XSPIPS_IXR_TXOW_MASK) == 0);
}
使用时:
二、中断模式
事件
spi中断和uart很像,返回值都是事件。中断处理程序根据事件处理。但是官方例程中中断处理没做什么处理,只是对于不是传输完成的事件进行error++。
和uart一样,额外指定中断处理程序。
这里指定的处理程序是针对spi状态,尤其针对FIFO的状态做一些处理。不是很清楚。