How do I recieve data on the LPSPI Bus?

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

How do I recieve data on the LPSPI Bus?

Jump to solution
1,648 Views
rtilson
Contributor III

I am trying to receive data on the SPI bus. I have figured out transmit on the bus but I every time I try to read from the RX FIFO all I read back are '0'.

I had initially thought that my IOMUX Pad options were wrong but I am not sure. I am using the mimxrt1062-evk for this work and the LPSPI1 peripheral.

My Initialization Code. In my previous posting I was alerted that I was running the peripheral out of spec and I corrected it. I now run the peripheral off the PLL3 - PFD0 at div 35.

void InitSPI(void)
{

	//Setup the peripheral clock

    CCM->CBCMR &= ~(CCM_CBCMR_LPSPI_CLK_SEL_MASK);
    CCM->CBCMR &=  ~(CCM_CBCMR_LPSPI_PODF_MASK);
    CCM->CBCMR |= CCM_CBCMR_LPSPI_CLK_SEL(0x1) | CCM_CBCMR_LPSPI_PODF(7);// PLL3-PFD0 = 246.857/8 = 30.857MHZ

    CCM->CCGR1 |= CCM_CCGR1_CG0(3); // Enable lpspi1 clock, lpspi_clk_root is based off the ipg_clk
    CCM->CCGR2 |= CCM_CCGR2_CG13(3);
    //Setup the pins - LPSPI1
	IOMUXC->SW_MUX_CTL_PAD[107] = 0x04 | 0x10; // *GPIO_AD_SD_B0_01 - cs - alt4, output, enable Software input
	IOMUXC->SW_MUX_CTL_PAD[108] = 0x04; // *GPIO_AD_SD_B0_02 - mosi - alt4, output
	IOMUXC->SW_MUX_CTL_PAD[109] = 0x04 | 0x10;// *GPIO_AD_SD_B0_03 - miso - alt4, input
	IOMUXC->SW_MUX_CTL_PAD[106] = 0x04;// *GPIO_AD_SD_B0_00 - clk - alt4, output

	IOMUXC->SW_PAD_CTL_PAD[107] = 0xE051; // *GPIO_AD_SD_B0_01 - cs - alt4, output
	IOMUXC->SW_PAD_CTL_PAD[108] = 0xE051; // *GPIO_AD_SD_B0_02 - mosi - alt4, output
	IOMUXC->SW_PAD_CTL_PAD[109] = 0;// *GPIO_AD_SD_B0_03 - miso - alt4, input
	IOMUXC->SW_PAD_CTL_PAD[106] = 0xE051;// *GPIO_AD_SD_B0_00 - clk - alt4, output
	//Setup the memory that will be used for writing data
	//******


	LPSPI1->CFGR0 = 0x0; //Use default configurations here.
	LPSPI1->CFGR1 = LPSPI_CFGR1_PCSCFG(0)  | LPSPI_CFGR1_PCSPOL(0) | LPSPI_CFGR1_MASTER(1) | LPSPI_CFGR1_OUTCFG(0) |
				    LPSPI_CFGR1_NOSTALL(1) | LPSPI_CFGR1_SAMPLE(0);
	LPSPI1->DMR0 = 0; // No data match, default (reset value)
	LPSPI1->DMR0 = 1; // No data match default (reset value)
	//Clock configuration, the reference clock is running at 88MHz per the CCM_CBCMR register settings.
	LPSPI1->CCR = LPSPI_CCR_SCKDIV(0x50) | LPSPI_CCR_SCKPCS(0xFF) | LPSPI_CCR_PCSSCK(0xFF) | LPSPI_CCR_DBT(0x7F) ;
	LPSPI1->FCR = LPSPI_FCR_TXWATER(1) | LPSPI_FCR_RXWATER(0);

	LPSPI1->CR = LPSPI_CR_RTF(1) | LPSPI_CR_RRF(1); //Reset Receive/Transmit FIFO
	LPSPI1->CR = LPSPI_CR_MEN(1) | LPSPI_CR_DBGEN(1);
	LPSPI1->TCR = LSPITCRN;//0x38000008;
	LPSPI1->DER = 0x00; //Disable RX/TX DMA
	LPSPI1->IER = 0x00; //Disable all SPI1 Interrupts


}

I am unsure of the PAD_CTL parameters for this pin. Are they correct for a peripheral controlled pin? Is it necessary to set these parameters if they are controlled by the peripheral?

How do I read back the contents of the RX FIFO? The fsl_lpspi.h is simply calling a function that returns the value of LPSPI1->RDR in while loop for along as the RX FIFO has data in it.

This is my read function:

ReadLCDSPIDATA(0x9, &buffer, 4);

#define cpuB() while(0) { __ISB(); __DSB(); }
void ReadLCDSPIDATA(uint8_t cmd, uint8_t *buffer, uint32_t len)
{
	volatile uint32_t tmp = 0; //LPSPI1->TCR;
	volatile uint32_t i = 0;
	volatile uint32_t readData[64] = {0xB};
	
	for(int i = 0; i < sizeof(readData)/4; i++)
		readData[i] = 0xBBBBBBBB;

	GPIO1->DR_CLEAR = (volatile uint32_t)(1<<16); //assert that this is a command.
	LPSPI1->SR = LPSPISRMSK();

	LPSPI1->TCR = (volatile uint32_t)0x00300007;
	cpuB();
	while((LPSPI1->SR & LPSPI_SR_MBF_MASK) > 0);

	LPSPI1->TDR = cmd;
	while((LPSPI1->SR & LPSPI_SR_TCF_MASK) > 0);

	tmp = LPSPI1->RDR; //burn one off the fifo because its clocked in during the command send
	cpuB();
	LPSPI1->SR = LPSPISRMSK();

	while(i < len)
	{
		LPSPI1->TDR = 0;
		while((LPSPI1->SR & LPSPI_SR_RDF_MASK) > 0);
		readData[i] = LPSPI1->RDR;
		LPSPI1->SR = (1 <<8);
		cpuB();
		i++;
	}

	i=0;

	LPSPI1->TCR = (volatile uint32_t)0x00000007;
	cpuB();

	while(1);
	__asm__("nop");
}

 

I know my SPI device is returning data and the frame is ending:

miso-soup.PNG

 

However, when I break the function I'm using that LPSPI1->FSR[RXCOUNT] is not 0 and there is still data there. What am I missing?

Labels (1)
0 Kudos
1 Solution
1,617 Views
rtilson
Contributor III

I found that the loopback demo was more informative than the spi_interrupt_b2b_master demo. The spi_interrupt_b2b_master demo needed a second board running the slave demo at least that is what was indicated in the text.

I was able to get it to work and successfully read data from the SPI bus. It was not documented that the Daisy chain enable bit had to be set for the LPSPI1 SDI input using GPIO_SD_B0_03. I only found this after running the example, and examining the register values.

View solution in original post

4 Replies
1,642 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
To provide the fastest possible support, I'd highly recommend you refer to the LPSPI demo in the SDK library for MIMXRT1060, and you can download the library via the below link.

https://mcuxpresso.nxp.com/en/welcome
Have a great day,
TIC

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,638 Views
rtilson
Contributor III

I see at least 3 different demos. Which one should I be looking at?

 

I am specifically looking for a means of controlling the peripheral through the cmsis interface. I'm finding that many of these examples, although good, are completely obfuscating how the peripheral is used. The SDK provides a really good interface for every conceivable  situation but is very complex as a result. This makes understanding how this stuff works extremely difficult and time consuming. Unfortunately the Reference Manual is not clear on how to read data from the LPSPI RX FIFO register and I'm seeking to understand how it works so I can use the SPI peripheral.

0 Kudos
1,622 Views
jeremyzhou
NXP Employee
NXP Employee

Hi,
1) Which one should I be looking at?
-- I'd like to suggest to refer to lpspi_interrupt_b2b_master demo.
Hope it helps.
Have a great day,
TIC

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

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos
1,618 Views
rtilson
Contributor III

I found that the loopback demo was more informative than the spi_interrupt_b2b_master demo. The spi_interrupt_b2b_master demo needed a second board running the slave demo at least that is what was indicated in the text.

I was able to get it to work and successfully read data from the SPI bus. It was not documented that the Daisy chain enable bit had to be set for the LPSPI1 SDI input using GPIO_SD_B0_03. I only found this after running the example, and examining the register values.