2024-07-07 01:55 PM
I’m using CubeIDE + HAL and I want to have TIM20 CH1 execute a capture compare interrupt and I want CH2 to execute a DMA transfer. I can use each separately, but together they fail. Either the timer resets stop functioning, or the counter stops counting up.
HAL has functions for IT and DMA, but not for both in tandem. Is this supported by the hardware? If so, what initialization commands\registers do I need to change to get both to function simultaneously?
2024-07-07 02:14 PM
HW should certainly support IRQ / DMA via different channels
2024-07-07 03:18 PM
Good. I guess it appears HAL\Cube doesn't...so I need a working code fragment where it's configured manually. Any pointers to a reference project?
2024-07-08 04:05 AM
Probably nothing ready-made. ST refuses to produce normal examples, pushes Cube. I have some random examples some of which use timer-triggered DMA and perhaps also timer-triggered interrupts, but not for 'G4 specifically, not specifically using both DMA and interrupt, and none better than what you can find randomly on the nets.
OTOH, this all is pretty basic stuff; the problem is, that you have to unlearn Cube and walk down the path you've avoided when you've chosen to use Cube.
The basic steps are:
- enable GPIO clock in RCC, for selected TIMx_CHx pins set AF in GPIOx_MODER and the proper AF number in GPIOx_AFR[]
- enable timer clock in RCC, set TIMx_ARR/TIMx_PSC as needed (mind PSC preloading) for period, set TIMx_CCRx for "pulse length", set TIMx_CCMRx.CCxS to select Compare vs. Capture, for Compare set PWM mode in TIMx_CCMRx.OCxM; enable given channel in TIMx_CCER.CCxE, enable timer counter by setting TIMx_CR1.CEN
- for interrupt, enable by TIMx_DIER.CCxIE, enable interrupt in NVIC using the CMSIS intrinsics (NVIC_EnableIRQ(), NVIC_SetPriority() if needed) and write the ISR, sticking to the ISR's name in vector table in startup code, in which qualify the interrupt source according to TIMx_SR and then clear it in TIMx_SR
- for DMA:
-- enable DMA clock in RCC
-- in TIM enable by TIMx_DIER.CCxDE
-- steer request from TIM to a selected DMA Channel in DMAMUX
-- for given DMA Channel, set up the memory and peripheral side pointer registers CMAR/CPAR, set number of transfers in CNDTR, set up fields in control register (at least transfer widths and transfer direction and probably MINC) and enable
-- if you want to be notified of the DMA Transfer Complete (and/or Half Transfer), enable also those in the control register, and then enable interrupt in NVIC, and write the ISR where you qualify the interrupt in DMA_ISR and clear in DMA_IFCR
That's roughly all.
JW