UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor abarlev
Visitor
57 Views
Registered: ‎10-01-2019

Unable to read SPI MISO pin using EMIO interface to PMOD

Hello,

I’m currently attempting to communicate with a sensor using SPI on the Zynq UltraScale+ MPSoC ZCU104 Evaluation Kit, and have been unable to read in data from the MISO line (although I can see that the sensor is outputting data).

I used Vivado to assign pins on the PL PMOD 0 header to the SPI interface. On the SDK side, I’m using the XSpiPs driver to facilitate SPI communication. The communication command I’m using is XSpiPs_PolledTransfer. Using a logic analyzer, I can see that the communication works properly. The chip select, clock, and MOSI pins are activated on the Xilinx side, and the sensor responds reliably on the MISO pin. The only problem is that once the sensor responds on MISO, XSpiPs_PolledTransfer fills the readBuffer with the exact bytes that were written out on the writeBuffer, instead of the bytes that were sent on MISO. This behavior is similar to a loopback mode, but I specifically do not activate loopback mode in the XSpiPs_SetOptions call. Below, I’ve attached the code I’m running and also block design/implementation.

Any assistance would be greatly appreciated!

 

 

#include "xparameters.h"
#include "xplatform_info.h"
#include "xspips.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xscugic_hw.h"
#include "xil_printf.h"
#include <stdlib.h>

void delay(int ms) {
    int c = 0, scaler = 10000;
    while (c < scaler*ms) {
    	c++;
    }
}

uint8_t registerRead(XSpiPs* sSPI_Device, uint8_t reg) {
	reg &= ~0x80u;

	u8 writeBuffer[2] = {reg, 0x00};
	u8 readBuffer[2] = {0x00, 0x00};

	xil_printf("Beginning registerRead...\n");
	xil_printf("BEFORE: read buffer contains %d and %d\n", readBuffer[0], readBuffer[1]);
	xil_printf("BEFORE: write buffer contains %d and %d\n", writeBuffer[0], writeBuffer[1]);

	xil_printf("Starting transfer...\n");
	XSpiPs_PolledTransfer(sSPI_Device, writeBuffer, readBuffer, 2);

	delay(50);

	xil_printf("AFTER: read buffer contains %d and %d\n", readBuffer[0], readBuffer[1]);
	xil_printf("AFTER: write buffer contains %d and %d\n\n", writeBuffer[0], writeBuffer[1]);

	return readBuffer[1];
}

void registerWrite(XSpiPs* sSPI_Device, uint8_t reg, uint8_t value) {
	reg |= 0x80u;

	u8 writeBuffer[2] = {reg, value};
	u8 readBuffer[2] = {0x00, 0x00};

	XSpiPs_PolledTransfer(sSPI_Device, writeBuffer, readBuffer, 2);

	delay(5);
}

void readMotionCount(XSpiPs* sSPI_Device, int16_t *deltaX, int16_t *deltaY)
{
  registerRead(sSPI_Device, 0x02);
  *deltaX = ((int16_t)registerRead(sSPI_Device, 0x04) << 8) | registerRead(sSPI_Device, 0x03);
  *deltaY = ((int16_t)registerRead(sSPI_Device, 0x06) << 8) | registerRead(sSPI_Device, 0x05);
}

int main() {

	xil_printf("\nBeginning SPI Interface Test...\n");

	int status;

	XSpiPs_Config *pSPI_config;
	XSpiPs sSPI_Device;

	pSPI_config = XSpiPs_LookupConfig(XPAR_PSU_SPI_0_DEVICE_ID);
	if (pSPI_config == NULL) {
		xil_printf("SPI Interface Test 1 FAILED.\n");
		return XST_FAILURE;
	}


	status = XSpiPs_CfgInitialize(&sSPI_Device, pSPI_config, pSPI_config->BaseAddress);
	if (status != XST_SUCCESS) {
		xil_printf("SPI Interface Test 2 FAILED.\n");
		//return XST_FAILURE;
	}


	status = XSpiPs_SelfTest(&sSPI_Device);
	if (status != XST_SUCCESS) {
		xil_printf("SPI Interface Test 3 FAILED.\n");
	}

	XSpiPs_SetClkPrescaler(&sSPI_Device, XSPIPS_CLK_PRESCALE_64);
	XSpiPs_SetOptions(&sSPI_Device, (XSPIPS_MASTER_OPTION | XSPIPS_CLK_PHASE_1_OPTION | XSPIPS_CLK_ACTIVE_LOW_OPTION));


	XSpiPs_Enable(&sSPI_Device);

	XSpiPs_SetSlaveSelect(&sSPI_Device, 0x00);

	registerWrite(&sSPI_Device, 0x3A, 0x5A);

	uint8_t chipId = registerRead(&sSPI_Device, 0x00);

	delay(10);

	xil_printf("SPI Interface set-up succeeded!\n");
	xil_printf("Chip ID: %u\n", chipId);

	int16_t deltaX, deltaY, count = 0;

	XSpiPs_SetDelays(&sSPI_Device, 2, 2, 2, 2);

	while (count < 20) {
		readMotionCount(&sSPI_Device, &deltaX, &deltaY);
		xil_printf("*** COUNT: %d, X: %d, Y: %d ***\n\n", count+1, deltaX, deltaY);
		count++;
		delay(2000);
	}

	XSpiPs_Disable(&sSPI_Device);


	xil_printf("SPI Interface Test completed.\n");

	return 0;
	
}

 

 

bd.PNGBlock designconfig.PNGPS configurationimp.PNGImplemented design I/O

0 Kudos