Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

SPI communication between FPGA(as a slave) and microcontroller(as master)

Status
Not open for further replies.

brahmi15

Newbie level 5
Joined
Oct 15, 2020
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
67
Hello all,

I am using ZC-706 zynq board as slave and atmega128 microcontroller as master.

I want to do spi communication between them. For testing i am just transmitting 1 byte of data which is transmitting successfully from the master side.

For FPGA slave i am using AXI quad spi IP core which is configured in slave mode. Please find the below block diagram design for same.

image.thumb.png.a27a04e504ac86f23ba1bef9b60bd1f7.png

From the PS side i am using the below SPI driver example which is mentioned below.

Code:
/***************************** Include Files *********************************/

#include "xparameters.h" /* XPAR parameters */
#include "xspi.h" /* SPI device driver */
#include "stdio.h"
#include "xil_printf.h"

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

/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID

/*
* This is the size of the buffer to be transmitted/received in this example.
*/
#define BUFFER_SIZE 16

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


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


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

static int SpiSlavePolledExample(XSpi *SpiInstancePtr, u16 SpiDeviceId);

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

/*
* The instances to support the device drivers are global such that they are
* initialized to zero each time the program runs. They could be local but
* should at least be static so that they are zeroed.
*/
static XSpi SpiInstance; /* The instance of the SPI device */

/*
* The following variables are used to read from the Spi device, these are
* global to avoid having large buffers on the stack.
*/
u8 ReadBuffer[BUFFER_SIZE];
u8 WriteBuffer[BUFFER_SIZE];

/*
* The following variable allows a test value to be added to the values that
* are sent in reflection to the Master transmission such that unique values can
* be generated to guarantee the transfer from Slave to Master is successful.
*/
int Test;

/*****************************************************************************/
/**
*
* Main function to call the Spi Slave example in polled mode.
*
* [USER=42587]@param[/USER] None
*
* [USER=344527]@Return[/USER] XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* [USER=545121]@note[/USER] None
*
******************************************************************************/
int main(void)
{
int Status;

/*
* Run the Spi Slave polled example.
*/
Status = SpiSlavePolledExample(&SpiInstance, SPI_DEVICE_ID);
if (Status != XST_SUCCESS) {
xil_printf("Spi slave polled Example Failed\r\n");
return XST_FAILURE;
}

xil_printf("Successfully ran Spi slave polled Example\r\n");
return XST_SUCCESS;
}

/*****************************************************************************/
/**
*
* This function does a minimal test on the Spi device and driver as a design
* example. The purpose of this function is to illustrate the device slave
* functionality in polled mode. This function receives data from a master and
* prints the received data.
*
* [USER=42587]@param[/USER] SpiInstancePtr is a pointer to the instance of Spi component.
*
* [USER=42587]@param[/USER] SpiDeviceId is the Device ID of the Spi Device and is the
* XPAR_<SPI_instance>_DEVICE_ID value from xparameters.h.
*
* [USER=344527]@Return[/USER] XST_SUCCESS if successful, otherwise XST_FAILURE.
*
* [USER=545121]@note[/USER] This function contains an infinite loop such that if the Spi
* device doesn't receive any data, it may never return.
*
******************************************************************************/
int SpiSlavePolledExample(XSpi *SpiInstancePtr, u16 SpiDeviceId)
{
XSpi_Config *ConfigPtr;
int Status;
u32 Count;

xil_printf("\r\nEntering the Spi Slave Polled Example.\r\n");
xil_printf("Waiting for data from SPI master\r\n");

/*
* Initialize the SPI driver so that it's ready to use, specify the
* device ID that is generated in xparameters.h.
*/
ConfigPtr = XSpi_LookupConfig(SpiDeviceId);
if (ConfigPtr == NULL) {
return XST_FAILURE;
}
Status = XSpi_CfgInitialize(SpiInstancePtr, ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

/*
* The SPI device is a slave by default and the clock phase and polarity
* have to be set according to its master. In this example, CPOL is set
* to active low and CPHA is set to 1.
*/
Status = XSpi_SetOptions(SpiInstancePtr,
XSP_CLK_ACTIVE_LOW_OPTION | XSP_CLK_PHASE_1_OPTION);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

/*
* Start the SPI driver so that the device is enabled.
*/
XSpi_Start(SpiInstancePtr);

/*
* Disable Global interrupt to use polled mode operation.
*/
XSpi_IntrGlobalDisable(SpiInstancePtr);


/*
* Initialize the write buffer with pattern to write, initialize the
* read buffer to zero so that it can be verified after the read.
*/
//Test = 0xF0;
//for (Count = 0; Count < BUFFER_SIZE; Count++) {
//WriteBuffer[Count] = (u8)(Count + Test);
//ReadBuffer[Count] = 0;
//}

/*
* Prepare the data buffers for transmission and to send/receive data
* when the SPI device is selected by a master.
*/
XSpi_Transfer(SpiInstancePtr, WriteBuffer, ReadBuffer, BUFFER_SIZE);

/*
* Print all the data received from the master so that it can be
* compared with the data sent by the master.
*/
xil_printf("\r\nReceived data is:\r\n");
for (Count = 0; Count < BUFFER_SIZE; Count++) {
xil_printf("0x%x \r\n", ReadBuffer[Count]);
}

xil_printf("\r\nExiting the Spi Slave Polled Example.\r\n");

return XST_SUCCESS;
}
I am not receiving any data. Please find the below output window picture.

image.png.b5c04c3dd5a9236f355e5810f91e4fd4.png

Kindly guide where I am wrong or I miss something?

Thank you.
 
Last edited by a moderator:

Hi,

I'm not familiar with your hardware...
* you disabled global interrupts. Are you sure nothing (no library function, no periferal....) uses an interrupt?
* you wrote "I'm not receiving any data". Are you sure about this?
What I see: the spi_transfer is coming back. (Thus I assume it received data). But all received data is 0x00.

This may be wrong or not. Nobody knows what data the master sends. Nobody knows whether the wiring is correct.

Klaus
 

Hello @KlausST

Thank you for your reply.
master (microcontroller) which send the 0x55 data continues when chip select is low.
 

How is the SPI interface initialized as slave? No reference to master or slave mode in the code.

Even if it's working is slave, what's the expected operation of XSpi_Transfer() in this case? Is the function blocking?
 

Xilinx provides the SPI driver and there is one slave polled mode example. which is by default working as a slave.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top