3
\$\begingroup\$

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

Second 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);
}
\$\endgroup\$
1
  • 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
    May 28, 2021 at 13:58

1 Answer 1

2
\$\begingroup\$

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.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ If it solved your problem, you can mark your own answer as solution. \$\endgroup\$
    – Mitu Raj
    May 28, 2021 at 13:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.