I am working on a project with a kl82 frdm board that will use the LPUART API to send "non blocking" data intermittently as well as be able to receive data through interrupt. I am using the LPUART_TransferSendNonBlocking function to send packets of data, but I also want to use the LPUART_IRQHandler whenever a byte is received. It seems that I can use the two separately, but I cannot use them together. I have seen some examples that use the LPUART_TransferReceiveNonBlocking function in order to receive bytes but the packets that are expected to receive are different lengths and I believe the callback function will only trigger once that amount of bytes has been received.
My example provided basically sends 26 bytes using the LPUART_TransferSendNonBlocking function, send one byte in the callback, and repeats every half a second. I want to be able to receive bytes on interrupt though with the LPUART1_IRQHandler function.
If anyone knows why this method doesn't work or knows of a better solution using this API please let me know!
Thanks,
Ronnie
Hi
Have you tried using the ring buffer to receive data?
First create handle using LPUART_TransferCreateHandle
For tx, call LPUART_TransferSendNonBlocking to send fixed length of data
For rx, call LPUART_TransferStartRingBuffer to start ring buffer, the received data will be stored in ring buffer first, then if you want to read data from ring buffer, call LPUART_TransferGetRxRingBufferLength to get currently how many data is avaliable in rb(x bytes), then call LPUART_TransferReceiveNonBlocking to read x bytes out of rb.
Is this solution works?
Have you tried using the ring buffer to receive data?
First create handle using LPUART_TransferCreateHandle
For tx, call LPUART_TransferSendNonBlocking to send fixed length of data
For rx, call LPUART_TransferStartRingBuffer to start ring buffer, the received data will be stored in ring buffer first, then if you want to read data from ring buffer, call LPUART_TransferGetRxRingBufferLength to get currently how many data is avaliable in rb(x bytes), then call LPUART_TransferReceiveNonBlocking to read x bytes out of rb.
Yes I have looked at this example and seen the function with the following parameters as well:
LPUART_TransferReceiveNonBlocking(DEMO_LPUART, &g_lpuartHandle, &receiveXfer, NULL);
The problem I have with using this function is that receiveXfer needs a "dataSize" attached to it to indicate how many bytes are to be received before calling the interrupt. The data packets that I expect to receive in my protocol varies from a single byte up to 256 bytes and any in between. I would ideally want to have the interrupt called for each byte or once the last byte is received- but there is no way of knowing when the last byte will be received.
Hi ronald_j_chasse,
Thanks for your updated information.
If you don't want this type API, and want to receive your own protocol varies from a single bye upto any bytes, I think you can just enable the Receive Interrupt to receive the UART data. Then you can design your own Interrupt ISR, in the UART ISR, you can use the counter to count your received data.
This is a very common customer's usage.
From the UART module side, after you enable the UART to receive an interrupt when one UART data is coming, then it will trigger one UART receive interrupt, in the UART ISR, you just need to check whether the interrupt is caused by the received interrupt, then you can do your own code.
You totally can don't use the LPUART_TransferReceiveNonBlocking API, you can write your own API, just to enable the receive interrupt, then in the ISR do your own code.
Wish it helps you!
If you still have questions about it, please kindly let me know!
Best Regards,
Kerry
-------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------
Thanks for your input! I still have some questions though.
I still want to use the LPUART_TransferSendNonBlocking function from the API. I do not know how to use the receive interrupt or create my own ISR for it. I have used the LPUART1_IRQHandler ISR to handle the received bytes, but it seems like I cannot use it while using the LPUART_TransferSendNonBlocking function. I want to be able to use BOTH the LPUART_TransferSendNonBlocking function AND some kind of interrupt for receiving 1 byte at a time.
Thanks!
Hi ronald_j_chasse,
If you want to enable both the TX and RX interrupt, you just need to enable both LPUARTx_CTRL[TIE] and LPUARTx_CTRL[RIE], more details, please check the CTRL register description in the KL82 reference manual.
So, you can use this API:
LPUART_EnableInterrupts(base, kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable);
About the interrupt, please check :
static void HAL_UartInterruptHandle(uint8_t instance)
{
hal_uart_state_t *uartHandle = s_UartState[instance];
uint32_t status;
if (NULL == uartHandle)
{
return;
}
status = LPUART_GetStatusFlags(s_LpuartAdapterBase[instance]);
/* Receive data register full */
if ((LPUART_STAT_RDRF_MASK & status) &&
(LPUART_GetEnabledInterrupts(s_LpuartAdapterBase[instance]) & kLPUART_RxDataRegFullInterruptEnable))
{
if (uartHandle->rx.buffer)
{
uartHandle->rx.buffer[uartHandle->rx.bufferSofar++] = LPUART_ReadByte(s_LpuartAdapterBase[instance]);
if (uartHandle->rx.bufferSofar >= uartHandle->rx.bufferLength)
{
LPUART_DisableInterrupts(s_LpuartAdapterBase[instance],
kLPUART_RxDataRegFullInterruptEnable | kLPUART_RxOverrunInterruptEnable);
if (uartHandle->callback)
{
uartHandle->rx.buffer = NULL;
uartHandle->callback(uartHandle, kStatus_HAL_UartRxIdle, uartHandle->callbackParam);
}
}
}
}
/* Send data register empty and the interrupt is enabled. */
if ((LPUART_STAT_TDRE_MASK & status) &&
(LPUART_GetEnabledInterrupts(s_LpuartAdapterBase[instance]) & kLPUART_TxDataRegEmptyInterruptEnable))
{
if (uartHandle->tx.buffer)
{
LPUART_WriteByte(s_LpuartAdapterBase[instance], uartHandle->tx.buffer[uartHandle->tx.bufferSofar++]);
if (uartHandle->tx.bufferSofar >= uartHandle->tx.bufferLength)
{
LPUART_DisableInterrupts(s_LpuartAdapterBase[uartHandle->instance],
kLPUART_TxDataRegEmptyInterruptEnable);
if (uartHandle->callback)
{
uartHandle->tx.buffer = NULL;
uartHandle->callback(uartHandle, kStatus_HAL_UartTxIdle, uartHandle->callbackParam);
}
}
}
}
#if 1
LPUART_ClearStatusFlags(s_LpuartAdapterBase[instance], status);
#endif
}
#endif
#endif
You also can do the operation in the callback function.
Wish it helps you!
If you still have questions about it, please kindly let me know!
Best Regards,
Kerry
-------------------------------------------------------------------------------
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.
-----------------------------------------------------------------------------
Hi @snahmad ,
If you have any kinetis issues, please create your own question post, then our kinetis engineer will help you in your own post, thanks.
I don't support the kinetis product now, but my kinetis colleague will help you in your new question post.
Best Regards,
kerry