Hello!
I try to implement an SPI-interface with FreeRtos on a Microblaze system (with Wiznet W6100). The interrupt handler gets triggered only once and then the code stops at “while (Spi_Wiznet_TransferInProgress);”
I have used almost the same code without rtos and it is working. That means the hardware is ok. I have used for the non-FreeRtos application the AXI-SPI with FIFO. For the FreeRtos application i deactivated the FIFO after some tries as I have changed the interrupt-configuration to the port-functions from FreeRtos and activated the XSP_INTR_RX_FULL_MASK - interrupt.
The SPI interface runs with 25 MHz and the Microblaze with 100 MHz.
I post only the (in my opinion) relevant part of my code. If needed, I can upload the whole main.c.
I use the following code for configuration of the SPI-interface:
XSpi_Config *ConfigPtr_Spi_Wiznet;
ConfigPtr_Spi_Wiznet=XSpi_LookupConfig(DeviceID_SPI_Wiznet);
XSpi_CfgInitialize(&Spi_Wiznet, ConfigPtr_Spi_Wiznet, ConfigPtr_Spi_Wiznet->BaseAddress);
// SetupInterruptSystem(); //not used, for FreeRtos I have to use the ported functions
//
// XSpi_SetStatusHandler(&Spi_Wiznet, &Spi_Wiznet, (XSpi_StatusHandler) Spi_Wiznet_Handler); //not used, for FreeRtos I have to use the ported functions
XSpi_SetOptions(&Spi_Wiznet, XSP_MASTER_OPTION );// | XSP_MANUAL_SSELECT_OPTION );
XSpi_SetSlaveSelect(&Spi_Wiznet, cs_wiznet);
XSpi_Start(&Spi_Wiznet);
code for interrupt configuration - at the beginning of a task (not in the while loop)
static void tf_init_wiznet(void* parameters){
const TickType_t x10second = pdMS_TO_TICKS( DELAY_10_SECONDS );
xil_printf( "Enable Interrupts\r\n" );
int xStatus;
xStatus=xPortInstallInterruptHandler(XPAR_CONTROLLER_MICROBLAZE_0_AXI_INTC_WIZNET_AXI_SPI_WIZNET_IP2INTC_IRPT_INTR, (XInterruptHandler) Spi_Wiznet_Handler, &Spi_Wiznet);
vPortEnableInterrupt(XPAR_CONTROLLER_MICROBLAZE_0_AXI_INTC_WIZNET_AXI_SPI_WIZNET_IP2INTC_IRPT_INTR);
XSpi_IntrEnable(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK); //use without FIFO!!
XSpi_IntrGlobalEnable(&Spi_Wiznet);
xil_printf( "Interrupt enabled\r\n" );
xil_printf( "Start Init W6100\r\n" );
functions for SPI transmit/receive
uint8_t my_wizchip_read(void){
uint8_t rx_data[1]={0};
uint8_t tx_data[1]={0xFF};
Spi_Wiznet_TransferInProgress=TRUE;
XSpi_Transfer(&Spi_Wiznet, tx_data, rx_data, 1);
while (Spi_Wiznet_TransferInProgress);
return rx_data[0];
}
void my_wizchip_write(uint8_t wb){
uint8_t rx_data[1]={0};
uint8_t tx_data[1]={wb};
Spi_Wiznet_TransferInProgress=TRUE;
XSpi_Transfer(&Spi_Wiznet, tx_data, rx_data, 1);
while (Spi_Wiznet_TransferInProgress);
return;
}
function for SPI Interrupt handler
void Spi_Wiznet_Handler(void *CallBackRef)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xil_printf( "SPI Int started\r\n" );
portENTER_CRITICAL(); //tried with and without portEnter- and portEXIT_CRITICAL
Spi_Wiznet_TransferInProgress=FALSE;
/* //code that i have used in the non-RTOS application with (void *CallBackRef, u32 StatusEvent, u32 ByteCount)
if (StatusEvent == 0x4) //XST_SPI_TRANSFER_DONE)
Spi_Wiznet_TransferInProgress=FALSE;
else
Spi_Wiznet_ErrorCount++;
*/
XSpi_IntrClear(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK);
XSpi_IntrEnable(&Spi_Wiznet,XSP_INTR_RX_FULL_MASK);
xil_printf( "SPI Int endedr\n");
portEXIT_CRITICAL(); //tried with and without portEnter- and portEXIT_CRITICAL
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
My questions:
Has anybody an idea why my interrupt doesn’t get triggered a second time?
Has anybody a working example with AXI-SPI interrupt and FreeRtos?
I made some tests with GPIO-interrupts…they worked well.
best regards
Dabrzn