stm32 - On STM32F7 DMA triggered by APB1 timers fails -
i have stm32f7 disco board stm32f723iek mcu. trying trigger dma request timer causes dma error, timers apb1 group (tim2 tim7 , others), connected dma1. doing same tim1 , tim8, connected dma2, works fine. error manifests teifx flag being set in appropriate dma lisr or hisr register , dma disabled after first transaction. ndtr register decremented one.
according datasheet, teif error may triggered "bus error". understand e.g. trying access peripheral not accessible dma bus. however, same setup works using dma2 , tim1/tim8, without changing dma address. problem seems related dma request , not data transaction itself. given there lot of timer channels defined dma1, should work.
i have tried vary dma settings made no difference. relevant portion of test program below. full version https://github.com/ak-hard/stm32-dma-tim/blob/master/main.c larger , have no dependencies except cmsis , stm32 device headers.
i wonder if can comment on or reproduce problem.
const struct { tim_typedef *tim; dma_typedef *dma; dma_stream_typedef *stream; unsigned channel; } cfg = { // uncomment needed combination below, tim1 , tim8 work // tim1, dma2, dma2_stream5, 6 tim8, dma2, dma2_stream1, 7 // tim2, dma1, dma1_stream1, 3 // tim2, dma1, dma1_stream7, 3 // tim3, dma1, dma1_stream2, 5 // tim4, dma1, dma1_stream6, 2 // tim5, dma1, dma1_stream0, 6 // tim5, dma1, dma1_stream6, 6 // tim6, dma1, dma1_stream1, 7 // tim7, dma1, dma1_stream2, 1 // tim7, dma1, dma1_stream4, 1 }; enum { dma_sxcr_dir_p2m = 0, dma_sxcr_psize_word = dma_sxcr_psize_1, dma_sxcr_msize_word = dma_sxcr_msize_1, }; #define dma_sxcr_chsel_num(ch) ((ch) << dma_sxcr_chsel_pos) uint32_t buf; void start(void) { systick->load = 0xffffffu; systick->val = 0; systick->ctrl = 5; rcc->ahb1enr |= rcc_ahb1enr_gpioaen; rcc->apb2enr |= rcc_apb2enr_tim1en | rcc_apb2enr_tim8en; rcc->apb1enr |= rcc_apb1enr_tim2en | rcc_apb1enr_tim3en | rcc_apb1enr_tim4en | rcc_apb1enr_tim5en | rcc_apb1enr_tim6en | rcc_apb1enr_tim7en; rcc->ahb1enr |= rcc_ahb1enr_dma1en | rcc_ahb1enr_dma2en; led_port->moder |= 1 << (2 * led_pin); led_port->ospeedr |= 3 << (2 * led_pin); // fastest speed cfg.tim->cr1 |= tim_cr1_arpe; cfg.tim->arr = 16; cfg.tim->psc = 1000; cfg.tim->egr = tim_egr_ug; // generate update event copy arr shadow cfg.tim->dier |= tim_dier_ude; cfg.stream->cr |= dma_sxcr_chsel_num(cfg.channel) | dma_sxcr_dir_p2m | dma_sxcr_psize_word | dma_sxcr_msize_word; cfg.stream->ndtr = 16; cfg.stream->par = (uint32_t) &gpioa->idr; cfg.stream->m0ar = (uint32_t) &buf; cfg.stream->cr |= dma_sxcr_en; cfg.tim->cr1 |= tim_cr1_cen; // wait until dma state changes while (cfg.dma->lisr == 0 && cfg.dma->hisr == 0) delay_ms(1); // check teifx bits int error = (cfg.dma->lisr | cfg.dma->hisr) & 0x02080208; while (1) { led_port->odr ^= 1 << led_pin; delay_ms(error ? 100 : 500); } }
there used answer here got deleted reason. author though.
looking @ bus matrix, becomes clear peripheral bus of dma1 only connected apb1. not part of matrix @ all. means dma1 can handle transfers from/to apb1 peripherals. since gpio ahb peripheral, not accessible dma1. should apply other apb2 (e.g. spi1) , ahb peripherals (e.g. otgfs). normally, not make sense access ahb or apb2 peripherals dma1 because requests not routed dma1. however, may needed convoluted cases gpio timer.
i think point made more obvious in documentation.
Comments
Post a Comment