2019-03-27 09:08 AM
Hi,
I use a timer channel and a DMA stream to generate a PWM signal.
At Transfer Complete interruption, I swap the channel to input capture mode to get an answer from external device, using the same DMA.
At transfer (reception) complete, I swap again to output compare mode.
It works, except that after having received data and reconfigured the timer channel to output compare, the first two data loaded by the dma into the CCR are not taken in account and the timer channel output stays 1 for two periods.
(It does the same if under debug I manually disable the DMA and force a value into the CCR)
The peripheral don't understand the command and of course do not send any answer. But after that, the timer channel is set again to output compare for next cycle and the output works again normally for one cycle.
So one in two of the cycle works : I send the command, I read the peripheral answer, but I can't send a right command just after having received an answer.
If I configure the external device to do not send answer, it works perfectly, I can send data, turn in input compare, later turn again in output compare and send the data correctly.
So the problem occurs only when the external device send an answer and a TC IT occurs.
To set in output compare mode I use TIM_OCxInit() and TIM_OCxPreloadConfig()
To set in input compare I use TIM_ICInit()
I also change the direction of DMA
I do miss something but do not know what.
Can anybody help?
Thanks in advance.
Ludovic
2019-03-27 09:16 AM
I forgot to say that I tried to deinit (TIM_DeInit) and reinit (TIM_TimeBaseInit + TIM_OCxInit) the timer after having received the "answer" but unsuccessfully, the problem stays the same.
2019-03-27 09:26 AM
You're probably going to want to get more familiar with the TIM peripheral at a register level, and get the transition down to a minimum without tearing everything down and reconfiguring.
Ideally you might construct the capture side to use a second channel in indirect more ie CH2 using CH1 input indirectly, so you can just disable the CH1 output as necessary.
Perhaps also look at the protocol at a wave form level and determine if there is a better or more effective way of implementing it. Sounds like some 1-wire protocol
2019-03-27 09:38 AM
Hi, thanks for your response.
I already use the TIM peripheral at register level inspired from sdtLibrary and of course follow the timing to stay in the needed response time. Unfortunately, I cannot use the CH2 in indirect mode because it is already used (in fact I use the four channels), and I cannot change the protocol to more than one wire...
The thing is I do not understand why the timer output stays locked to 1 for two cycles, and only when data has been received before.
2019-03-27 02:29 PM
As Clive said, a lot depends here on the details, so you need to understand very well what you are doing.
> The thing is I do not understand why the timer output stays locked to 1 for two cycles, and only when data has been received before.
I can't explain 2 cycles without seeing actual code (and maybe not even after that), but for example the CCR preloading sometimes results in effects which may be really hard to understand.
JW
2019-03-29 02:06 PM
Hi,
In fact, I have found my problem... when I was swapping from input to output mode, I was restarting the timer after the dma.
I do not understand exactly why, but starting the dma after the timer has solved my problem.
I was thinking that it could be possible to configure and start the dma and then enable the timer at the time I want it to start while filling the CCR data from dma. If it is possible, I have not found the solution for it to work at first output.
Thank you for your suggestions
Ludo
2019-03-29 03:37 PM
As it's been said, lot depends on the very details, and can't really be discussed without a complete description of the content of relevant registers at the key moments.
JW
2019-03-29 11:33 PM
True, anyway, if you change from output to input manually using SW interrupt, why using DMA in the first place, because you might need both change GPIO.MODER (unless open drain with pull-up?) AND DMA direction bit. Then just do it purely by SW, in this case you'll have to calculate the worst case interrupt delay jitter due to other's and check the duration: for example when turning from output to input, there will be an ISR dead time for monitorint the incoming edge. A min dead time between edges.
2019-03-30 05:33 AM
I use dma because I have four charnels to manage synchroniously in both ways and I need up to 1,2 Mbit data transfer with less than 80ns of error. Only a timer and dma can do.
2022-03-09 06:44 AM
Hi @Ludovic Durand-Texte , I know its been a while since your post but I'm having the same issue as you had.
Can you please share the sequence you did for the input and output change? The functions you use and the configuration needed.
It will help me a lot..!
Thanks you!!