STM32G431 circular DMA с TIM17 DMAMUX

#timer #stm32 #dma

#таймер #stm32 #dma

Вопрос:

Я уже пару дней пытаюсь создать простую программу DMA для G4. Но без HAL (с использованием libopencm3). Цель состоит в том, чтобы настроить DMA для считывания данных (в циклическом режиме) из буфера и отправки их в TIM17_CCR1.Ранее я заставлял код работать в HAL, но мне не повезло с libopencm3. Мне удалось перенести данные из буфера в OCR в режиме mem2mem (хотя мне нужен mem2perif) просто для того, чтобы попробовать. Но я понятия не имею, как начать с mem2perif. Настройка DMA не имеет большого значения, но я запутался в части DMAMUX.

Вам вообще нужно его настраивать? Как правильно его настроить? Я полностью запутался в документации ST и не могу найти какой-либо существующий код, использующий DMAMUX без HAL. У кого-нибудь из вас есть какие-либо примеры, на которые я мог бы посмотреть? Лучше всего было бы немного голого металла C, чтобы я мог проверить регистры. Что-нибудь, что помогло бы некоторым документам (кроме собственных STS)? Это было бы очень оценено.

Большое спасибо!

Комментарии:

1. using libopencm3 сделайте это на уровне регистра. Не используйте волшебные библиотеки. Бьюсь об заклад, вы будете готовы через 2-3 часа, предполагая, что вы никогда не делали этого раньше.

2. если вам трудно сделать это с помощью библиотеки, которую никто не знает, возможно, начните использовать STM32 HAL и попросите поддержки здесь

3. как я уже сказал, я успешно делал это с помощью HAL раньше, помощь там не нужна 😉

Ответ №1:

У меня это работает даже с библиотекой, просто нужен еще один день тестирования: (

Вот код для всех, кто интересуется:

 gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_FRONT_LED | GPIO_BACK_LED);
gpio_set_output_options(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_FRONT_LED | GPIO_BACK_LED);
gpio_set_af(GPIOB, GPIO_AF10, GPIO_BACK_LED);

//Setup for back led
dma_set_priority(DMA1, DMA_CHANNEL1, DMA_CCR_PL_LOW);
dma_set_memory_size(DMA1, DMA_CHANNEL1, DMA_CCR_MSIZE_8BIT);
dma_set_peripheral_size(DMA1, DMA_CHANNEL1, DMA_CCR_PSIZE_16BIT);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL1);
dma_enable_circular_mode(DMA1, DMA_CHANNEL1);
dma_set_read_from_memory(DMA1, DMA_CHANNEL1);

dmamux_set_dma_channel_request(DMAMUX1, DMA_CHANNEL1, DMAMUX_CxCR_DMAREQ_ID_TIM17_CH1);

dma_set_peripheral_address(DMA1, DMA_CHANNEL1, (uint32_t)amp;TIM17_CCR1);
dma_set_memory_address(DMA1, DMA_CHANNEL1, (uint32_t)amp;ledBackBuffer);
dma_set_number_of_data(DMA1, DMA_CHANNEL1, LED_BACK_BUFFER_SIZE);

timer_enable_preload(TIM17);
timer_update_on_overflow(TIM17);
timer_set_dma_on_update_event(TIM17);
timer_enable_irq(TIM17, TIM_DIER_CC1DE);
timer_generate_event(TIM17, TIM_EGR_CC1G);
timer_set_oc_mode(TIM17, TIM_OC1, TIM_OCM_PWM1);
timer_enable_oc_output(TIM17, TIM_OC1);
timer_enable_break_main_output(TIM17);
timer_set_period(TIM17, 179);

timer_enable_counter(TIM17);
dma_enable_channel(DMA1, DMA_CHANNEL1);
  

ledBackBuffer — это базовый массив uint8_t, заполненный данными для передачи на все светодиоды.