cancel
Showing results for 
Search instead for 
Did you mean: 

How to debug DMA Peripheral to Peripheral Transfer? (Using an STM32 F1)

TLim .2
Associate II

Hello,

I'm trying to understand the peripheral to peripheral transfers. I'm pretty sure my setup is correct but it's not working and I don't think I understand enough to know what to look for to troubleshoot.

For my test I simply have uart1 rx connected to the GPIOB port. I have a script that runs that alternatively sends 0xFF and 0x00 zero bytes and I have an led on pin 6 of GPIOB. So I expect the led to flash. And all this would be independent of the core.

I've previously and successfully ran a memory to peripheral transfer where I sent a message through to the uart1_tx and also turned on the led on GPIOB on pin 6.

I'm running pretty much the same setup only just configured to for peripheral to peripheral transfers and I know I'm using the right DMA channel for uart1 rx as well so I'm not sure what is going on.

Here is my code btw:

  hdma_usart1_rx.Instance = DMA1_Channel5;
  hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  hdma_usart1_rx.Init.MemInc = DMA_MINC_DISABLE;
  hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
  hdma_usart1_rx.Init.Mode = DMA_CIRCULAR; 
  hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
  HAL_DMA_Init(&hdma_usart1_rx);
 
  HAL_DMA_Start(&hdma_usart1_rx, (uint32_t)&huart1.Instance->DR, (uint32_t)&GPIOB->ODR, 1);
  //Enable UART in DMA mode
  huart1.Instance->CR3 |= USART_CR3_DMAR;

Thanks for any input you may have.

6 REPLIES 6

9.2 GPIO registers

The peripheral registers have to be accessed by words (32-bit).

JW

PS. If in doubts, read out and check/observe/post DMA/UART/GPIO registers content. Start with DMA registers, including status registers. Set NDTR to more than 1 to be able to observe.

Ozone
Lead II

That the F1 supports periphery-to-periphery DMA transfers would be new to me.

RM0008 states (section 13.1):

Direct memory access (DMA) is used in order to provide high-speed data transfer between peripherals and memory as well as memory to memory.

PS: I should read the whole FM...

DMA main features

...

�? Memory-to-memory transfer

�? Peripheral-to-memory and memory-to-peripheral, and peripheral-to-peripheral transfers

 

Hi O3,

> That the F1 supports periphery-to-periphery DMA transfers would be new to me.

This all is consequence of entirely inadequate ST documentation. Please see my rant starting there is no such thing as "peripheral to peripheral DMA mode" in https://community.st.com/s/question/0D53W00000QRRPT/how-to-send-data-from-adc-diretly-to-fmac-using-dma-peripheraltoperipheral .

Jan

@Ozone​ 

I was confused by that "updated" RM as well.

And need to agree to your ranting points ...

Ok I get that, but does that not meant that if I pass a byte through it would just send to first eight pin of the port as in, GPIOB pin 0-7? Maybe I'm misunderstanding.

Also if that is the case then I need to find out how to send more than a byte in python but I'll figure that out elsewhere.

And then here are my register contents

For DMA (channel 5 because that's what is connected to uart1 rx):

CCR5 = 0x21

CNDTR5 = 0x1

CPAR5 = 0x40013804

CMAR5 = 0x40010C0C

The peripheral address is right for usart1 and it looks all enabled.

For USART1:

SR = 0xC0

DR = 0x0

BRR = 0x753

CR1 = 0x200C

CR2 = 0x0

CR3 = 0x40

I don't see the data register change here when I run my script.

For GPIOB:

CRL = 0x42484444

CRH = 0x44444444

IDR = 0xFF9B

ODR = 0x10

And of course no change here when I'm running but that's kind of expected since the chain breaks before here.

I'm still playing around and will update further with results.

Thanks for the input, I read stuff like that too and it throws me off. But good to know the right information is always somewhere.