AnsweredAssumed Answered

i.MX6 ECSPI CS & timing issues

Question asked by Julien Corjon on Aug 22, 2016
Latest reply on Aug 22, 2016 by igorpadykov

Dear All,

 

I'm facing several issues with communication between an i.MX6Q ECSPI2 and an FPGA. Goal is to write 8bits address and read a 32bits value as fast as we can.

 

In my DTS file I set-up ECSPI2 to use SCLK/MISO/MOSI/SS0 and I wrote my own fpga kernel driver (kernel rel_imx_3.14.52_1.1.0_ga is compiled with imx-spi driver). You can find both at the end of this post.

 

First, here is a capture of two SPI transfert in one SPI message :

 

scope_6.png

 

Issue 1 : CS have to stay enabled between 8bits address writing and 32bits value reading.

Even if I set explicitely cs_change to 0 in my kernel driver, CS is disabled between the two bursts. I assume that I have to set SS_CTL to 0 but I have no idea how to do that in my driver

Note : If I change CS from SS0(DISP0_DAT18 - ALT2) to GPIO5_IO12 (DISP0_DAT18 - ALT5) this CS issue disappear - see oscilloscope print bellow - but I'd prefer to use native ECSPI CS.

scope_7.png

 

Issue 2 : Why Is there a CLK tick between the two SPI message?

This issue is the same than the one describe here : https://community.nxp.com/message/625531#comment-625531 but solution have not been found yet.

 

Issue 3 : Time to take / release SPI communication is huge

As you can notice in the oscilloscope prints the time to take / release the SPI communication is really disappointing. I assume this is because SPI communication is handled by the kernel instead of the ECSPI bloc. Is there any way to change that?

 

Issue 4 : How to handle a 40bits SPI message with BURST ECSPI capability in my FPGA kernel driver?

 

-------------------------------------------------------------

 

=== DTS File ===

&ecspi2 {

  pinctrl-names = "default";

  pinctrl-0 = <&pinctrl_ecspi2>;

  fsl,spi-num-chipselects = <1>;

  cs-gpios = <0>;

  status = "okay";

 

  fpga: fpga {

  compatible = "eca,fpga";

  reg = <0>;

  spi-max-frequency = <20000000>;

  };

};

 

&iomuxc {

  ecspi2 {

  pinctrl_ecspi2: ecspi2grp {

  fsl,pins = <

  MX6QDL_PAD_DISP0_DAT17__ECSPI2_MISO 0x100b1

  MX6QDL_PAD_DISP0_DAT16__ECSPI2_MOSI 0x100b1

  MX6QDL_PAD_DISP0_DAT19__ECSPI2_SCLK 0x100b1

  MX6QDL_PAD_DISP0_DAT18__ECSPI2_SS0  0x100b1

  >;

                };

  };

}

 

 

=== SPI driver ===

static int eca_fpga_reg_read(void *context, unsigned int reg, unsigned int *out)

{

  struct device *dev = context;

  struct spi_transfer t[2];

  struct spi_message m;

  u8 address;

  __le32 val;

  int ret;

 

  mutex_lock(&spi_lock);

 

  address = (reg << 1) | 0x1;

  spi_message_init(&m);

  memset(t, 0, sizeof(t));

  t[0].tx_buf = &address;

  t[0].len = sizeof(address);

  t[0].cs_change = 0;

  t[0].bits_per_word = 8;

  t[1].rx_buf = &val;

  t[1].len = sizeof(val);

  t[1].bits_per_word = 32;

  spi_message_add_tail(&t[0], &m);

  spi_message_add_tail(&t[1], &m);

  ret = spi_sync(to_spi_device(dev), &m);

 

  mutex_unlock(&spi_lock);

 

  if (ret)

  return ret;

 

  *out = cpu_to_le32(val);

  return 0;

}

 

 

Any advice/hint/solution is more than welcome

Outcomes