I’m on an Orin Dev Kit - JP 6.2 and my device-tree and spi-tegra114.c have been updated to work in a single read/write fashion with drivers for the ADI IMU. The modifications to spi-tegra114.c are per the response from SPI bus chip select on Jetpack 6.2 with device-tree - #4 by jays
Running the IMU kernel space driver, I can see that it does work for a specific situation but when there is a need for a burst read - per the IMU datasheet here:
Notice the CS is always asserted between the MOSI (DIN) and then MISO (DOUT) lines respond but the CS must stay asserted during this time.
Looks like the following post has the exact same issue on the CS but didn’t notice that the burst read feature does not work.
You can see the difference between JP 5 and JP6 and clearly the CS deasserting is the problem.
It looks like cs_change doesn’t seem to be properly handled with this driver. There is no work around for this until spi-tegra114.c is asserting the CS line properly. From the oscope this is what it looks like now:
You can see the first 16 clocks, the CS is asserted and then immediately afterwards it is deasserted and then asserted again. That doesn’t match the requirement on the datasheet. Any updates to fix this issue? I know the response have been a fix in the up and coming JP however that’s been a few months.
Yes the CS is the issue even with the application of the patches from prior topics.
The CS assertion must be held during all the SCLKs - regardless if there isn’t a SCLK because the part requires the CS to be asserted during the burst read. The first 16 clocks shown are the MOSI events while the remaining clocks are waiting for MISO to occur. MISO can’t occur because the parts wants CS to be asserted once the MOSI lines are done.
From what I can tell, it looks like the spi-tegra114.c driver doesn’t handle the .cs_change properly since the transaction in the driver has been modified to force cs_change = 0 and we see no difference in the CS waveform.
Even removing nvidia, enable_hw-based-cs in the device tree does nothing to change this around.
Could you try to combine write(MOSI) and read(MISO) to a single spi_message for spi_transfer in your use case?
For example, if you want to write 16 bytes and receive N bytes. Please specify 16+N as total length for your spi transaction. It could help your CS keeps asserted during this spi transaction.
You can see the transfers are all put together into one spi message already and this code hasn’t changed from Jetpack 5 to Jetpack 6. We do know this is working fine also on RPI too so it seems like a problem with how spi-tegra114.c is handling the CS now.
Reading around the port of JP 5 to JP6 spi driver is a massive change. We know it is the spi-tegra114 driver and even the prior links that are out there are partial hacks to address similar SPI handling to JP5. Those changes don’t really fix the CS problem.
The suggestion to send SPI data in only one single spi_transfer - that is done already in the code I pointed out in adis_buffer.c.
I see your point on the two transfers now. That is not possible with the IMU because you must do a TX to set up a burst read (it has to be written to the device) and then the 2nd transfer is really the read response. This portion of the IMU driver hasn’t changed from JP5 to JP6. This seems to be causing the CS to deassert too but again even with the changes per other threads, the CS deasserts while we know in JP5, it doesn’t do that.
it is as if the cs_change is ignored for some reason.
I want to clarify that if I use cs-gpios, I won’t be able to utiliize jetson-io. Next, since the part is connected to another board that attaches to the 40 pin header, the usage from SPI1-CS0 won’t work so thus it looks like I need to change the overlay to setup that specific pin (i.e. GPIO3_PZ.06). Do you have an example of that setup in the overlay then?
It didn’t seem to work per the changes that look like this in the device tree on the orin jetson.
spi@3210000 {
/* force the SPI clock so it can go down to 2 MHz - issue in JP 6 */
assigned-clock-parents = <&bpmp TEGRA234_CLK_CLK_M>;
cs-gpios = <&gpio TEGRA234_MAIN_GPIO(Z, 6) GPIO_ACTIVE_LOW>;
compatible = "nvidia,tegra114-spi";
status = "okay";
spi@0 {
status = "okay";
compatible = "adi,adis16505-2";
adi,burst32-enable;
reg = <0x0>;
spi-cpha;
spi-cpol;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = < TEGRA234_MAIN_GPIO(AC , 6) IRQ_TYPE_EDGE_RISING >;
reset-gpios = <&gpio TEGRA234_MAIN_GPIO(G, 6) GPIO_ACTIVE_LOW >;
controller-data {
//nvidia,enable-hw-based-cs;
cs-gpios;
nvidia,rx-clk-tap-delay = <0x10>;
nvidia,tx-clk-tap-delay = <0x0>;
};
};
};
};
The driver doesn’t see the part per the read on the product id so functionally the spi bus doesn’t seem to be operating right with those specific changes.
Post power cycle, the dmesg is good - no issues doing SPI bus single reads. However the burst read that are needed still has the exact same problem, where a CS must be continuously asserted through the entire transaction.
Could you try about this to port SPI driver from JP5 to JP6?
You can simply overwrite the spi-tegra114.c and check if you can build it successfully.
Current behavior is expected for SPI driver but it seems not meeting for your requirement.
Have you also tried to control CS pin from your application manually?