2020-03-12 03:20 AM
Here's the context:
//In my main.c:
#define BUFFER_SIZE 32
#define __SECTION_RAM_D2 __attribute__((section(".RAM_D2"))) /* AHB SRAM (D2 domain): */
volatile __SECTION_RAM_D2 uint16_t Buffer[BUFFER_SIZE] = {0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF,0xFFFF};
//In my STM32H743xxx.Id, at the end of the file:
/* Definition for DMA area */
.RAM_D2 :
{
KEEP(*(.RAM_D2)) /* ORIGIN = 0x30000000, LENGTH = 288K */
} >RAM_D2
__HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_CC4);
HAL_DMA_Start_IT(htim1.hdma[TIM_DMA_ID_CC4], (uint32_t)Buffer, (uint32_t)DAC3_D0_GPIO_Port->ODR, BUFFER_SIZE);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_4);
I must be missing something evident, but it is the first time I am using an STM32, and a DMA.
Thanks in advance for your help ! :D
2020-03-12 04:08 AM
I could not figure it out with CubeMX/HAL, but it works for me with the register interface as documented in the reference manual.
DMAMUX1_Channel0->CCR = (DMA_REQUEST_TIM1_CH4 << DMAMUX_CxCR_DMAREQ_ID_Pos); // map timer channel event to DMA1 Stream0.
DMA1->LIFCR = DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0; // clear DMA complete flags
DMA1_Stream0->PAR = (uint32_t)&(GPIOx->BSRR); // you can use ODR as well
DMA1_Stream0->M0AR = (uint32_t)bits_out; // address of the buffer
DMA1_Stream0->NDTR = out_n; // bytes to transfer
DMA1_Stream0->CR =
DMA_SxCR_MSIZE_1 | // 10: 32 bit
DMA_SxCR_PSIZE_1 | // 10: 32 bit
DMA_SxCR_MINC | // memory address increment
DMA_SxCR_DIR_0 | // 00: P->M, 01:M->P, 10:M->M
DMA_SxCR_CIRC | // circular mode, comment it out when you don't need continuous transfer
DMA_SxCR_EN; // enable DMA channel
Don't forget to disable caching of the buffer, or flush (clean) the cache before starting DMA.
https://community.st.com/s/question/0D50X0000CEr14wSQB/h745-memory-regions-attributes-cache
2020-03-12 07:08 AM
Thank you for your reply !
I had also tried without CubeMX/HAL, without success.
I tried using your code and adapting it to my needs (and I flushed the cache before starting DMA), but no luck on this, nothing happens on GPIOD.
My guess right now is that my timer doesn't trigger the DMA transfer (or rather the DMA is not configured to be triggered by the right timer event).
Also it (TIM1) is configured as PWM generation, is it a correct way to use it for DMA ? I've seen some code from my company using OC mode rather than PWM but i'm not sure it is fitted for my needs.