Question
What is causing intermittent switching on the SPI lines of my Xilinx SoC?
Background
I am attempting to control a Texas Instruments LMX2572 frequency synthesizer over SPI using the code posted below. The SPI controller runs on a Xilinx Znyq7000 processing system instantiated on an XCu7Z010 SoC which itself exists on a Bajie development board (first listing on this page). When I step through these transfer commands I see logic analyzer activity such as the following two images. SPI Error
These are intermittent issues and successful SPI commands have been transferred previously. What could be causing this issue? It is most peculiar and I do not understand why a seemingly pseudo-successful transfer is taking place.
#include "xparameters.h"
#include "xgpiops.h"
#include "xuartps.h"
#include "sleep.h"
//#include "stdio.h"
#include "uart.h"
#include "sd.h"
#include "xspips.h"
#include "xil_printf.h"
#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
/************************** Variable Definitions ******************************/
XSpiPs Spi; /* The instance of the SPI device */
XSpiPs_Config *SpiConfig;
int main()
{
int Status;
SpiConfig = XSpiPs_LookupConfig(SPI_DEVICE_ID);
if (NULL == SpiConfig) {
return XST_FAILURE;
}
Status = XSpiPs_CfgInitialize(&Spi, SpiConfig, SpiConfig->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
XSpiPs_SetOptions(&Spi,XSPIPS_FORCE_SSELECT_OPTION|XSPIPS_MASTER_OPTION);
XSpiPs_SetClkPrescaler(&Spi, XSPIPS_CLK_PRESCALE_8);
XSpiPs_SetSlaveSelect(&Spi, 0);
// LMX2572 Register Values
u8 R0_buffer[3];
R0_buffer[0] = 0x00; // MSB is 0: Set R/W to 0 (write), [6:0] are register address 00
R0_buffer[1] = 0x22;
R0_buffer[2] = 0x1C;
Status = XSpiPs_Transfer(&Spi, R0_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R71_buffer[3];
R71_buffer[0] = 0x47;
R71_buffer[1] = 0x00;
R71_buffer[2] = 0x81;
Status = XSpiPs_Transfer(&Spi, R71_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R57_buffer[3];
R57_buffer[0] = 0x39;
R57_buffer[1] = 0x00;
R57_buffer[2] = 0x20;
Status = XSpiPs_Transfer(&Spi, R57_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R52_buffer[3];
R52_buffer[0] = 0x34;
R52_buffer[1] = 0x04;
R52_buffer[2] = 0x21;
Status = XSpiPs_Transfer(&Spi, R52_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R44_buffer[3];
R44_buffer[0] = 0x2C;
R44_buffer[1] = 0x18;
R44_buffer[2] = 0x22;
Status = XSpiPs_Transfer(&Spi, R44_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R36_buffer[3]; // Lower 16 bits of N divider
R36_buffer[0] = 0x24;
R36_buffer[1] = 0x00;
R36_buffer[2] = 0xFF; // Divide to the lowest frequency
Status = XSpiPs_Transfer(&Spi, R36_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R34_buffer[3]; // Lower 16 bits of N divider
R34_buffer[0] = 0x22;
R34_buffer[1] = 0x00;
R34_buffer[2] = 0x17; // Divide to the lowest frequency
Status = XSpiPs_Transfer(&Spi, R34_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R30_buffer[3];
R30_buffer[0] = 0x1E;
R30_buffer[1] = 0x0C;
R30_buffer[2] = 0xA6;
Status = XSpiPs_Transfer(&Spi, R30_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R29_buffer[3];
R29_buffer[0] = 0x1D;
R29_buffer[1] = 0x18;
R29_buffer[2] = 0xC6;
Status = XSpiPs_Transfer(&Spi, R29_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R20_buffer[3];
R20_buffer[0] = 0x14;
R20_buffer[1] = 0x40;
R20_buffer[2] = 0x48;
Status = XSpiPs_Transfer(&Spi, R20_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
u8 R5_buffer[3];
R5_buffer[0] = 0x05;
R5_buffer[1] = 0x20;
R5_buffer[2] = 0xC8;
Status = XSpiPs_Transfer(&Spi, R5_buffer, NULL, 3);
if (Status != XST_SUCCESS) {
print("SPI Transfer Failed\r\n");
}
usleep(20000);
XSpiPs_Abort(&Spi);
}
-
2\$\begingroup\$ As a rule of thumb, I always 'scope questionable logic-analyzer signals. Just to make sure it is reporting "real" data. \$\endgroup\$rdtsc– rdtsc2021年05月28日 13:58:48 +00:00Commented May 28, 2021 at 13:58
1 Answer 1
Update
The problem was fixed by changing the clock prescaler to the following
XSpiPs_SetClkPrescaler(&Spi, XSPIPS_CLK_PRESCALE_256);
which means that the issue may have been caused in fact by the logic analyzer not being able to sample the values correctly.
-
1\$\begingroup\$ If it solved your problem, you can mark your own answer as solution. \$\endgroup\$Mitu Raj– Mitu Raj2021年05月28日 13:29:16 +00:00Commented May 28, 2021 at 13:29