News:

Attention: For security reasons,please choose a user name *different* from your login name.
Also make sure to choose a secure password and change it regularly.

Main Menu

Check SPI communication in Zynqberry

Started by Deepak, April 26, 2021, 12:20:14 PM

Previous topic - Next topic

Deepak

Hello,

I want to communicate from Zynqberry with an external device through SPI. The external device is stacked on top of zynqberry on the GPIO pins. Firstly, in vivado hardware design, I selected Zynq PS and enabled SPI0 and SPI1. Then,  I enabled the SPI Device drivers in petalinux kernel configuration (Cadence SPI controller, Xilinx SPI controller common module, Xilinx Zynq QSPI controller and User mode SPI device driver support are all enabled on the kernel configuration menu).
I added below entry to device tree (system-user.dtsi). The entire contents of system-user.dtsi is as below:

/include/ "system-conf.dtsi"
/ {
};
/* USB PHY */
/{
    usb_phy0: usb_phy@0 {
        compatible = "ulpi-phy";
        #phy-cells = <0>;
        reg = <0xe0002000 0x1000>;
        view-port = <0x0170>;
        drv-vbus;
    };
};

&usb0 {
   dr_mode = "host";
   //dr_mode = "peripheral";
    usb-phy = <&usb_phy0>;
} ;

&spi0{
   #address-cells=<1>;
   #size-cells=<0>;
   status = "okay";
    axispidevice: spidev@0 {
         compatible = "spidev";
          reg = <0>;
           spi-max-frequency = <3125000>;
     };
};

Now there is spi available at /dev/spi1.0 but, when I run my program to communicate with the external device it fails. I want to test the spi communication.
I did a loopback test by connecting the pin 19 and pin 21 (MISO and MOSI pins) and running the program which is available at this website.
https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c
I am receiving only x"00" not the sent data.

root@arm:/home/pi/Dexter# ./spidev_test -D /dev/spidev1.0                                             
spi mode: 0                                                                                           
bits per word: 8                                                                                       
max speed: 500000 Hz (500 KHz)                                                                         
                                                                                                       
00 00 00 00 00 00                                                                                     
00 00 00 00 00 00                                                                                     
00 00 00 00 00 00                                                                                     
00 00 00 00 00 00                                                                                     
00 00 00 00 00 00                                                                                     
00 00 00 00 00 00                                                                                     
00 00       

I believe the MISO and MOSI pins are the same as in raspberrypi. Please correct me if I am wrong and how can I confirm the MISO and MOSI pins in zynqberry ?
Could someone help me if the steps I followed to enable SPI is correct? or how can I check if the spi is enabled correctly or not?

Thanks in advance.

Oleksandr Kiyenko

Hello,
you need to specify SPI pins you want to use in the Zynq SPI configuration and then check schematics when those pins are connected.
Zynq Processing System -> MIO configuration -> SPI0/1
Or you can configure SPI as EMIO and route signals through PL.

Best regards
Oleksandr Kiyenko

Deepak

Thanks Kiyenko for the reply.
I am new to embedded hardware, I am not quite sure how to route the signal. In Zynq Processing system -> MIO Configuration -> I/O Peripherals -> it was EMIO before for both SPI0 and SPI1.
Now I changed SPI0 peripheral to MIO 28..33 and SPI1 to MIO 34..39.
Then I opened RTL Analysis -> Schematics . I do not see any pins named SPI in that schematic diagram.

Could you please help me understand how I should proceed?

Oleksandr Kiyenko

Hello,
you can download the board schematics from https://shop.trenz-electronic.de/Download/?path=Trenz_Electronic/Modules_and_Module_Carriers/special/TE0726/REV03/Documents
so in this schematics, you can see that MIO28..33 and MIO34..39 are already used by the USB interface.
If you want to have an SPI interface on the GPIO pins you need to:
- configure SPI as EMIO
- in block design make these interfaces external
- regenerate HDL wrapper and check it for the names of the signals
- modify constraints to map these signals to GPIO pins

Best regards
Oleksandr Kiyenko

Deepak

Hello Kiyenko,

Thanks for the reply. I tried the steps you mentioned in Vivado.

- First, I opened Zynq7 PS and enabled SPI0 and selected IO as 'EMIO'.

- Expanded SPI_O and many signals are present now (SPI0_SCLK_I, SPI_SCLK_0, SPI0_SCLK_T, ...). I made only the MISO and MOSI signals (SPI0_MOSI_O_0, SPI0_MISO_I_0) as external.

- Run Implementation -> I/O Planning -> I/O Ports -> selected package pin. For SPI0_MOSI_O_0 as R12 and SPI0_MISO_I_0 as P15 as per
https://shop.trenz-electronic.de/trenzdownloads/Trenz_Electronic/Modules_and_Module_Carriers/special/TE0726/REV03/Documents/TRM-TE0726-03.pdf

- The constraints file got automatically updated with the signals which I mapped
set_property PACKAGE_PIN R12 [get_ports SPI0_MOSI_O_0]
set_property PACKAGE_PIN P15 [get_ports SPI0_MISO_I_0]

- In Implementation now I have 'Failed Timing ERROR'.

Did I miss out any step? Should I route all the SPI0 signals as external and map each signal to a port ?

My current task is to get SPI available on the pins 19 (MOSI) and pins 21 (MISO) like in the raspberry pi and run a spi loopback test in linux.

Could you please help me on how I should get this working.

Thanks !

Oleksandr Kiyenko

Hello Deepak,

the sequence looks right.
Can you show these 'Failed Timing ERROR' details?

BR
Oleksandr Kiyenko

Deepak

Hello Kiyenko,
Thanks for the reply.
I have attached screenshot of the Design Timing Summary report.
If I ignore the  'Failed Timing ERROR' message and select 'generate bitstream', it issues 'write_bitstream ERROR'.

I made only MISO and MOSI pins as external. The other pins I dint change. is this correct ? (attached Zynq PS block diagram)

Contents of constraint file:

set_property PACKAGE_PIN R12 [get_ports SPI0_MOSI_O_0]
set_property PACKAGE_PIN P15 [get_ports SPI0_MISO_I_0]
set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MOSI_O_0]
set_property IOSTANDARD LVCMOS33 [get_ports SPI0_MISO_I_0]

Thanks !

Oleksandr Kiyenko

Hello Deepak,
from your screenshots, it's not clear what causes this error. Please find the error description in the "Messages" tab.


BR
Oleksandr Kiyenko

Deepak

#8
Hello Kiyenko,

Thanks for your reply.

I realized the J8 pins 19 and 21 are Zynq pins H14 and J13 respectively. I mentioned it as R12 and P15 before. I am sorry, I dint read the schematics properly.

J8 Pin              Name               Zynq Pin
-------------------------------------------------
19                   GPIO10             H14
21                   GPIO9               J13

After I added SPI0 in Zynq PS and made MISO and MOSI as external. I selected 'Run Implementation'.

After Implementation, I unplaced Zynq Pin H14 and J13 mapped to the GPIO signals (GPIO_1_tri_io[7] and GPIO_1_tri_io[8]) and mapped the MISO and MOSI signals to those Zynq package pins and selected 'Run Implementation'. Vivado assigns the 'package pin' ( M12 and K12 ) automatically to the GPIO pins (GPIO_1_tri_io[7] and GPIO_1_tri_io[8]) which were unplaced by me before. I removed these automatic assignment made and selected 'Generate Bit stream'.

That time it issued an error saying 'GPIO 19 and GPIO 21' pins are not placed and bit stream was not generated.

But, if I leave the automatic assignment of signals (GPIO_1_tri_io[7] and GPIO_1_tri_io[8]) to package pins (M12 and K12) as it is and run 'Generate Bitstream', the bit stream was generated successfully.

I used this bitstream to build petalinux image for the Zynqberry and programmed it with the new BOOT.bin created with the new hardware file (zsys_wrapper.bit) . I looped the GPIO pins 19 and 21 using jumper wire and I ran the spi loopback test C-program and was able to receive the sent data.

Could you please tell me if the process I followed is correct in Vivado ? If we unplace any signal and if Vivado automatically assigns a package pin to it, will it be fine or will it cause any damage to the device ?

But now when I connect Zynqberry to Brickpi3, and run the example sensor program it still issues 'No SPI response ERROR'. Should I make the other SPI signals (clock and chip select) also external ?

Thanks for your time and consideration.

Thanks
Deepak

Oleksandr Kiyenko

Hello Deepak,
your workflow is OK. I prefer to assign pins in xdc file manually, but both ways are good.
Yes, you need to assign SPI CLK and CS pins to make SPI interface works.

BR
Oleksandr Kiyenko

Deepak

Hello Kiyenko,

Thanks for your reply.

I made the SPI clk and SPI chip_select signals also as external pins and routed them to respective GPIO pins.

J8 Pin              Name               Zynq Pin          Signal
-----------------------------------------------------------------------
19                   GPIO10             H14                SPI0_MOSI_O_0
21                   GPIO9               J13                 SPI0_MISO_I_0
23                  GPIO11            J15                 SPI0_SCLK_O_0
24                  GPIO8            L15                 SPI0_SS_O_0

I assigned the signals to the respective GPIO pins based on the Brickpi3 schematics I got from these websites.
https://dlnmh9ip6v2uc.cloudfront.net/datasheets/Dev/RaspberryPi/BrickPi%201.7.3.pdf
https://drive.google.com/drive/folders/1Lc0aOtIx5IfxitarA3TCcvvx8Ebw4c0j

The spi loopback test (https://raw.githubusercontent.com/raspberrypi/linux/rpi-3.10.y/Documentation/spi/spidev_test.c) receives the sent data when I loop the GPIO 19 and 21 pins and run the program.
But still same error when trying to communicate with Brickpi3 "No SPI Response".

Could you please tell me how I can troubleshoot this error further ?

Thanks for your time and consideration.

Best Regards
Deepak

Oleksandr Kiyenko

Hello Deepak,
sorry, but I can't help you to debug your project.
The only thing that I can mention that you need to check SPI settings,
Frequency, CPHA, CPOL should correspond device you trying to communicate.

Best regards
Oleksandr Kiyenko

Deepak

#12
Hello Kiyenko,
Thanks for your reply.

The CPOL and CPHA are mentioned in the python program (0b00; CPOL = 0; CPHA=0). Could you please tell how I can set that in Vivado design, if it is possible?
The spi frequency in the python program i run is set as 500KHz but the minimum SPI clock I can set in Vivado is 111.11 MHz. 

BP_SPI = spidev.SpiDev()
BP_SPI.max_speed_hz = 500000
BP_SPI.mode = 0b00

Thanks for your time and consideration.

Best Regards
Deepak

Oleksandr Kiyenko

Hello Deepack,

you need to set spi-max-frequency parameter in the device tree for the used SPI interface.
https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842255/Linux+SPI+Driver

Best regards
Oleksandr Kiyenko

Deepak

Hello Kiyenko,
Thanks for your reply.
Now I am able to get the sensor readings from the Brickpi3.
I made the GPIO pins and SPI pins as Pull Type 'Pull Down'.

But, there is no lego sensor available at /sys/class/lego-sensor.
I would like to install the lego drivers. Currently, I am referring the below website. But I am not entirely sure of the steps.
It would be helpful if you could share any insights on how to build drivers.

Thanks for your time and consideration.

Best Regards
Deepak