zedboard(5)spi轮询和中断

一个SPI可以有几个从设备
在zynq开发和外部ad相连时,经常需要spi进行寄存器配置,连线一定要注意,MOSI和MISO信号为SDI和SDO。
zedboard(5)spi轮询和中断_第1张图片
在程序中使用 s32 XSpiPs_SetSlaveSelect(XSpiPs *InstancePtr, u8 SlaveSel) 选择。其实就是吧对应设备的ss拉低。
备注:只选一个ss,可以不用指定。(感觉,还没测试)

zedboard(5)spi轮询和中断_第2张图片
这是xspips.c中定义的函数,发送和接收有 XSpiPs_TransferXSpiPs_PolledTransfer 两个函数,分别采用中断和轮询模式。

  


一、轮询模式

米联客参考代码,SpiPs_Init中部分和官方例程流程一样,SpiPs_Read和SpiPs_Send为精简版感觉,也可以直接使用xspips.cXSpiPs_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);

}

使用时:
zedboard(5)spi轮询和中断_第3张图片
  


二、中断模式

事件
zedboard(5)spi轮询和中断_第4张图片
spi中断和uart很像,返回值都是事件。中断处理程序根据事件处理。但是官方例程中中断处理没做什么处理,只是对于不是传输完成的事件进行error++。
zedboard(5)spi轮询和中断_第5张图片
和uart一样,额外指定中断处理程序。
zedboard(5)spi轮询和中断_第6张图片
zedboard(5)spi轮询和中断_第7张图片
这里指定的处理程序是针对spi状态,尤其针对FIFO的状态做一些处理。不是很清楚。
在这里插入图片描述
zedboard(5)spi轮询和中断_第8张图片

你可能感兴趣的:(ZYNQ系列,fpga开发)