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 read register to read data coming from SPI slave device on AM335x

Hi,

I have connected a SPI slave on SPI0 of Am335x EVM. 

Slave is in SPI_MODE_1, sends 24-bit per word

For testing the functionality of slave device, I am configuring McSPI within slave device driver hence not using omap mcspi driver (spi0 is disabled in am335x-evm.dts)

This is the register configuration that I am doing in device driver :

void __iomem *spi_addr = ioremap_nocache(0x48030000, 0x400);
void __iomem *clock_addr = ioremap_nocache(0x44e00000, 0x400);

// enable SPI0 module clock
iowrite32(0x2, clock_addr+0x4c);

//SPI SYSCONFIG
//smart idle mode, automatic OCP clock gating
iowrite32(0x11, spi_addr+0x110);

//SPI MODULCTRL
// single channel
iowrite32(0x1, spi_addr+0x128);

//SPI CH0CONF
//PHA = 1, CLKD = 0x4, WL = 0x17, TRM = 1
iowrite32(0x40b91, spi_addr+0x12c);

//SPI CH0CTRL
//channel0 active
iowrite32(0x1, spi_addr+0x134);

Since FIFO is disabled for Rx, when I enable the channel 0, will SPI_RX0 register (offset 0x13c) contain the data received from slave ?

Description of SPI_RX0 register says - "The McSPI channel 0 FIFO receive buffer register (MCSPI_RX0)"

 


Since i am not using FIFO for Rx, will this register still contain the data received from slave ? If no, then which register shall I read.

thanks

  • Hi,

    Moving ahead, I am able to see SPI_CLK getting generated for 24 cycles (my WL is 24) when I want to read.
    I connected logic analyser on SPI0_CLK, SPI0_D0

    Following are operations:
    - enable SPI0_CH0, write to TX0 register.
    - wait for RXS bit to set (Channel 0 receiver register status)
    - once RXS is 1, read RX0 register

    I see all "1" for those 24 clock cycles but RX0 read returns 0x1, 0x2, 0x4, 0x8 ...

    It seems to be 1 but left shift operation whereas data coming D0 is all "1". So I expect "0xffffff" to be read from RX0.

    Is there any other configuration that I am missing.

    Any help is appreciated.

    regards
    Ankur
  • Some more information:

    1) AM335x McSPI is working in Rx only mode as SPI slave device only transmits. Hence, SPI0_SCLK, SPI0_D0 and SPI0_CS are used.

    2) SPI0 CH0 is configured as : MODE_1, 24 bit WL, 3 MHz, Rx on D0, Tx disabled on D0 and D1, Receive only, SPIEN disabled, single channel, FIFO disabled

    3) SPI0_SCLK configured as (OUTPUT_PULLUP | MUX_MODE0), SPI_D0 is in GPIO mode (INPUT_PULLUP  | MUX_MODE7 | ACTIVE_HIGH) as SPI slave pulls SPI_D0 low to indicate data ready

    4) Once falling edge is detected on GPIO, then GPIO is configured in SPIO0_D0 (INPUT_PULLUP | MUX_MODE0) , SPI0_CH0 is Enabled.

    5) Write in SPI0_TX0 and wait for SPI0_CH0STAT_RXS to be set.

    6) Once SPI0_CH0STAT_RXS is set, disable SPI0_CH0 and read SPI0_RX0

    I see 24 clock cycles and data on SPI0_D0 as "0xffffff" on a logic analyzer but SPI0_RX0 read returns 0x1.

    I am stuck on this, looking for some help.

  • To debug, I disabled my module and enabled spi0 in am335x-evm.dts file.

    spi0_pins: pinmux_spi0_pins {
    	pinctrl-single,pins = <
    		0x150 (PIN_OUTPUT_PULLUP | MUX_MODE0)	/* spi0_sclk.gpio0_2 */
    		0x154 (PIN_INPUT_PULLUP | MUX_MODE0)	/* spi0_d0.gpio0_3 */
    	>;
    };
    
    &spi0 {
    	status = "okay";
    	pinctrl-names = "default";
    	pinctrl-0 = <&spi0_pins>;
    
    	spidev0: spi@0{
    		compatible = "linux,spidev";
    		reg = <0>;
    		spi-max-frequency = <375000>;
    		spi-cpha; /* (CPOL=0, CPHA=1) MODE_1 */
    	};
    };

    Input on D0 is always HIGH. I get strange results using spidev_test

    root@am335x-evm:~# ./spidev_test -s 375000 -b 8 -W 1 -H 1 -D /dev/spidev1.0
    spi mode: 1
    bits per word: 8
    max speed: 375000 Hz (375 KHz)
    number of words to be transfered: 1
    --------tx data-----------

    00
    ---------rx data----------

    03
    root@am335x-evm:~# ./spidev_test -s 375000 -b 8 -W 1 -H 1 -D /dev/spidev1.0
    spi mode: 1
    bits per word: 8
    max speed: 375000 Hz (375 KHz)
    number of words to be transfered: 1
    --------tx data-----------

    00
    ---------rx data----------

    0F
    root@am335x-evm:~# ./spidev_test -s 375000 -b 8 -W 1 -H 1 -D /dev/spidev1.0
    spi mode: 1
    bits per word: 8
    max speed: 375000 Hz (375 KHz)
    number of words to be transfered: 1
    --------tx data-----------

    00
    ---------rx data----------

    3F
    root@am335x-evm:~# ./spidev_test -s 375000 -b 8 -W 1 -H 1 -D /dev/spidev1.0
    spi mode: 1
    bits per word: 8
    max speed: 375000 Hz (375 KHz)
    number of words to be transfered: 1
    --------tx data-----------

    00
    ---------rx data----------

    FF
    root@am335x-evm:~#

    I expected 0xFF everytime but it looks like 1 bit shift operation everytime.

    So instead of receiving all 1's, it is receiving only 1 bit every 8 clock cycles.

    Please help me to proceed further.

  • Hi Ankur,

    Please check if the below wiki pages will be in help for your issue:

    processors.wiki.ti.com/.../AM335x_McSPI_Driver%27s_Guide
    processors.wiki.ti.com/.../Linux_Core_SPI_User%27s_Guide

    BR
    Pavel
  • Ankur Tyagi said:
    Since FIFO is disabled for Rx, when I enable the channel 0, will SPI_RX0 register (offset 0x13c) contain the data received from slave ?

    Yes, I think so. See AM335x TRM, figure Transmit/Receive Mode With No FIFO Used (page 4790).


    BR
    Pavel

  • Hi,

    I managed to resolve the issue and the problem was that in order to receive SPI data, SPI CLK pad "should" have "rx_active" enabled.

    So the SPI0_SCLK should be configured as (INPUT | MUX_MODE0) and I was configuring it as (OUTPUT | MUX_MODE0) which is more logical as McSPI being master, should provide clock as OUTPUT.

    regards

    Ankur

  • Ankur,

    spi0_sclk is of type I/O, and when you set RXACTIVE to 1, you are making it I/O. See AM335x TRM, 24.2.3 McSPI Pin List:

    SPIx_SCLK - This output signal is also used as a re-timing input. The associated CONF_<module>_<pin>_RXACTIVE bit for the output clock
    must be set to 1 to enable the clock input back to the module.

    BR
    Pavel
  • Initially I missed that line below the table and ready only the description in table "output when master"

    I would suggest to mention "RXACTIVE bit" in main description table.

    cheers
    Ankur