SPI communication of SPE-FW in r35.3.1 may have two bugs

,

Hi,
@jachen @Trumany @kevinFFF @DaneLLL @WayneWWW
Who can help me answer my questions? Thank you in advance.

I update my AGX Xavier devkit from r32.7.3 to r35.3.1. Then I meet two bugs for SPI communication of SPE-FW in r35.3.1.

Bug 1: The SPI clock frequency cannot be set correctly.

#define SPI_TEST_CLOCK_RATE 12000000 //12MHz

Based on the above setting, the SPI clock frequency should be 12MHz. But I check the SCK line by my scope. I find that the SPI clock frequency is about 1.2MHz. That is to say, the true value is one tenth of the set value. Other settings also follow this pattern , such as 30M—>3M, 5M—> 0.5M.

Bug 2: The SPI DMA mode do not work correctly.
When I test the SPI of SPE-FW with DMA mode, I meet the similar bug which I meet in r32.7.3. It should be mentioned that the PIO mode of SPI works fine in r35.3.1.

My test code in spi_app.c file is

#define SPI_TEST_CONTROLLER	spi_ctlr_spi2
#define SPI_TEST_CLOCK_RATE	12000000 
#define SPI_TEST_DMA_TX_CHANNEL	2
#define SPI_TEST_DMA_RX_CHANNEL	3

#define SPI_TEST_RETRIES	50000000
#define SPI_TEST_DELAY		2000
#define SPI_buffer		512
char data_to_send[SPI_buffer];
char data_to_read[SPI_buffer];

extern int en_spi_flag;

static void spi_test_task(void *pvParameters)
{
	int ret, count;
	(void)pvParameters; /* unused */
	// const uint8_t data_to_send[] = {0xab, 0xcd};
	// uint8_t data_to_read[] = {0x0, 0x0};
	for(int k=0; k < 10; k++)
	{
		data_to_send[k]=k;
	}

	struct spi_client_setting spi_test_device[] = {
		{
			.chip_select = 0,
			.set_rx_tap_delay = false,
			.spi_max_clk_rate = SPI_TEST_CLOCK_RATE,
			.spi_no_dma = false,
		}
	};
	struct spi_master_init master_test_conf[] = {
		{
			.dma_id = &gpcdma_id_aon,
			.dma_chans.tx = SPI_TEST_DMA_TX_CHANNEL,
			.dma_chans.rx = SPI_TEST_DMA_RX_CHANNEL,
			.spi_max_clk_rate = SPI_TEST_CLOCK_RATE,
			.dma_slave_req = GPCDMA_AO_CHANNEL_CH0_CSR_0_REQ_SEL_SPI,
		}
	};

	ret = spi_init(&SPI_TEST_CONTROLLER, master_test_conf);
	if (ret) {
		printf("spi_test: master init failed\r\n");
		return;
	}

	ret = spi_client_setup(&SPI_TEST_CONTROLLER, spi_test_device);
	if (ret) {
		printf("spi_test: couldn't setup SPI device\r\n");
		return;
	}

	struct spi_xfer xfer = {
		.flags = BIT(TEGRA_SPI_XFER_FIRST_MSG) |
			 BIT(TEGRA_SPI_XFER_LAST_MSG),
		.tx_buf = data_to_send,
		.rx_buf = data_to_read,
		.len = ARRAY_SIZE(data_to_read),
		.chip_select = 0,
		.tx_nbits = TEGRA_SPI_NBITS_SINGLE,
		.rx_nbits = TEGRA_SPI_NBITS_SINGLE,
		.bits_per_word = 8,
		.mode = TEGRA_SPI_MODE_0 | TEGRA_SPI_LSBYTE_FIRST,
	};

	while (1)
	{
		if (en_spi_flag == 1)
		{
			for(int k=0; k < 10; k++)
			{
				data_to_send[k]=k;
			}

			for (count = 0; count < SPI_TEST_RETRIES; count++) {
				ret = spi_transfer(&SPI_TEST_CONTROLLER, &xfer);
				if (ret)
					printf("SPI TX/RX failed\r\n");
				else {
					if (!memcmp(data_to_read, data_to_send,
							ARRAY_SIZE(data_to_read)))
						printf("SPI test successful~\r\n");
					else
						printf("Received incorrect data\r\n");
				}
				rtosTaskDelay(SPI_TEST_DELAY);
			}
			break;
		}
	}
	rtosTaskDelete(NULL);
	
}

Where extern int en_spi_flag; is a flag in the IVC task to enable the SPI task after successful the Linux kernel initialization. After the SPI task works, I get the following error from the debug UART:

SPI TX/RX failed

  1. SPI clock issue.
    Can you help to confirm that the SPI clock is correct in 32.7.3 SPE firmware?
    Please help to confirm, and I can do some code review then.

  2. DMA issue.
    So after DMA in SPI is enabled, no crash happens, and just fails? Can you add some debug code at “spe-freertos-bsp/fsp/source/drivers/spi-mst/spi.c” to narrow down the failure? It should be different from previous issue (crash) per my rough review.
    In addition, have you ever checked SPI data (output) pin waveform and confirm there are really traffic in bus?

I will setup local environment to check but it may take time.

br
ChenJian

Thanks for your help.

Yes, the SPI clock is correct in 32.7.3 SPE firmware. I have double-checked confirmed by the scope and logic analyzer.

Yes, no crash happens, just receive SPI TX/RX failed frome the debug UART console.

I will follow your advices to debug this issue.

Hi,
@jachen
Are there any updates about those issues? Do you have preliminary test results? For example, is it confirmed that these two bugs do exist?

Sorry that I still have not got chance to look into it.
More updates once local environment is setup.

thanks for patience.

br
ChenJian

OK, thanks for your help again. I look forward to your feedback.

For clock issue, please double check in your side.
My local test shows 12M clock is correct.

DMA need more time to check.

br
ChenJian

Hi,
In my side, I still have this problem about clock issue.
In r35.3.1, the pinmux of spi2 in tegra19x-mb1-pinmux-p2888-0000-a04-p2822-0000-b01.cfg is:

pinmux.0x0c302048 = 0x00001400; # spi2_sck_pcc0: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302050 = 0x00001450; # spi2_miso_pcc1: spi2, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302028 = 0x00001400; # spi2_mosi_pcc2: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302038 = 0x00001400; # spi2_cs0_pcc3: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

In r32.7.3, the pinmux of spi2 is:

pinmux.0x0c302048 = 0x0000400; # spi2_sck_pcc0: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302050 = 0x0000450; # spi2_miso_pcc1: spi2, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302028 = 0x0000400; # spi2_mosi_pcc2: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

pinmux.0x0c302038 = 0x0000400; # spi2_cs0_pcc3: spi2, tristate-disable, input-disable, io_high_voltage-disable, lpdr-disable

Does this difference have any impact?

no. that bit (bit 12) is E_SCHMT should not have impact to clock.
You can try the original SPI test code.
I’ve check with scope, and the clock withe default code is 12MHz for SPI clock.
Xavier AGX devkit, with 35.3.1 BSP (A5 pin in J28).

br
ChenJian

Thanks a lot.

A5 pin in J28? Dose it mean A5 pin in J6(PCIe x16 connector)?

In my side, If I want to get the 12MHz spi clock frequency from sck line(A5 pin in J6(PCIe x16 connector)), the following setting I have to use with the original SPI test code:

#define SPI_TEST_CLOCK_RATE 120000000 //120MHz

Anyway, there is a solution to the problem about SPI clock frequency. But please test the SPI DMA mode.

Hello,
For clock issue, please double check in your side. You need not update the clock from 12M to 120M. My local test shows correct clock value in scope.
With default settings, 512-byte transfer in 12M mode results in about 341 us.

For SPI DMA mode, please try following patch (debug purpose, and no finalized yet.)
spe-spi-sync-dma-transfer.patch (6.3 KB)

My local test looks good.

br
Chenjian

1 Like

Thanks.
@jachen

How to use this patch file? Can you give me some details?

Hello,
Patch is a standard way to share code changes/updates.
Please find some guides in internet for usage.
For example:
如何使用patch命令打补丁_patch怎么用_琳琳酱的博客-CSDN博客
patch命令用法_reversed (or previously applied) patch detected! a_车子 chezi的博客-CSDN博客

br
Chenjian

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.