cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F405 32-bit timer in encoder mode

ksi
Associate II
Posted on March 09, 2015 at 23:42

I'm using STM32F405 TIM5 in encoder mode. As it is 32-bit timer I want to have the CNT register to hold actual position so I wouldn't need software assistance once it is setup, just read the counter.

However it looks like I can NOT initialize the counter to what I want.

When I'm writing e.g. 0x7ff to the CNT register it works. I can read 0x7ff back after writing, counter counts from that value when encoder moves.

The problem starts when I'm trying to initialize the counter with bigger value, more that 16 bits. When I'm writing e.g. 0x7fffffff into it (with 32-bit str instruction in assembly so that is not a C quirk) CNT reads back as 0 and encoder counts from zero. It looks like writing anything bigger than 0xffff (i.e. more than 16 bits) just resets the counter to zero.

Am I missing something? Are there some magic hoops I have to jump to initialize it to the value I need (bigger than 16 bit) or it is a Silicon Bug and I should kiss it goodbye?

Documentation is misleading -- ALL timer registers are shown as 16-bit but that nice picture with memory locations shows it as 32-bit. There is absolutely no mention of something special about initializing that timer CNT register. No mention of 16-bit only, no counter reset, nothing.

Can somebody shed a light on what's going on and how to work around it?
4 REPLIES 4
jpeacock
Associate II
Posted on March 10, 2015 at 14:00

The RM shows timer 2 and 5 with 32 bit CNT and CCR.  The ST peripheral library also uses 32 bit access to set CNT and CCR.  Is it possible the compiler is casting these operations as 16 bits in some way?

When I ran the encoder on TIM5 it did show a 32 bit -1 (0xffff ffff) when it overshot the zero position, so the capture compare does report 32 bit.

  Jack
ksi
Associate II
Posted on March 10, 2015 at 18:01

Yep, it works in 32 bit mode once initialized. The only problem is it is NOT possible to load anything over 0xffff into Timer 5 counter. Anything under 16 bit works, anything over resets the counter so it has 0 in it. You write 0xffff and the counter reads back 0xffff. Write 0x1ffff and it is loaded with 0.

And no, it is NOT a compiler because I'm writing it from ASSEMBLY code with 32-bit ''str'' instruction so I am 100% sure it is a 32-bit write.

Looks like a Silicon Bug to me. As it is usual for ST undocumented, not mentioned anywhere.

And I do NOT use capture. I read the counter directly. No interrupts, no capture, no software. Encoder moves, counter tracks it. No need for capture, interrupts, any software. Just read the counter.

The only problem is how to preload that counter with half-scale value (0x7fffffff) for biasing it so it would get the full SIGNED int32 range with a trivial math (anything below 0x7fffffff is negative -> -(0x7fffffff - actual counter value); anything over is positive -> (actual value -0x7fffffff).)

I'm pretty sure there will be no reply from ST :(

jpeacock
Associate II
Posted on March 10, 2015 at 18:49

Using the CNT instead of CCR you get some LSB noise since it can oscillate if the encoder stops on an edge.  Capturing on one edge on one phase (i.e. CW leading edge, CCW falling edge) minimizes the LSB oscillation.

What happens if you load it as two 16-bit writes?  Is the timer disabled or stopped when you set the CNT?  What's the ARR set at?

  Jack

ksi
Associate II
Posted on March 10, 2015 at 19:53

Damn, I hate those forums! The stupid thing crashed (''Sorry we had an unhandled exception, blah-blah'') and ate my entire message that took me some time to write when I hit ''OK'' button to post it.

OK, one more attempt -- ARR is set to 0xffffffff but it doesn't matter because it behaves the same when set to e.g. 0xefffffff. Autoreload is NOT supposed to happen at all; that is what that half-range bias is for. If it DID happen we have a catastrophic failure -- something went wrong and we have no other choice but to halt.

It behaves exactly the same whether counter is stopped or not. 16-bit writes I did not try because it makes no sense and ST docs (RM) clearly tell that ALL writes to ALL 32-bit registers must be done as a single 32-bit write operation.

This not actually the first report of such behavior. There is another one about the very same issue with a very helpful reply from ST stuff kinda like ''You don't use ST Library properly'' with nothing else but just that.

OK, won't repeat my lengthy message that stupid forum just ate, don't want to waste my time again. Let's hope this one made it through...