cancel
Showing results for 
Search instead for 
Did you mean: 

Serial communication limited to 512 bytes

Pincate
Associate III

Hello, I am using a NUCLEO-H7A3ZI-Q to send and receive packets over serial. I have a varying payload size, so I am using: HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx_buffer, 4096); as this searches for an idle at the end of the frame to begin processing this data. 

To process this data and copy it into a look up table (LUT)  capable of being 0-4096 bytes long I have this following script; which comprises two uint8_t into one uint16_t to be represented by a 12-bit DAC, hence the clipping if they exceed 0FFF (4095).

This receives and writes perfectly up to 512 bytes of memory (256 uint16_t within the LUT), however above this all remaining values in the LUT are left unpopulated. 

uint16_t length = 0;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t size){
                if (lut != NULL) {
                    HAL_DAC_Stop_DMA(&hdac1, DAC_CHANNEL_1);
                    free (lut);
                    lut = NULL;
                }
              if(rx_buffer[0] == 0XAA) {
                    length = rx_buffer[2] | (rx_buffer[1] <<8);
                    frame_rate = rx_buffer[3];
                    mode = rx_buffer[4];
                    if (mode >=3){
                    mode = 0;
              }
              uint16_t receive = __HAL_DMA_GET_COUNTER(huart3.hdmarx);
              if (receive >= length + 5) {
                    lut = malloc ((length/2)*sizeof(uint16_t));
                    for (uint16_t k = 0, i = 5; i < length + 5; ++k, i += 2){
                          lut[k] = (rx_buffer[i+1] | rx_buffer[i] << 8);
                          if (lut[k] >= 4095) {
                                lut[k] = 4095;
                          }
                    }
              }
              mode_init = 0;
              HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(&huart3, lut, length);
        }
        HAL_UARTEx_ReceiveToIdle_DMA(&huart3, rx_buffer, 4096);
}

I have tried moving the DMA ram address to 0x3 and the rx_buffer appears to be populating fully, however this is not being transfered to the LUT

.RxDmaSection :
{
KEEP(*(.RxDmaSection))
} > RAM_CD

Edited to apply source code formatting - please see How to insert source code for future reference.

10 REPLIES 10
Pincate
Associate III

This was caused by a hardware limitation on my DMA. I worked around this with a circular buffer copying data to memory as soon as it arrived with half time and full time events with idle events capturing remaining data.

 

This guide covers the basis for the method I used.

 

STM32 UART DMA Receive Example | Normal & Circular Mode