stm32stm32cubeidestm32f3

HAL_UARTEx_RxEventCallback() circular DMA: What address is the data?


I'm using the HAL with an STM32F3xx, implementing UART receive with circular DMA. The data should continually be received into the huart->pRxBuffPtr buffer, overwriting old data as new data arrives, and the HAL_UARTEx_RxEventCallback() function gets called regularly to copy out the data before it gets overwritten. The HAL_UARTEx_RxEventCallback() function receives a size parameter and of course a pointer huart, but no direct indication of where in the huart->pRxBuffPtr the freshly arrived data was DMA'd to.

How do I know whereabouts in huart->pRxBuffPtr the freshly arrived data starts?


Solution

  • Thank you to Tom V for the hint. For future generations, here is the solution code - a function which returns true and gets the next available byte, otherwise returns false:

    bool uart_receiveByte(uint8_t *pData) {
      static size_t dmaTail = 0u;
    
      bool isByteReceived = false;
    
      // dmaHead is the next position in the buffer the DMA will write to.
      // dmaTail is the next position in the buffer to be read from.
      const size_t dmaHead = huart->RxXferSize - huart->hdmarx->Instance->CNDTR;
    
      if (dmaTail != dmaHead) {
        isByteReceived = true;
        *pData = pRxDmaBuffer[dmaTail];
        if (++dmaTail >= huart->RxXferSize) {
          dmaTail = 0u;
        }
      }
    
      return isByteReceived;
    }