SPI latency issue with I.MX6ULL

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SPI latency issue with I.MX6ULL

2,019 Views
roshanmohammed
Contributor I

Hi ,

We are using NXP's I.MX6ULL processor with TCAN4550 for CANFD communication. We are facing an SPI latency issue while transmitting CAN data. CAN data transmission/reception is happening according to SPI interrupt. We have observed that a bunch of data transmitting/receiving in 1 ms then it is inactive for a specific time (We observed 16 ms) then again data transmission/reception will happen for next 1 second. This is continuing. CS line is going low and high continuously multiple times for 1 ms. Then CS will be inactive (High) for next 16 seconds. This is continuing.

Could you recommend the changes needs to do in SPI driver for resolving this latency issue. Is there a SPI driver which supports multi word? 

Regards

Roshan Mohammed PP

0 Kudos
14 Replies

1,762 Views
roshanmohammed
Contributor I

@AldoG 
I had done the changes in device tree as below

interrupt-parent = <&gpio1>;
interrupts = <23 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
iw-tcan-prop;
status = "okay";

I checked only the transmission now. I am transmitting the data with an inter frame delay of 0 milli seconds (No delay between the frames). I observed that the data receiving at the reception end after 1 milli second. ie; The time gap between transmission & reception takes 1 milli second. If possible to reduce that delay to 100 micro seconds, then I cracked this.

What is your suggestions to reduce this time gap between transmission and reception.

0 Kudos

1,987 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

Could you share which kernel version you’re working with?
Also, how are you configuring the SPI in your device tree?

Best regards,
Aldo.

0 Kudos

1,963 Views
roshanmohammed
Contributor I

Hi @AldoG 

Linux kernel is 5.4.70. Below is the SPI configuration in the device tree.
&ecspi1 {
fsl,spi-num-chipselects = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1_1>;
cs-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
status = "okay";

hclk: clock@4 {
compatible = "fixed-clock";
reg = <4>;
#clock-cells = <0>;
clock-frequency = <40000000>;
clock-output-names = "hclk";
};

cclk: clock@5 {
compatible = "fixed-clock";
reg = <5>;
#clock-cells = <0>;
clock-frequency = <40000000>;
clock-output-names = "cclk";
};

tcan4x5x: tcan4x5x@0 {
compatible = "ti,tcan4x5x";
reg = <0>;
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <18000000>;
bosch,mram-cfg = <0x0 3 2 30 10 0 26 12>;
clocks = <&hclk>, <&cclk>;
clock-names = "hclk", "cclk";
interrupt-parent = <&gpio1>;
interrupts = <23 IRQ_TYPE_EDGE_RISING>;
data-ready-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
iw-tcan-prop;
status = "okay";
};
};

pinctrl_ecspi1_1: pinctrl_ecspi1_1 {
fsl,pins = <
MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK 0x10b0
MX6UL_PAD_CSI_DATA05__GPIO4_IO26 0x80000000
MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI 0x10b0
MX6UL_PAD_CSI_DATA07__ECSPI1_MISO 0x10b0
MX6UL_PAD_UART2_CTS_B__GPIO1_IO22 0x80000000
MX6UL_PAD_UART2_RTS_B__GPIO1_IO23 0x80000000
>;
};

0 Kudos

1,952 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

Thank you for sharing,

have you tried any change to driver (spi-imx)?

 

If not, you may try with the following changes explained in this post right here:

https://community.nxp.com/t5/i-MX-Processors/i-MX6-ECSPI-single-burst-transfers/m-p/281395

 

There is even a patch that may be used as reference.

 

Best regards,
Aldo.

0 Kudos

1,881 Views
roshanmohammed
Contributor I

@AldoG This not resolved our issue. Still we are facing the same delay on CANFD transfer.

Please see below.

roshanmohammed_0-1683716713976.png

It will transfer a bunch data at 597 th ms then there is a delay of 42 milli second and then again it will transfer a bunch of data at 640 th ms. This continues. Observed a delay 42 or 43 milli seconds.

Still I am observing the same delay between the transfer of CANFD data.

0 Kudos

1,871 Views
kef2
Senior Contributor IV

Some drivers adjust interrupt level or edge sensitivity, so that is irrelevant. But you still should care to match it. nINT according to datasheet seems being IRQ_TYPE_LEVEL_LOW. You have:

interrupts = <23 IRQ_TYPE_EDGE_RISING>;

Don't know what's this, the same pin as for nINT, then it should be LOW, not HIGH
data-ready-gpios = <&gpio1 23 GPIO_ACTIVE_HIGH>;

This one seems matching RST polarity.
reset-gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;

 

i.MX6ULL SPI is fine with MCP2518FD.

 

0 Kudos

1,804 Views
roshanmohammed
Contributor I

Hi @kef2 
I changed the interrupt to ACTIVE LOW interrupts = <23 IRQ_TYPE_LEVEL_LOW>;

I couldn't find any changes . Still I am observing the same delay between the transfer of CANFD data.

0 Kudos

1,752 Views
kef2
Senior Contributor IV

You wrote previously

  • We observed 16 ms) then again data transmission/reception will happen for next 1 second. This is continuing. CS line is going low and high continuously multiple times for 1 ms. Then CS will be inactive (High) for next 16 seconds.

Furst of all 16ms jitter isn't something unexpected in Linux, no matter how powerful is your CPU. Perhaps Linux RT patch can improve it, but no guaranties for that.

Isn’t it a mistype, 16s inactivity, not 16ms? If indeed seconds, then what is your total CPU usage (number that htop shows).  iMX6ULL, with its tiny L2 cache and high interrupt rate caused by numerous small SPI transfers, in Linux won’t be able to receive all possible CAN traffic. In my MCP2518FD setup, with CAN app it tops at 5.5kmsg/s @ 100% CPU.

  •   Is there a SPI driver which supports multi word? 

What do you mean here? SPI driver already uses SPI FIFO and DMA to send single "multiword/byte" SPI message. Do you mean driver, that would schedule several SPI messages with required CS toggles between adjacent messages, and just single interrupt at the end, when all messages are done? This should be possible with special SDMA scripts, but since no SDMA tools/docs available, only NXP PRO service could help you with this.

0 Kudos

1,011 Views
roshanmohammed
Contributor I

Hi @kef2 

As you said, I am able to achieve 5.5k msgs/s with 1mbps data rate. The message size was 8 bytes.

As per the theoretical calculation, I am expecting ~8.6k msgs/s. Is there any limitation ?

Regards

Roshan Mohammed PP

0 Kudos

968 Views
kef2
Senior Contributor IV

With MCP2518FD LInux driver I'm capable to handle just 3 kmsg/s of CAN on 6ULL. It is just too slow to support full CAN bus at 1Mbps arbitration rate. Try iMX7D, which is capable to receive all MCP2518FD messages with one core almost fully loaded. But the best is to use secondary M4 to handle low level CAN traffic and notify A7 at lower interrupt rate, collecting messages for millisecond or fraction of it and then interrupting Linux at ~10x times lower rate, leaving Cortex-A CPU almost idle.

0 Kudos

613 Views
dahai
Contributor I

Do you have a detailed tutorial on configuring the mcp2518 for the imx6 Ull development board? I really need it. Thank you.

0 Kudos

1,644 Views
roshanmohammed
Contributor I

@AldoG Earlier I mentioned that we are observing a delay of 42/43 ms . We reached in this calculation by checking the CPU terminal timestamp. It was wrong. We have added timestamp reading inside spi driver then we observed that there are no abnormal delay of 42/43 ms. But still we are observing a delay of  ~0.9 ms between each transfer. 

We probed the CS, CLK, MOSI and interrupt pin. On probing we observed that interrupt is happening on every 0.8 ms and the gap between 2 continuous CS low & high is 0.9 ms (Not between single CS low & high, you can see a stream of CS line going low and high then there is a long gap). We are able to receive data in the reception side also on every 0.9 ms. Multiple no of clocks also triggering at the same time. Please see below trace.

roshanmohammed_0-1685010415066.png

Even after triggering multiple clock, CS pin, I was able to receive 1 data at reception side and interrupt is holding high for a long time. Is that expected interrupt holding high for a long duration?

We observed that 4 byte data is transferring while CS going low and high. Is it possible to transfer more than 4 bytes on a single CS going low & high.

One more interesting thing we observed is without transferring any data, We are getting pulses from the probed lines CS, interrupt, clock. Below is the trace for that.

roshanmohammed_1-1685011235252.png

Regards

Roshan Mohammed PP

 

0 Kudos

1,605 Views
kef2
Senior Contributor IV
  • Even after triggering multiple clock, CS pin, I was able to receive 1 data at reception side and interrupt is holding high for a long time. Is that expected interrupt holding high for a long duration?

INT should be asserted until host clears it. According to your waveforms, it takes interrupt latency time (from INT->0 to CS->0) of about <50us and two first SPI transfers. Looks good. What is you real SPI clock and how does it relate to maximum, specified in TCAN4550 datasheet?

  • We observed that 4 byte data is transferring while CS going low and high. Is it possible to transfer more than 4 bytes on a single CS going low & high.

Could you provide more detailed oscillogram confirming your statement? If CS would pulse after every byte instead of single pulse per multibyte message, then I guess your driver wouldn't probe at all and you wouldn't be able to send/receive any CAN messages.

  • One more interesting thing we observed is without transferring any data, We are getting pulses from the probed lines CS, interrupt, clock. Below is the trace for that.

Study your TCAN4550 datasheet and driver code. Isn't TCAN4550 reporting bus off or something? It must be using INT to signal it. 

0 Kudos

1,774 Views
AldoG
NXP TechSupport
NXP TechSupport

Hello,

What about the SPI do you still see the CS go inactive between transfers?
Also, did you make changes to the device tree as well to the driver specified in the community thread I shared previously?

Best regards,
Aldo.

0 Kudos