S32K118 LPUART RX only one byte

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

S32K118 LPUART RX only one byte

201 Views
HiddenSquid
Contributor I

I am trying to configure LPUART on S32K118 MCU.

Sending works fine and I can consistently get TX_EMPTY callback followed by an END_TRANSFER callback.

Now I am also trying to receive an arbitrary amount of bytes with asinc_receive. I tried setting the RX_BUFFER size to 1, writing the byte to a buffer and then calling SetRxBuffer to increase it by one, but I could never receive more than one byte without ending up in the ERROR callback. I figured maybe setting the RX buffer is too slow at updating the buffer and therefore runs into error before next byte is received.

I then tried to use IDLE detection, which once again worked for single bytes reception, but ran into the ERROR callback if more than one byte is sent to it again.

I have incresed the IDLE line detection frame count to MAX, tried aborting and starting the receive at various locations in the code, but still end up in the error callback event.

What could the issue be?

I will provide the appropriate code snippets:

void LPUART1_handler(void){
	Lpuart_Uart_Ip_IrqHandler(UART_INST);
	return;
}

void LPUART_callback(const uint8 HwInstance, const Lpuart_Uart_Ip_EventType Event, const void *UserData){
	(void)HwInstance;
	(void)UserData;
	// Check hardware instance if using 2 UART instances
	switch (Event)
	{
		case LPUART_UART_IP_EVENT_RX_FULL:
			ASMV_KEYWORD("nop");
			// rb_push_byte(&ring_buffer, byte_buffer);
			// Lpuart_Uart_Ip_SetRxBuffer(UART_INST, &byte_buffer, 1U);
			break;
		case LPUART_UART_IP_EVENT_TX_EMPTY:
			ASMV_KEYWORD("nop");
			break;
		case LPUART_UART_IP_EVENT_END_TRANSFER:
			ASMV_KEYWORD("nop");
			//Gpio_Dio_Ip_WritePin(DEBUG_LED_PORT, DEBUG_LED_PIN, LED_ON);
			Lpuart_Uart_Ip_AsyncReceive(UART_INST, rx_buffer, 64U);
			break;
		case LPUART_UART_IP_EVENT_ERROR:
			ASMV_KEYWORD("nop");
			break;
		#if (LPUART_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
		case LPUART_UART_IP_EVENT_IDLE_STATE:
			// ASMV_KEYWORD("nop");
			// TODO: Write contents of rx_buffer to ring buffer
			UART_status = Lpuart_Uart_Ip_GetReceiveStatus(UART_INST, &bytesLeft);

			uint32 received = 64U - bytesLeft;

			if (received > 0)
				rb_write(&ring_buffer, rx_buffer, received);

			// Lpuart_Uart_Ip_AsyncReceive(UART_INST, rx_buffer, 64U);
			break;
		#endif
		default:
			ASMV_KEYWORD("nop");
			break;
	}
}


initialising: 

// Initialising UART with ring buffer
	rb_init(&ring_buffer, ring_data, RING_BUFFER_SIZE);

	Lpuart_Uart_Ip_Init(UART_INST, &Lpuart_Uart_Ip_xHwConfigPB_1 );	//BAUD 115200
	
	// Arming the receive buffer
	#if (LPUART_UART_IP_ENABLE_TIMEOUT_INTERRUPT == STD_ON)
	Lpuart_Uart_Ip_AsyncReceive(UART_INST, rx_buffer, RING_BUFFER_SIZE);
	#else
	Lpuart_Uart_Ip_AsyncReceive(UART_INST, &byte_buffer, 1U);
	#endif

 main loop:

for(;;)
    {
		// DO SMART STUFF
		if (rb_available(&ring_buffer) != 0){
			rb_consume(&ring_buffer, rb_available(&ring_buffer));
			Lpuart_Uart_Ip_AbortReceivingData(UART_INST);
		}
    }

 

0 Kudos
Reply
1 Reply

112 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

receiving byte by byte would work normally, just you need to advance rxbuffer using SetRxBuffer before new byte is received. From your code I see you commented it out, sometimes you call Lpuart_Uart_Ip_AsyncReceive with 1 byte, then with 64. Also you Abort receiving at some place.

Simple example for single-byte mode is given on https://community.nxp.com/t5/S32K-Knowledge-Base/RTD600-IP-S32K312-EVB-Lpuart-interrupt-echo/ta-p/21... so you can refer to it. 
Note RTD does not differentiate between TX and RX end events directly, but you can use user flag as mentioned on https://community.nxp.com/t5/S32K/S32K3-RTD-5-0-0-LPUART-Distinguishing-between-TX-and-RX-when-end/m...

BR, Petr

0 Kudos
Reply