Hi,
Board - Custom board based on RT1020
Currently I'm using DMA uart for the communication between two board.
Communication is works fine but i want to set uart receive size is dynamically.
Currently I set like this,
receiveXfer.data = rxBuff;
receiveXfer.dataSize = 10;
but, this receiveXfer.dataSize will have to change dynamically based on request by sender ,but I'm not able to set this size; because sender sometimes sends 32 bytes sometimes 22 bytes .
Suppose if I set receiveXfer.dataSize fixed size to 22 and exchanging of data works fine till 22 bytes receive ,but when sender send size of data different than 22 bytes then communication gets stuck means it will stop the exchanging data.
e.g.
when, this way i want set or other you can suggest.
if(rxBuff[0] == 0x22)
{
//receiveXfer.dataSize size will be 22
}
if(rxBuff[0] == 0x24)
{
//receiveXfer.dataSize size will be 32
}
Is it possible to resolve this issue.
Hi @hanmant
There are serval method to reach it.
1. Use interrupt or callback function to dynamically adjust the receive size:
When the first byte is received, determine the data length through the interrupt or callback function, and then dynamically adjust the size of the receive buffer. Sample code for reference:
void UART_ReceiveCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == UARTx) {
if (rxBuff[0] == 0x22) {
receiveXfer.dataSize = 22;
} else if (rxBuff[0] == 0x24) {
receiveXfer.dataSize = 32;
}
HAL_UART_Receive_DMA(huart, rxBuff + 1, receiveXfer.dataSize - 1);
}
}
// inital callback functions
HAL_UART_RegisterCallback(&huart1, HAL_UART_RX_COMPLETE_CB_ID, UART_ReceiveCallback);
2. Receive one byte first to determine the data length, and then receive the remaining data
uint8_t rxBuff[32]; // assume maxlen is 32 bytes
void start_receive() {
HAL_UART_Receive_DMA(&huart1, rxBuff, 1);
}
void UART_ReceiveCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == UARTx) {
if (rxBuff[0] == 0x22) {
receiveXfer.dataSize = 22;
} else if (rxBuff[0] == 0x24) {
receiveXfer.dataSize = 32;
}
HAL_UART_Receive_DMA(huart, rxBuff + 1, receiveXfer.dataSize - 1);
}
}
// inital callback
HAL_UART_RegisterCallback(&huart1, HAL_UART_RX_COMPLETE_CB_ID, UART_ReceiveCallback);
// receive
start_receive();
3. By using ring buffer to get solve fixed lenght issue.
Here is only sample code, only for reference.
typedef struct
{
uint16_t length;
// others in packet
} packet_header_t;
#define MAX_RX_BUFFER_SIZE 128 // max buff for example
uint8_t rxBuff[MAX_RX_BUFFER_SIZE];
lpuart_transfer_t receiveXfer;
void init_UART_DMA(LPUART_Type *base, lpuart_edma_handle_t *handle)
{
receiveXfer.data = rxBuff;
receiveXfer.dataSize = sizeof(packet_header_t);
LPUART_TransferReceiveEDMA(base, &receiveXfer, handle);
}
/* LPUART user callback */
void LPUART_UserCallback(LPUART_Type *base, lpuart_edma_handle_t *handle, status_t status, void *userData)
{
userData = userData;
if (kStatus_LPUART_TxIdle == status)
{
txBufferFull = false;
txOnGoing = false;
}
if (kStatus_LPUART_RxIdle == status)
{
rxBufferEmpty = false;
rxOnGoing = false;
// Check if the received data contains a complete header
if (receiveXfer.dataSize >= sizeof(packet_header_t))
{
packet_header_t *header = (packet_header_t *)rxBuff;
uint32_t packetLength = header->length; // Get the packet length
// If the current receive buffer size is smaller than the actual packet length, reconfigure the receive buffer
if (receiveXfer.dataSize < packetLength)
{
receiveXfer.dataSize = packetLength;
LPUART_TransferReceiveEDMA(base, &receiveXfer, handle);
}
else
{
// Processing received data
processReceivedData(rxBuff, packetLength);
// Reconfigure the receive buffer to the initial size and prepare to the next data packet
receiveXfer.dataSize = sizeof(packet_header_t);
LPUART_TransferReceiveEDMA(base, &receiveXfer, handle);
}
}
}
}
void processReceivedData(uint8_t *data, uint32_t length)
{
// FYI
for (uint32_t i = 0; i < length; i++)
{
printf("%02X ", data[i]);
}
printf("\n");
}
int main(void)
{
lpuart_edma_handle_t handle;
LPUART_Init(LPUART1, &uartConfig);
LPUART_TransferCreateHandleEDMA(LPUART1, &handle, LPUART_UserCallback, NULL);
EDMA_CreateHandle(&dmaHandle, DMA0, 1);
init_UART_DMA(LPUART1, &handle);
while (1)
{
// FYI.
}
return 0;
}
what is your issues?
Hi @hanmant
I did know the frame size is changeable, so I try to provide some useful methods for reference, such as interrupt , callback function or ring buffer to dynamically adjust the size, I can't support to provide whole dedicated customized applications.
BTW, you can also refer to the example(DMA, ringbuff) 'evkminxrt1024_lpuart_edma_rb_transfer' which used ring buf and updated in its callback functions.
Hi @Sam_Gao
I have received any response.