LPC4327 SPI DMA Transfer Rx Buffer Right Shift One Bit

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

LPC4327 SPI DMA Transfer Rx Buffer Right Shift One Bit

1,012 Views
sd016808
Contributor II

Dear engineer,

I use the LPC4327 to be the SPI Master and use DMA to transfer DATA.

The oscilloscope shows the correct data return by our Slave as beflow.

Yello: SCLK Purple:MISO Blue:MOSI

10 Mhz:

10 Mhz10 Mhz

21Mhz:

20 Mhz20 Mhz

Both return value for 10 Mhz and 21Mhz is 0x15. But the DMA transfer rx buffer give me 0x0A for 21Mhz clockrate(Right shift 1 bit) and 0x15 for 10 Mhz(correct with oscilloscope).

I have checked the SPI mode for master and slave is same(CPOL0 CPHA0).

The spec shows maximum SPI data bit rate is 25 Mbits/s for LPC4327.

sd016808_0-1688524810741.png

Why do I get a shift value for the high speed clock rate?

Do I need to set something for the high speed clockrate?

Labels (1)
Tags (3)
0 Kudos
Reply
4 Replies

947 Views
Xu_Zhang
NXP Employee
NXP Employee

Hi, d016808

May I ask if you use LPC4327 as SPI DMA Transfer, which communication mode do you choose, SPI or SSP? The SSP controller can operate on a SPI, but for transmit only 51 Mbit/s (master) and 11 Mbit/s (slave).

Xu_Zhang_0-1688612728174.png

BR

Xu Zhang

0 Kudos
Reply

941 Views
sd016808
Contributor II

Hi,

I choose the SSP1 controller, and LPC4327 as master mode. I think set the SPI clockrate 21 Mhz has met the spec.

I show the open and read function as below:

 

 

int _open(uint32_t clk_rate, uint32_t addr)
{
	_dma_tx_ch_num = dma_register_channel(_dma_tx_completed_isr);
	_dma_rx_ch_num = dma_register_channel(_dma_rx_completed_isr);

	Board_SSP_Init(LPC_SSP1);
	Chip_SSP_Init(LPC_SSP1);
	Chip_SSP_SetFormat(LPC_SSP1, SSP_BITS_8, SSP_FRAMEFORMAT_SPI, SSP_CLOCK_CPHA0_CPOL0);
	Chip_SSP_SetMaster(LPC_SSP1, 1);
	Chip_SSP_SetBitRate(LPC_SSP1, clk_rate);
	Chip_SSP_Enable(LPC_SSP1);

	_cs_enable(false);

	printf("SPI master is open.\n");
	return 0;
}
int _read(uint8_t addr, void* data, size_t size)
{
	uint8_t buf[0x80];
	int cnt;

	if (size == 0)
		return 0;

	if (IS_BIT_CLR(LPC_SSP1->CR1, SSP_CR1_SSP_EN)) {
		printf("[SPI:%s] The device is not open.\n", __func__);
		return -1;
	}
	if (addr + size > sizeof(buf)) {
		printf("[SPI:%s] Too large data size: %u\n", __func__, size);
		return -1;
	}

	/* Fill the address to the buffer. */
	for (cnt = 0; cnt < size; cnt++)
		buf[cnt] = addr + cnt;

	/* Prepare DMA transfers. */
	DMA_TransferDescriptor_t dma_tx_desc;
	DMA_TransferDescriptor_t dma_tx_desc_dummy;
	if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_tx_desc,
				(uint32_t)buf, GPDMA_CONN_SSP1_Tx, size,
				GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, &dma_tx_desc_dummy)) {
		printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
		return -1;
	}
	if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_tx_desc_dummy,
				(uint32_t)buf, GPDMA_CONN_SSP1_Tx, 1,
				GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA, NULL)) {
		printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
		return -1;
	}

	DMA_TransferDescriptor_t dma_rx_desc_dummy;
	DMA_TransferDescriptor_t dma_rx_desc;
	if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_rx_desc_dummy,
				GPDMA_CONN_SSP1_Rx, (uint32_t)buf, 1,
				GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, &dma_rx_desc)) {
		printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
		return -1;
	}
	if (SUCCESS != Chip_GPDMA_PrepareDescriptor(LPC_GPDMA, &dma_rx_desc,
				GPDMA_CONN_SSP1_Rx, (uint32_t)data, size,
				GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA, NULL)) {
		printf("[SPI:%s] Fail to prepare the DMA descriptor.\n", __func__);
		return -1;
	}

	/* Start DMA transfers. */
	_is_dma_tx_completed = false;
	_is_dma_rx_completed = false;
	cnt = -1;

	_cs_enable(true);
	Chip_SSP_DMA_Enable(LPC_SSP1);

	if (SUCCESS != Chip_GPDMA_SGTransfer(LPC_GPDMA, _dma_tx_ch_num,
			(uint32_t)buf, GPDMA_CONN_SSP1_Tx,
			&dma_tx_desc, GPDMA_TRANSFERTYPE_M2P_CONTROLLER_DMA)) {
	printf("[SPI:%s] Fail to start the DMA transfer.\n", __func__);
	goto _disable_ssp_dma;
	}


	if (SUCCESS != Chip_GPDMA_SGTransfer(LPC_GPDMA, _dma_rx_ch_num,
				GPDMA_CONN_SSP1_Rx, (uint32_t)buf,
				&dma_rx_desc_dummy, GPDMA_TRANSFERTYPE_P2M_CONTROLLER_DMA)) {
		printf("[SPI:%s] Fail to start the DMA transfer.\n", __func__);
		goto _disable_ssp_dma;
	}

	/* Wait DMA transfers completed. */
	while (!_is_dma_tx_completed || !_is_dma_rx_completed);
	cnt = size;

_disable_ssp_dma:
	Chip_SSP_DMA_Disable(LPC_SSP1);
	_cs_enable(false);

	return cnt;
}

 

 

 

Actually, I have tried to use polling mode instead of DMA. But the data still shift 1 bit.

0 Kudos
Reply

866 Views
Xu_Zhang
NXP Employee
NXP Employee

May I ask what Slave you use in the data transmission process? Is it also LPC4327? Is it convenient to provide specific 21Mhz problem demo, so that we can better solve the problem for you.

 

Xu Zhang

0 Kudos
Reply

834 Views
sd016808
Contributor II

Hi,

The device is not LPC4327. It is a device that we developed. Is there any possible reason why the oscilloscope shows the correct waveform, but the DMA transfer receives shifted 1 bit data in the same SPI mode?

I have tried connecting the LPC4327 MISO and MOSI pins to assess the situation. When I connect them, I can run at 25.5 MHz with the correct data. However, when I increase the speed further, the data starts to shift to the right. I believe this situation is within the specifications.

I compared the waveforms for the pin-to-pin connection and the pin-to-our-slave connection, and observed a slight delay in the slave output wave. I suspect that this delay may be due to our slave output being too slow for the LPC4327 operating at 21 MHz. What is the minimum required setting time for the LPC4327 at 21 MHz?

 

 

0 Kudos
Reply