This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI delay after chip select

Hello,

Using the built-in SPI driver on Beaglebone Black, there is 5us gap between when chip select (CS) asserts (goes low) and when SCLK and DIn/DOut start clocking data.  It is all working fine, BUT from what I understand from the Sitara documentation, the delay is unnecessary and it will kill my SPI bandwidth.  And I am unable to set and hold CS low over multi-word transfers, because the target device (a TI ADS7920) uses the falling edge of CS to trigger each transfer.


Any help is greatly appreciated.  Thank you.

Scott

  • Hi,

    What Linux version is this?
  • Hello,

    Here is my version information:

    > cat /etc/os-release
    PRETTY_NAME="Debian GNU/Linux 7 (wheezy)"
    NAME="Debian GNU/Linux"
    VERSION_ID="7"
    VERSION="7 (wheezy)"
    ID=debian
    ANSI_COLOR="1;31"
    HOME_URL="http://www.debian.org/"
    SUPPORT_URL="www.debian.org/.../"
    BUG_REPORT_URL="http://bugs.debian.org/"

    FYI, if a Beaglebone update would help, we are very willing to do the update.

    Scott

  • I'm sorry, this is not a version supported by TI. Can you try with the TI release: www.ti.com/.../PROCESSOR-SDK-AM335X
  • Hello,

    Finally got around working through a version update, but I still see the delay. 

    Scott

  • I have asked the software team to look at this. They will respond here.
  • Hi Scott,

    Let me verify this on my BBB. I'll get back to you with my findings.

    Best Regards,
    Yordan
  • Thank you, Yordan.  FYI in my limited testing, the ChipSelect-to-SCLK delay improves at higher speeds, but never gets better than ~2us.  I also looked at the driver source and nothing jumps out at me as the cause of the delay.

  • Hi Scott,

    I've played with the SPI on my BBB (running kernel 4.4.12) and I can confirm your finding, that there is always a some delay between the assertion of CS & the first spi clock. I've also noted that this delay is lowered when spi clock is used. Bellow picture is when using 5MHz spi clk (the delay is about 12.4 us):

     

    However, I think this is explained in AM335x TRM, Section 24.3.2.8 Chip-Select Timing Control:

    So you may need to re-configure your CHx_CONF register appropriately, in order to minimize this delay. 

    Hope this helps. 

    Best Regards, 
    Yordan

  • First, thank you for your help.

    Second, I have already tried to read the MODULCTRL and CHx_CONF registers <via /dev/mem and mmap() > to see the values for INITDLY and TCS respectively, but get SIGBUS errors. There is already a SIGBUS issue for SPI-registers logged, but the prescribed remedy fails too. So, I am still looking for help, short of editing the SPI driver and building a kernel from source.

    Any help is greatly appreciated.
  • Hi Scott,

    I'm working on your case, but unfortunately still not able to find a solution with the delay between CS & clock. I've asked the SoC designers for some pointers and I am awaiting their replies.

    However, there might be a workaround for your problem:
    And I am unable to set and hold CS low over multi-word transfers, because the target device (a TI ADS7920) uses the falling edge of CS to trigger each transfer

    There is another possibility. Instead of driving the CS for each word, you can disable it and use the spi in 3-pin mode. And on the device ball that is SPIx_CS you can pinmux a GPIO and toggle it whenever you transfer a word through the spi and your external device can syncronize on the gpio signal (which would act as a CS).

    Best Regards,
    Yordan
  • Hi,

    I have another suggestion, which I think will work for you.

    In am335x-boneblack.dts, I added the following node: 
      

    spi1_pins: spi1_pins {
       pinctrl-single,pins = <
           0x19C (PIN_INPUT_PULLUP | MUX_MODE3) /*MCASP0_AHCLKR -> spi1_CS0*/
           0x194 (PIN_INPUT_PULLUP | MUX_MODE3) /*MCASP0_FSX -> spi1_D0*/
           0x198 (PIN_INPUT | MUX_MODE3) /*MCASP0_AXR0 -> spi1_D1*/
           0x190 (PIN_INPUT_PULLUP | MUX_MODE3) /*MCASP0_ACLKX -> spi1_SCLK*/
       >;
    };

    &spi1 {
       #address-cells = <1>;
       #size-cells = <0>;
       status = "okay";
       pinctrl-names = "default";
       pinctrl-0 = <&spi1_pins>;
       spidev@0 {
             #address-cells = <1>;
             #size-cells = <0>;
             spi-max-frequency = <5000000>;
             reg = <0>;
             compatible = "rohm,dh2228fv";
        };
    };

    Then in spi-omap2-mcspi.c I added the following settings: 
        

    static void omap2_mcspi_set_master_mode(struct spi_master *master)
    {
          struct omap2_mcspi *mcspi = spi_master_get_devdata(master);
          struct omap2_mcspi_regs *ctx = &mcspi->ctx;
          u32 l;

    /*
    * Setup when switching from (reset default) slave mode
    * to single-channel master mode
    */
        l = mcspi_read_reg(master, OMAP2_MCSPI_MODULCTRL);
        l &= ~(OMAP2_MCSPI_MODULCTRL_STEST | OMAP2_MCSPI_MODULCTRL_MS);
        l |= OMAP2_MCSPI_MODULCTRL_SINGLE;
    +  l &= (0 << 4);
    +  l &= (0 << 5);
    +  l &= (0 << 6);
        mcspi_write_reg(master, OMAP2_MCSPI_MODULCTRL, l);

        ctx->modulctrl = l;
    }

    The above lines: 
     l &= (0 << 4);
     l &= (0 << 5);
     l &= (0 << 6);

    Set MCSPI_MODULCTRL[6:4]INITDLY = 0x0 => 0h = No delay for first SPI transfer 

    As a result, upon executing: 
      root@am335x-evm:~# echo BABACECA > /dev/spidev1.0 

    I got the following result: 
      

    A you can see the CS asserts almost at the same time as SPI_CLK (there are only 120ns delay, which may be lowered if you increase the SPI_CLK frequency). 

    Best Regards, 
    Yordan

  • Hi Yordan,

    I am not ignoring you, and I definitely appreciate your help.  Your last posting looks very promising.  I am in the processing of building the kernel, after which I will make the change you suggest, and let you know how it goes.

    Thanks again,
    Scott

  • Hi Yordan,

    I have a question relating to the suggested additions to am335x-boneblack.dts: 

    --I understand the spi1 pin assignments, but the &spi1 { } subsection is different from most other spi1 examples.  That is, is the "compatible = "rohm,dh2228fv" line instead of the usual "compatible="spidev" critical to fixing the CS delay?  Is any part of the am335x-boneblack.dts particular to my CS_delay issue or are you just configuring the pins?

    Thanks again,
    Scott

  • Hi Scott,

    hat is, is the "compatible = "rohm,dh2228fv" line instead of the usual "compatible="spidev" critical to fixing the CS delay?


    I added the compatible = "rohm,dh2228fv", because in the spidev.c driver (kernel is v4.4.19 from lates SDK03.01) the options for the compatible parameter are:
    #ifdef CONFIG_OF
    static const struct of_device_id spidev_dt_ids[] = {
    { .compatible = "rohm,dh2228fv" },
    { .compatible = "lineartechnology,ltc2488" },
    {},
    };
    This suggest that it is goot to use either "rohm,dh2228fv" or "lineartechnology,ltc2488" in the dts.

    Is any part of the am335x-boneblack.dts particular to my CS_delay issue or are you just configuring the pins?

    No, the dts does NOT deal with the cs_delay. This is just to configure the spi pins, parameters & the spidev entry in /dev/, so I can use the interface in user space.
    FYI, I also added CONFIG_SPI_SPIDEV=y in tisdk_am335x-evm_defconfig to enable the SPIDEV support.

    Best Regards,
    Yordan
  • Hi Yordan,

    Per your coding suggestion above, I zeroed out the INITDLY field of the OMAP2_MCSPI_MODULCTRL register, but in our case, the delay-change did not take effect unless we also cleared the OMAP2_MCSPI_MODULCTRL_SINGLE field.


    Thank you again,

    Scott