2019-06-10 02:02 PM
I've been trying to get any DMA2 stream-channel (presently TIM1_UP) to update TIM1 CCR1,2, or 3 registers using a table in memory for a while now with no luck. Before adding some of my code here, I thought I would see if anyone has ever actually gotten that to work before.
The manual is vague and there are a few web pages that mention passing capture registers to memory (peripheral to memory) and supposedly the other way around should work.
I have ADC1, ADC2, ADC3 succesfully transfering to memory though. That seemed easy compared to this.
I have the DMA2 Stream5 NDTR doing the right thing when TIM1 is enabled to do so but the data, IF coming from memory to peripheral is going out into space somewhere.
Direct mode, FIFO mode, Double buffer mode.... Nothing seems to put data into any of those CCR registers from the data array
A software example of this would be really nice if anyone knows of one out there. There is a thread from 2016 where Clive pointed to one I think but that link is now dead.
A couple of additional questions...
The TIM1&TIM8 DMAR register (for full transfer)...
What does that mean exactly, "for full transfer" ? Is the DMAR necessary for loading CCRx from memory in DMA mode ?
Why would I see others (code examples on the interweb) do this...
DMA2_Stream5->PAR = (uint32_t) &TIM1->DMAR;
DMAR is supposed to contain the start of the peripheral address, why would they want the address of the DMAR in the DMA2 Peripheral Address Register ?
And what exactly do they mean by peripheral control or DMA controller control ? Is that the trigger only ?
Thanks,
boB
2019-06-11 03:15 PM
Thanks. This helps a lot. In debugging, I do have to go back and forth between the DMA2 and TIM1 (or TIM8) screens but at least I can see what I basically need. It's just time consuming. Maybe some automation could help but at what time cost to develop tools ?
I started this whole project with ST Cube and that went great until I needed to add DMA. When I needed to see new code, I would just create a new CUBE project and examine that code and use what I could make out of it.
I MUCH prefer to change bits directly rather than the HAL method though. I came from an assembly language background so it's more intuitive for me rather than all these structures embedded with structures.
Also, I updated CUBE MX and now it creates code for IAR EWARM 7 and up instead of 6.x which is our main system except for a single seat of version 7 now which I would rather keep for another SW engineer. At least I can look at the code it creates.
Thanks again for your awesome insights !
2019-06-11 04:30 PM
OK, NOW, trying to get DMA2 to do what I want to, I find that the TIM1 MOE output enable DISABLES itself (also AOE) when the REP RCR count is done.
The reasons I see for this in the documentation are when a BREAK is generated in TIM1. ALL my break generation bits are zero. I'm not even sure
what break means ?
MOE will stay high and output continue pulses only if I set DMA not to update the CCRx registers.
Is there another reason that MOE might go low besides dead time generation DTG or break that I am not seeing in the documentation maybe ?
This MAY be related to DBM double buffer mode which is really what I would like to have working so I can update waveform table based on CT status.
Also, I thought there was a way to stop the timer only after the NDTR in Sream register went to zero. Is that still true ? I would like to have an entire half cycle of my waveform table pulsed out of TIM1 and TIM8 before getting an interrupt.
Now I'm not sure if this is going to work.
2019-06-11 04:42 PM
There are several things I could upload but a couple of debug captures of registers might be useful to add to my ********...
EDIT: JUST noticed I am getting some DMA2 Stream 5 error flags. THAT will disable my stream... BUT should not have any effect on the TIM1 MOE output enable bit as far as I can see with the documentation.
The DMA2 Stream 5 registers expanded ... Not my end DMA mode necessarily, just some of what I am getting.
The Timer 1 registers after a typical DMA trigger.
To get the red updated numbers, I have to hit F5 again but that's OK.
2019-06-11 06:00 PM
They got a bit sloppy with the DMA stream x configuration register (DMA_SxCR) bits part of the reference manual... CHSEL[3:0] should be CHSEL[2:0], they forgot the [1:0] in MBURST[1:0] and I'm finding a few other missing words here and there...
So, when in Memory to Peripheral DMA mode and using the FIFO, I set the MBURST amount in my case to 01 which is INCR4 or burst of 4 beats (I assume 4 beats of 1/2 words in my case), BUT does PBURST need to be set for Memory to Peripheral DMA transfers ?
I don't think I am seeing that stated.
2019-06-12 12:46 AM
Don't use bursts until you *exactly* know what are you doing, especially on the peripheral side. Maybe refrain from using FIFO at all, for a safe starting point; there are alignment constraints for using FIFO/bursts which may not be obvious at the first sight (read the documentation very, very, very carefully if you really think you need to use them).
But the main problem is, that you use increment on the peripheral side, it means, that you write the first transfer into the DMAR register, but each subsequent writes go further and further up in the TIM registers area, until it overwrites the register containing MOE.
Note what have I said on viewing the pointer registers in DMA in my previous post.
JW
2019-06-16 11:56 AM
JW, I took your advice and got this to work with minimum extra added features. Circular mode, which turns on automatically with double buffer mode turned on, appears to work as well, but I stop TIM1 and transfers in the Transfer Complete TC interrupt.
Thanks for making me start with minimum operation first !
Now on to see if I can get two CCRx register DMA updates to work in TIM1 and TIM8 and keep my 3 ADC DMAs operational as well.
2019-06-17 07:12 PM
One question I still have is regarding the DMA2 request mapping table.
Stream 6 channel 0 has these 3 triggers (?)
TIM1_CH1
TIM1_CH2
TIM1_CH3
Stream 6 channel 6 has this one trigger
TIM1_CH3
Since TIMER 1 (and 8) has a DMA enable for each of these timer channels
CC1DE, CC2DE, CC3DE, CC4DE
WHY don't they just have all 4 channels in channel 0 and not just the 3 channels ?
Why would ST do things this way ? There must be a reason but I don't understand.
And what is COMDE good for ? I did not understand ST's documentation for this one.
I think it has something to do with channels that have a Negative output on one of the CCRx pins
(complement or commutate ?)
Then there is Stream 4 channel 6 that has these 3 triggers...
TIM1_CH4
TIM1_TRIG
TIM1_COM
Any idea why these three would be on the same channel ?
Thanks for any insight on, I think, my last questions regarding DMA. Hopefully.
2019-06-17 11:12 PM
For most timers, the DMA request sources as enabled by respective xxxDE in TIMx_DIER, are ORed together and there's only one common stream/channel available for them. For TIM1 and TIM8 there are more options, where more sources are given, these are again ORed together. You are not supposed to use them at once.
I guess the particular picks are mostly random, maybe they stemmed from some important customer's request at an early design stage of a particular family ('F4).
Note, that the advanced timers have also a quirk, where by setting TIMx_CR2.CCDS, the CCx DMA triggers may occur when update occurs.
COM signal stands for Commutation event, it's a badly explained feature of the advanced timers. In those, not only ARR and CCRx can be preloaded (shadowed), but also CCxE, CCxNE and OCxM bits, if TIMx_CR2.CCPC is set; and they get loaded into their respective "active" registers (TIMx_CCER/TIMx_CCMRx) upon the COM event. And COM event is generated by rising edge of TRGI (as selected by TIMx_SMCR.TS) if TIMx_CR2.CCUS is set, or in software by setting TIMx_EGR.COMG.
JW
2019-06-18 03:58 PM
Thank you again, Jan.
You are a great adjunct to ST and I think that you should be getting paid as a consultant or applications person.
Things are now working thanks mainly to your help and others too.
I was wondering if those trigger sources were ORed or not. Makes perfect sense that they are. One Stream configured to be used to update one register at a time.
Now, I wonder why this part does not have a CAN peripheral DMA trigger ORed into maybe one with a UART DMA trigger source. CAN peripherals must have come recently and they didn't have time I guess... OR, like you propose, ,maybe that one customer (if that was the case) didn't need CAN or DMA for CANBUS.
I will be using the CAN also pretty soon.
boB