cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
drug490
Visitor
Visitor
237 Views
Registered: ‎07-14-2020

Zynq SPI Slave Interupt mode

Hello, I am working in Zynq SPI Slave interrupt mode, the exchange is going on, but the interrupt processing is not happening, what am I doing wrong, can someone have an example?

My code:

/***************************** Include Files **********************************/

#include <stdio.h>
#include <stdlib.h>
#include "xil_printf.h"
#include "xparameters.h" /* SDK generated parameters */
#include "xspips.h" /* SPI device driver */
#include "xbram.h" /* BRAM device driver */
#include "xscugic.h" /* Interrupt controller device driver */
#include "xil_io.h" /* I/O driver */
#include "Xil_exception.h"
#include "xil_cache.h"
#include "xil_types.h"
#include "sleep.h"

/************************** Constant Definitions *****************************/

#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
#define INTC_DEVICE_ID XPAR_SCUGIC_0_DEVICE_ID
#define SPI_INTR_ID XPAR_XSPIPS_0_INTR // XPAR_XSPIPS_0_INTR or XPS_SPI0_INT_ID ?

#define SGI0_INTR_PRI (0x78) // Highest Priority
#define SGI0_INTR_TRIG (0x03) // Rising-edge Sensitive


/**************************** Type Definitions *******************************/

/***************** Macros (Inline Functions) Definitions *********************/

#define SpiPs_RecvByte(BaseAddress) \
(u8)XSpiPs_In32((BaseAddress) + XSPIPS_RXD_OFFSET)

#define SpiPs_SendByte(BaseAddress, Data) \
XSpiPs_Out32((BaseAddress) + XSPIPS_TXD_OFFSET, (Data))


#define MAX_DATA 100

/************************** Function Prototypes ******************************/

int SpiSlaveInit(u16 DeviceId);

static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiIntrId);

void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount);

void SpiSlaveRead(int ByteCount);

/************************** Variable Definitions *****************************/

static XSpiPs Spi; /* SPI Driver */
static XScuGic IntcInstance; /* GIC Driver */

u8 ReadBuffer[MAX_DATA];

int main(void)
{
int Status;
xil_printf("START \r\n");


Status = SpiSlaveInit(SPI_DEVICE_ID);


Status = SpiSetupIntrSystem(&IntcInstance, &Spi, SPI_INTR_ID); // начальная инициализация GIC и тестирование


while(1)
{
SpiSlaveRead(1);
xil_printf("ReadBuffer[0] = %08x \n\r ", ReadBuffer[0]);
}

xil_printf("STOP \r\n");
return XST_SUCCESS;
}


int SpiSlaveInit(u16 DeviceId) // SPI slave
{
int Status;
XSpiPs_Config *SpiConfig;

/*
* Initialize the SPI device.
*/
SpiConfig = XSpiPs_LookupConfig(DeviceId);


Status = XSpiPs_CfgInitialize(&Spi, SpiConfig, SpiConfig->BaseAddress);


Status = XSpiPs_SelfTest(&Spi);

 

Status = XSpiPs_SetOptions((&Spi), (XSPIPS_CR_CPHA_MASK) | \
(XSPIPS_CR_CPOL_MASK));


XSpiPs_SetRXWatermark((&Spi),1);


XSpiPs_Enable(&Spi); // включение
xil_printf("SPI config finish\r\n");


return XST_SUCCESS;
}


static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr,
XSpiPs *SpiInstancePtr, u16 SpiIntrId)
{
int Status;

XScuGic_Config *IntcConfig; /* Instance of the interrupt controller*/

Xil_ExceptionInit();

/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);


Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
IntcConfig->CpuBaseAddress);


Status = XScuGic_SelfTest(IntcInstancePtr);


/*
* Connect the interrupt controller interrupt handler to the hardware
* interrupt handling logic in the processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
IntcInstancePtr);


// Xil_ExceptionEnable();

/*
* Connect the device driver handler that will be called when an
* interrupt for the device occurs, the handler defined above performs
* the specific interrupt processing for the device.
*/
Status = XScuGic_Connect(IntcInstancePtr, SpiIntrId,
(Xil_ExceptionHandler)XSpiPs_InterruptHandler,
(void *)SpiInstancePtr);


/*
* Enable the interrupt for the Spi device.
*/

XScuGic_Enable(IntcInstancePtr, SpiIntrId);


XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,
(XSpiPs_StatusHandler) SpiHandler);


/*
* Enable interrupts in the Processor.
*/
Xil_ExceptionEnable();

/* Set priority and trigger type */
XScuGic_SetPriorityTriggerType(IntcInstancePtr, SPI_INTR_ID, SGI0_INTR_PRI, SGI0_INTR_TRIG); // ?

XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,
(XSpiPs_StatusHandler) SpiHandler);

xil_printf("GIC config finish\r\n");

return XST_SUCCESS;
}

void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
{
xil_printf("interrupt \r\n");

if (StatusEvent != XST_SPI_SLAVE_MODE) {
xil_printf("XST_SPI_SLAVE_MODE \r\n");
}
if (StatusEvent != XST_SPI_RECEIVE_NOT_EMPTY) {
xil_printf("XST_SPI_RECEIVE_NOT_EMPTY \r\n");
}
if (StatusEvent != XST_SPI_TRANSFER_DONE) {
xil_printf("XST_SPI_TRANSFER_DONE \r\n");
}
}

void SpiSlaveRead(int ByteCount)
{
int Count;
u32 StatusReg;

XSpiPs_SetRXWatermark((&Spi), ByteCount);

StatusReg = XSpiPs_ReadReg(Spi.Config.BaseAddress,
XSPIPS_SR_OFFSET);
/*
* Polling the Rx Buffer for Data
*/
do{
StatusReg = XSpiPs_ReadReg(Spi.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(
Spi.Config.BaseAddress);
}

}

 

Tags (2)
0 Kudos
Reply
4 Replies
venui
Moderator
Moderator
216 Views
Registered: ‎04-09-2019

Hi,

Can you please point me where are you monitoring and reporting as interrupt is not processing.

Regards,

Venu

0 Kudos
Reply
drug490
Visitor
Visitor
202 Views
Registered: ‎07-14-2020

I want to just run the callback function(interrupt handler), when receiving the first byte in the FIFO, how do I do this?

callback function:

void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
{
xil_printf("interrupt \r\n");

if (StatusEvent != XST_SPI_SLAVE_MODE) {
xil_printf("XST_SPI_SLAVE_MODE \r\n");
}
if (StatusEvent != XST_SPI_RECEIVE_NOT_EMPTY) {
xil_printf("XST_SPI_RECEIVE_NOT_EMPTY \r\n");
}
if (StatusEvent != XST_SPI_TRANSFER_DONE) {
xil_printf("XST_SPI_TRANSFER_DONE \r\n");
}
}

0 Kudos
Reply
drug490
Visitor
Visitor
163 Views
Registered: ‎07-14-2020

added a line 

Xil_Out32((XPAR_XSPIPS_0_BASEADDR + XSPIPS_IER_OFFSET), 0x10); //irq enable  

rigidly enable interrupts during initialization,  the interrupt worked once, after that, in the callback procedure, it cut off the controller, also had to turn on the controller hard

Xil_Out32((XPAR_XSPIPS_0_BASEADDR + XSPIPS_ER_OFFSET), 0x01);//spi enable

it works, but this is not the way of the samurai, everything should work at the API level of functions

 

 

0 Kudos
Reply
drug490
Visitor
Visitor
125 Views
Registered: ‎07-14-2020

XScuGic_Connect(IntcInstancePtr, SpiIntrId, (Xil_ExceptionHandler)SpiHandler, (void *)SpiInstancePtr);

to

Xil_Out32((XPAR_XSPIPS_0_BASEADDR + XSPIPS_ER_OFFSET), 0x01);//spi enable   

not use

0 Kudos
Reply