iMX6q SPI slave problem

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

iMX6q SPI slave problem

4,315 Views
raymondman
Contributor II

Hi,

I am working on SPI slave mode on iMX6q with the Linux kernel 3.0.35_4.1.0 and have already applied the patch from i.MX6 ESPI slave mode support patch based on rel_imx_3.0.35_4.1.0

The burst length is set to 31.

A single SPI transfer is 2kB of a test pattern from 0x00 to 0xff repeatedly is used to test the SPI transfer.

If SPI clock is 18MHz, iMX6 receives incorrect data starting from 256bytes, or 64x32bits (the fifo size). Starting from 257th bytes, it should repeat 0x00 to 0xff. The received data may be of the following patterns,

256: 14 15 16 17 18 19 1a 1b

256: 0c 0d 0e 0f 10 11 12 13

256: 08 09 0a 0b 0c 0d 0e 0f

If SPI clock is ~1MHz, the error starts at a later position,

776: 00 03 77 2c a1 49 88 92

776: bf 3f c0 40 c1 41 c2 42

1036: c1 41 c2 42 36 60 e0 89

Does It mean that iMX6 is not fast enough to handle the incoming SPI data due to OS latency? Can anyone share experience how fast the SPI clock iMX6q can support? Or Do I need to modify the configuration?

I also refer to the below link to add DMA support

Linux Kernel - [PATCH V1] spi: imx: add dma support for ecspi

Below are debug messages to show the workflow of the DMA.

sdma_control

sdma_config_channel

sdma_disable_channel

sdma_config_ownership

sdma_get_pc

peripheral_type=7

IMX_DMATYPE_CSPI

sdma_set_chan_private_data

sdma_load_context

imx-sdma imx-sdma: load_address = 683

imx-sdma imx-sdma: wml = 0x00000001

imx-sdma imx-sdma: shp_addr = 0x02008000

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000001

imx-sdma imx-sdma: event_mask1 = 0x00000000

sdma_set_context_reg

sdma_run_channel

RX dma config OK

sdma_control

sdma_config_channel

sdma_disable_channel

sdma_config_ownership

sdma_get_pc

peripheral_type=7

IMX_DMATYPE_CSPI

sdma_set_chan_private_data

sdma_load_context

imx-sdma imx-sdma: load_address = 747

imx-sdma imx-sdma: wml = 0x00000020

imx-sdma imx-sdma: shp_addr = 0x02008004

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000001

imx-sdma imx-sdma: event_mask1 = 0x00000000

sdma_set_context_reg

sdma_run_channel

TX dma config OK

spi_imx_transfer

sdma_prep_slave_sg chan_id=1 sg_len=1, dir=2 flags=3

imx-sdma imx-sdma: setting up 1 entries for channel 2.

setting up 1 entries for channel 2.

sdma_load_context

imx-sdma imx-sdma: load_address = 683

imx-sdma imx-sdma: wml = 0x00000001

imx-sdma imx-sdma: shp_addr = 0x02008000

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000001

imx-sdma imx-sdma: event_mask1 = 0x00000000

sdma_set_context_reg

sdma_run_channel

imx-sdma imx-sdma: entry 0: count: 8 dma: 0x00000000  intr

sdma_prep_slave_sg chan_id=0 sg_len=1, dir=1 flags=3

imx-sdma imx-sdma: setting up 1 entries for channel 1.

setting up 1 entries for channel 1.

sdma_load_context

imx-sdma imx-sdma: load_address = 747

imx-sdma imx-sdma: wml = 0x00000020

imx-sdma imx-sdma: shp_addr = 0x02008004

imx-sdma imx-sdma: per_addr = 0x00000000

imx-sdma imx-sdma: event_mask0 = 0x00000001

imx-sdma imx-sdma: event_mask1 = 0x00000000

sdma_set_context_reg

sdma_run_channel

imx-sdma imx-sdma: entry 0: count: 8 dma: 0x00000000  intr

sdma_tx_submit

sdma_assign_cookie

sdma_enable_channel channel=1

sdma_tx_submit

sdma_assign_cookie

sdma_enable_channel channel=2

sdma_issue_pending

sdma_issue_pending

spidev spi0.0: DMA transfer timeout

sdma_control

sdma_disable_channel

sdma_control

sdma_disable_channel

Transfer end

07 65 55 13 50 29 05 c4 spidev_message

It seems DMA cannot receive any interrupt.

I can run mxc_sdma_test from Freescale which does memory-to-memory DMA transfer successfully. During the process, sdma_int_handler() is called.

Can anyone advise what's wrong with the DMA of my case? How can I check if SDMA can support the DMA transfer from/to ECSPI? In imx-sdma.c, I can see the following line to get the firmware name. Where is this firmware stored? I am using Yocto/Dora root filesystem image downloaded from https://boundarydevices.com/yocto-dora-release-mx6/

If the firmware is not correct, where can I download the one supporting ECSPI DMA?

fwname = kasprintf(GFP_KERNEL, "imx/sdma/sdma-%s-to%d.bin",
cpu_name, to_version);

Additional information:

Try 2 sets of configuration

1)

ECSPI1_CONREG= 0x01f000e1

ECSPI1_CONFREG= 0x00000000

ECSPI1_DMAREG= 0x81020020

2)

ECSPI1_CONREG= 0x01F10001

ECSPI1_CONFREG= 0x00000000

ECSPI1_DMAREG= 0x008300A0;

While booting up the system, I can see sdma_int_handler() is called.

sdma_request_channel

sdma_set_channel_priority

sdma_config_ownership

sdma_set_channel_priority

sdma_add_scripts

sdma_get_firmware

sdma_load_script

sdma_run_channel

sdma_int_handler

sdma_add_scripts

imx-sdma imx-sdma: loaded firmware 1.1

imx-sdma imx-sdma: initialized

Thanks a lot!

0 Kudos
4 Replies

1,080 Views
raymondman
Contributor II

Hi,

In this link Linux-Kernel Archive: [PATCH v2 8/8] spi: imx: Add support for SPI Slave mode for imx53 and imx6 chi...

It mentions that

2. Due to Freescale errata ERR003775 "eCSPI: Burst completion by Chip

Select (SS) signal in Slave mode is not functional" burst size must

be set exactly to the size of the transfer. This limit SPI transaction

with maximum 2^12 bits.

Is it true that I can only transfer 512bytes in a single transaction?

Thanks a lot!

0 Kudos

1,080 Views
igorpadykov
NXP Employee
NXP Employee

Hi raymond

this is right:

slave mode with unspecified burst length cannot be supported due to this issue.

The burst length should always be specified with the BURST_LENGTH parameter.

Also it may be useful to look at

Re: imx6 SPI in DMA mode sometime throws "I/O Error in DMA RX"

Best regards

igor

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

Note: If this post answers your question, please click the Correct Answer button. Thank you!

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

0 Kudos

1,080 Views
raymondman
Contributor II

Hi igor,

Thanks for your reply.

That means I may send 16kb or more if imx6 is used as spi master like the author in  the thread. But as slave mode, I can transmit or receive 512kbytes (the maximum burst lenght) in a single transfer, right?

The sdma firmware 1.1 should be working for spi slave mode using DMA, right?

Many thanks!

0 Kudos

1,080 Views
raymondman
Contributor II

Hi igor,

I set the packet size to 256Bytes (the fifo size) and burst_legnth to 7FF. It seems sometimes DMA can work but the received data is not correct. There are still chances that DMA timeout.

If using PIO, the data can be received correctly. Do you have more hints?

Many thanks!

0 Kudos