cancel
Showing results for 
Search instead for 
Did you mean: 

USART DMA: registers

michele23
Associate II
Posted on October 13, 2015 at 10:08

Hi,

Im using STM32F071RB.

For SW certification purpose, I need to get rid of libraries and operate at register level.

I modified the init function for USART1 RX in DMA mode:

HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)

{

 static DMA_HandleTypeDef hdma_rx;

RCC->APB2ENR |= (RCC_APB2ENR_USART1EN);

RCC->AHBENR |= (RCC_AHBENR_DMA1EN);

UART_GPIO_Config();

hdma_rx.Instance = DMA1_Channel3;

DMA1_Channel3->CCR    |= 0x000020AF;

huart->hdmarx = &(hdma_rx);

 

hdma_rx.Parent = huart;

HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);   

HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);

USART1->CR1 &=  ~USART_CR1_UE;

USART1->CR1 = 0x0000000C;

USART1->BRR = 0x00000034;

USART1->CR3 = 0x00001000;

USART1->CR1 |=  USART_CR1_UE;

return (UART_CheckIdleState(huart));

}

This code works, but I cannot ''translate'' the bold lines into register level,

because I dont see any effect on DMA1 and USART1 register.

What should I search for?

Thanks,

M.

#dma-usart
4 REPLIES 4
Posted on October 13, 2015 at 13:57

What should I search for?

The code setting up the transfer, and providing the buffer, rather than the code initializing the descriptor for the DMA channel?

Looking at the HAL code, it's hard to see it supporting DMA on more than one USART, perhaps there is other code I'm not seeing.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
michele23
Associate II
Posted on October 13, 2015 at 16:52

I have only 1 usart supported by dma.

This is my rx procedure:

HAL_StatusTypeDef UART_Receive_DMA(UART_HandleTypeDef *huart)

{

 if(huart->State == HAL_UART_STATE_READY)// || (huart->State == HAL_UART_STATE_BUSY_TX))

  {     

  /* Set the UART DMA transfer complete callback */

  huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;    

  DMA1_Channel3->CCR &= ~(DMA_CCR_EN);

  DMA1_Channel3->CNDTR = 0x14;

  DMA1_Channel3->CPAR    = (uint32_t)(&(USART1->RDR));

  DMA1_Channel3->CMAR = (uint32_t)(aRxBuffer_SAFE);

  DMA1_Channel3->CCR = 0x000020AE;

  DMA1_Channel3->CCR |= DMA_CCR_EN;

    

  USART1->CR3 |= USART_CR3_DMAR;

  return HAL_OK;

  }

 else

  {

    return HAL_BUSY;

  }

}

static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  

{

  UART_HandleTypeDef* huart = ( UART_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;

  huart->RxXferCount = 0;

  USART1->CR3 &= ~USART_CR3_DMAR;

  huart->State = HAL_UART_STATE_READY;

}

Posted on October 13, 2015 at 18:09

And you've emboldened the line for some reason? Seems to be casting more than necessary, as it pulls the associated USART descriptor out of the DMA one.

Not sure how transcoding the library gets closer to certifying things, you'll have walked the entire code tree by the time you're done.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 13, 2015 at 18:36

I miss the question in last post too, but allow me some random remarks:

>   DMA1_Channel3->CCR = 0x000020AE;

>   DMA1_Channel3->CCR |= DMA_CCR_EN;

There's no reason to do this write in two steps.

I'd recommend not to use ''magic values'' such as 0x000020AE, but to stick to symbols defined in the stm32fNNNxxx.h header, such as DMA_CCR_EN. I'd also recommend to get rid of the whole HAL stuff altogether and clean it down to standard clean initialization + main_loop + ISR design, no ''descriptors'' and ''handlers'' and callbacks and other unnecessary decoration. A clean design will help you not only to get your certification easier, but also to develop and maintain your application.

JW