High Speed Uart using LPUART3 on the iMXRT1060-EVK not working

cancel
Showing results for 
Search instead for 
Did you mean: 

High Speed Uart using LPUART3 on the iMXRT1060-EVK not working

168 Views
rtilson
Contributor III

Hello,

I am using the EVK board for the iMXRT1060 and I'm software prototyping a bridge application and I need to simulate line speeds coming into the MCU. I'm using LPUART3 which uses GPIO_AD_B1_07 for RX. I'm trying to push through 4Mbaud but I can get no faster reception than 460.8Kbaud. I am using the serial port of a Raspberry Pi 3b+ as my transmitter to the MCU. I have used both an oscilliscope and a logic analyzer to show that data is being transmitted. I understand the difficulty of getting high speed data over jumper wires, however I'm able to use LPSPI at 8Mhz clock on this same devkit.

My initialization code:

 

void UartBridgeInit(void) //lpuart3
{
	//LPUART3
	uint32_t *lpUart3_PinMUX_TX = (uint32_t*)0x401F8114; //IMXRT1060RM.pdf GPIO_AD_B1_06/
	uint32_t *lpUart3_PinMUX_RX = (uint32_t*)0x401F8118; //IMXRT1060RM.pdf GPIO_AD_B1_07/
	uint32_t *lpUart3_PinCtrl_TX = (uint32_t*)0x401F8404; //IMXRT1060RM.pdf GPIO_AD_B1_06/
	uint32_t *lpUart3_PinCtrl_RX = (uint32_t*)0x401F8308; //IMXRT1060RM.pdf GPIO_AD_B1_07/



	//CCM->CSCDR1 &= ~(CCM_CSCDR1_UART_CLK_PODF_MASK); // check

	CCM->CCGR0 |= CCM_CCGR0_CG6(0x3); //check  enables lpuart3_clk and lpuart3_baudclk
	*lpUart3_PinMUX_TX = 0x2U; //Select Alt2
	*lpUart3_PinMUX_RX = 0x2U; //Select Alt2
//	*lpUart3_PinCtrl_TX = 0x0001_
 	*lpUart3_PinCtrl_RX |= 0x00010000;
	//LPUART3->BAUD = ( LPUART_BAUD_SBR(41) |  LPUART_BAUD_BOTHEDGE(1) | LPUART_BAUD_OSR(15) ); // 114778 baud; baud rate clk/((OSR +1 ) * SBR)
	//LPUART3->BAUD = ( LPUART_BAUD_SBR(6) |  LPUART_BAUD_BOTHEDGE(1) | LPUART_BAUD_OSR(0x1C) ); //460800 Baud....works
	LPUART3->BAUD = ( LPUART_BAUD_SBR(3) |  LPUART_BAUD_BOTHEDGE(1) | LPUART_BAUD_OSR(0x16) ); //1,152,000 Baud....
	//LPUART3->CTRL |= (RX_ENABLE | (1<<21) ); //Enables the Lpuart

	//Enable GPIO Clock

	__NVIC_EnableIRQ(LPUART3_IRQn);
}
__attribute__((aligned(4),section("$SRAM_ITC"))) void LPUART3_IRQHandler(void)
{

	uint8_t retVal = 0;
	volatile uint8_t uData = 0;
	uint8_t rxIdx = 0;
	urtBufferElm *elm = NULL;

	if(((LPUART3->STAT & LPUART_STAT_RDRF_MASK) > 0))
	{
		//Keep adding received data until minimum size is met or until length is met.
		//3rd byte is is the urtnet length byte.
	    rxIdx = urtBufferCtrl.rxurtBufferIdx;
	    elm = &urtBufferCtrl.urtRxData[rxIdx];
		uData =(uint8_t)(LPUART3->DATA & 0xFF);
		__DSB();
		__ISB();

		elm->urtDat[elm->idx] = uData;
		elm->idx++;
	//	__DSB();
	//	__ISB();
		if( (elm->idx) == (elm->urtDat[2]) ) //This seems like an adequate quit condition. 3rd byte will always be a length
		{
			elm->urtLen = elm->urtDat[2];
			urtBufferCtrl.rxNewData++;
			urtBufferCtrl.rxurtBufferIdx= (urtBufferCtrl.rxurtBufferIdx + 1)  & (BUFFELMS-1); //too prevent buffer overruns but will cause buffer corruption if not serviced fast enough
		}
		else if(elm->idx > 254) //safety check to insure we aren't receiving junk
				elm->idx = 0;
	}

	//TODO Rethink this block, I don't like the embedded if statement in the else block. There has to be a better way.
	if((LPUART3->STAT & LPUART_STAT_TC_MASK) && uBridgeDataTxReady()) //If the transmitter is ready, and the tx is ready and there data to transmit
	{
		retVal = uBridgeDataTx();
		if(retVal)
		{
			LPUART3->CTRL &= ~(uint32_t)(TX_INT | TX_ENABLE);
		}
	}
	else
	{
		if( (LPUART3->CTRL & ((uint32_t)(TX_INT | TX_ENABLE))) > 0 ) //need something better than this
			LPUART3->CTRL &= ~(uint32_t)(TX_INT | TX_ENABLE);
	}
	LPUART1->STAT = LPUART_STAT_TC(1);
	__DSB();
	__ISB();
  return;
}

Right now the initialization set for 1.152Mbaud but 4Mbaud is desired. What do I need to do to get these faster speeds? The datasheet specifies that the RX of a pad can be at 25ns, at 4Mbaud the transition is 250ns, so the signal is in spec for the pad. The datasheet however doesn't spec how fast the LPUART peripheral can run at. At the higher speeds, it looks as if the I'm getting 1 or 2 interrupts but I miss the other 6 data bytes (8 bytes total).

I am running the CPU at 600MHz and I have the LPUART3_IRQ located in SRAM_ITC. I don't have caching enabled.

Thanks.

 

0 Kudos
3 Replies

138 Views
rtilson
Contributor III

I was able to squeak out 1.152Mbaud. I suspect that since I'm running this out of QSPI Flash found on the EVK that the time latency for the interrupt to fetch from QSPI decode and execute, I have already missed several bytes. By placing a ramfunc call in the ISR Handler that services the interrupt I was able to increase the baud speed to 1.1Mbaud. Further in that point, I can probably get another speed boost if I relocate all interrupt handling code out of QSPI flash and eliminate the call from the LPUART3 IRQ.

0 Kudos

161 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi,

Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
To assure UART receive the right data when UART works at a high baud rate, I'd like to suggest you use the DMA instead of the interrupt method to receive the data.
Please give it a try.
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

148 Views
rtilson
Contributor III

I tried every standard uart speed from 4MBaud to 460.8Kbaud, before I got something that works. I was able to achieve with a PIC18F high end 8bit MCU a serial speed of 921600baud running at 40MHz (internal OSC) without the aid of DMA on a different project. Am I to understand correctly that the iMXRT1060 running at 600MHz is unable to achieve that speed w/o the need of DMA? Is this understanding correct?

0 Kudos