SPI slave can only receive the second packet from Nano dev kit SPI master

Thank you so much.

Looking forward your new solution.

This was easier than I thought BUT it may not work for you because it needs GPIO chip selects, not hardware chip selects.

Apply the attached patch. It has all earlier patches as well as a new one to enable nvidia,clk-delay-between-packets.

In your DTS…
Use GPIO chip selects.
Set nvidia,clk-delay-between-packets = < clock_cycles >;
Set nvidia,cs-inactive-cycles = <0>;
0001-spi-tegra114-Various-fixes.patch.txt (3.32 KB)

I have tested with a GPIO chip select(pin12 of J41 on Nano devKit), and it work. But in our in industrial production HW, there is no GPIO pin for spi CS, so we have to set “spi1_cs0_pc3” which is the CS0 for /dev/spidev0.0 as GPIO, then use it as GPIO chip select. For now, we have no real industrial product board to test, so we are not sure if this solution works.

I will try the patch in the Nano devKit.

Thanks

Duplicated…

Hi gtj,

After I rebuilt the kernel with above patch, and add “nvidia,clk-delay-between-packets” to the dts as below, but the running system losted /dev/spidev0.0.

spi@0 {
				compatible = "spidev";
				status = "okay";
				reg = <0x0>;
				spi-max-frequency = <0x1312d00>;
				nvidia,enable-hw-based-cs;
				nvidia,rx-clk-tap-delay = <0x7>;

				controller-data {
						nvidia,cs-inactive-cycles = <0x0>;
						nvidia,cs-hold-clk-count = <0x10>;
						nvidia,cs-setup-clk-count = <0x10>;
						nvidia,clk-delay-between-packets = <0x10>;
						nvidia,enable-hw-based-cs;
				};

while /dev/spidev1.0 is still there.

sercomm:~$ ls /dev/ | grep spi
spidev1.0
sercomm:~$

The of_node is as blow.

ercomm:/sys/devices/7000d400.spi/of_node/spi@0/controller-data$ ls
name  nvidia,clk-delay-between-packets  nvidia,cs-hold-clk-count  nvidia,cs-inactive-cycles  nvidia,cs-setup-clk-count  nvidia,enable-hw-based-cs

I don’t understand how to configure this “GPIO chip selects”.

Thanks

Hi gtj

If there is no better solution for our spi slave requirement. We will have to configure the “spi1_cs0_pc3”(CS0 for /dev/spidev0.0) as GPIO, but we don’t know whether it is necessary to configure the other CS(spi1_cs1_pc4) for /dev/spidev0.0?

And if you have time, please help me change the dts.

Thanks

Hi gtj,

(1) Please help me check whether the new patch at #39 works.

(2) As for our carrier board, we have no pin24 of J41 as devKit, and it shouldn’t have the header-40pin-pinmux node. So the dts you gave out at #33 for setting spi cs as gpio should have a better choice.

header-40pin-pinmux {
    ...
    pin24 {
         nvidia,function = "rsvd1";
         nvidia,pins = "spi1_cs0_pc3";
         nvidia,pull = < 2 >;
         nvidia,tristate = < 0 >;
         nvidia,enable-input = < 0 >;
         };
    ...

I’m not exactly sure what you’re asking but here’s a working setup for the devkit carrier board…

For the pinmux…

pin24 {
     nvidia,function = "spi1";
     nvidia,pins = "spi1_cs0_pc3";
     nvidia,pull = < 2 >;
     nvidia,tristate = < 0 >;
     nvidia,enable-input = < 0 >;
    };

For spi0…

fragment@spi0 {
 target = < &spi0 >;
 __overlay__ {
  status = "okay";
  cs-gpios = <&gpio 19 1>, < 0 >;
  num-cs = < 2 >;
  prod-settings {
   status = "disabled";
   prod {
    prod = <>;
   };
  };
  spi@0 {
   compatible = "spidev";
   status = "okay";
   reg = < 0x0 >;
   spi-max-frequency = < 54000000 >;
   controller-data {
    nvidia,cs-setup-clk-count = < 0x2 >;
    nvidia,cs-hold-clk-count = < 0x2 >;
    nvidia,cs-inactive-cycles = < 0x0 >;
    nvidia,clk-delay-between-packets = < 0x2 >;
   };
  };
 };

Hi gtj,

Sorry for that.

Our final industrial product is based on the production Module, and our carried board has no 40pin like J41, we will never need the header-40pin-pinmux node and its subnodes, right?

For short, could you provide us a dts patch that sets “spi1_cs0_pc3” as gpio while “spi1_cs1_pc4” as the chip select pin for /dev/spidev0.0 for our production module based board?

The “header-40pin-pinmux” is just a name for the collection of the pins that appear on the 40 pin connector. Whether you actually have a 40-pin header is irrelevant.

OK so…

For your production board, what dts are you using as a base?

For spi1_cs0_pc3, you just want that as a standalone GPIO right? Not attached to the spi controller.

For spi1_cs1_pc4, you want THAT as the GPIO based chip select 0 for the spi controller, right?

Hi gtj,

Actually, this is the normal way to realize our requirement compared with setting the CS as GPIO. For the latter, we simulates the GPIO as CS pin, I mean manually pull up and pull down the GPIO in program, so it functions as the CS.

Hi gtj,

Thanks.

“tegra210-p3448-0000-p3449-0000-b00.dtb”, I am not sure. I got it from the log of “sudo BOARDID=3448 FAB=B01 ./flash.sh --no-flash jetson-nano-emmc mmcblk0p1”. Please forgive us we have no module in hand.

Yes. we want set it as a standalone GPIO to pull up/down it manually.So it is a software GPIO chip select.

What is “GPIO based chip select”? I am not sure. We will never use it, just let it as the CS1 for /dev/spidev0.0, if the driver of spi must have a CS, so it must be set as the normal chip select to the spi controller. If the chip select is not a must for the driver or spi controller, then just let it go because in hardware we do not use it.

The difference between hardware chip select and GPIO chip select is that when hardware based, the spi controller itself toggles the CS and you have limited control. When GPIO based, the tegra114 driver toggles the CS and has more control like being able to set “nvidia,clk-delay-between-packets”.

I think I got it now. :)

You don’t care how the driver is configured for CS because you’re not going to use it all. You’re going to toggle spi1_cs0_pc3 yourself.

What confused me was

Now I understand that you really meant spidev0.1 not spidev0.0

Are you using the base dts from 32.3.1 or the older one from 32.2.x? The pinmuxes are a little different so I have to know which one you’re using.

Hi gtj,

We have use a standard GPIO(the gpio79(in sysfs) of devKit) as software CS0, finally it can communicate with our test stm32 MCU.

Thanks, that’s what we intended.

Forgive me for my poor knowledge about linux device and its drvier. We do not need /dev/spidev0.1. So don’t care CS1 any more. Sorry again.

Our code are based on the lastest version R32.3.1.

Thanks.

Last, we are trying our best to get below timing diagram.


And you got my idea at #35.
" OK, you want to keep the spacing between the bytes but you still want CS to stay low. is that right? "

Hi gtj,

The Nvidia have not released the pinumx document for 32.3.1 yet. Do you have the new pinumx document for R32.3.1? We will test our board this Friday, but I am not sure about the DTB based on the Jetson Nano Pinmux 1.01 which is for 32.2.x.

Have a good day.

No. I don’t use the pinmux documents. I look at the original DTS source.

Anyway, try this…

SPI_Custom.dts is the dts file that creates the overlay.
SPI_Custom.dtbo is the overlay created from ^.
tegra210-p3448-0000-p3449-0000-b00-user-custom.dtb is the full custom dtb.

Copy the dtbo and dtb to /boot/ and modify /boot/extlinux/extlinux.conf to point to the new dtb.

The correct gpio pin for control is 19.

I tested these and was able to control spi1_cs0_pc3 using standard gpio functions.
SPI_Custom.zip (44 KB)

Hi gtj,

Thank you.

I will test it about 7 hours latter. Hope it work for me.

Hi gtj,

Please consider making a patch to hardware CS to meet the above timing diagram requirement. Because the GPIO chip select costs a lot time when linux schedules, and seem not stable. The GPIO chip select is just for test whether the hardware work normally or not.

Thank you.

This isn’t going to be easy as I said before and I’m helping you in my spare time. Maybe if you can give me a little more information about where the data you’re transmitting is coming from I could find a solution. Better yet, if you have a small test program I could run that simulates the data source, that’d also help

Is the data fixed size or are you streaming something with an unknown length?
How much data do you need to transmit between CS going low and CS going high again?
How often do you open/close the spidev device? Do you open it permanently or do you open it, transmit some amount of data, then close it again?
How many of those 1x6 packets would you transmit before wanting CS to go high again?
Can you accumulate those 1x6 packets and send them in one batch with CS going low at the start and CS going high at the end of the batch?

Some of those questions are duplicates but it’ll help me understand.

Hi gtj,
Thanks for the question list.

It is fix size on one transfer, always 1*6 bytes.

Just one message with 1x6 bytes. But there must be low spacing(15us more or less) between those bytes.

We do open it then close it after transfer several transfers consist of 1*6 bytes. So there is not much data to be transferred.

Just one. During one 1x6 packets are transmitted, the CS always stay low.

One batch one 1x6 packet.

FYI, 1x6 packet with about 15 us spacing(CS low) between them.

Two 1x6 packet.