Counter in Encoder mode.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Counter in Encoder mode.

Post by rew »

I have not found a "driver" in chibios to use a counter in "encoder mode".

But "DIY" should not be too difficult. I have found an example for STM32F40x on github

Code: Select all

  stm32_tim_t *enc = STM32_TIM4;

  palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(2) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_PUDR_PULLUP);
  palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(2) | PAL_STM32_OTYPE_PUSHPULL | PAL_STM32_PUDR_PULLUP);

  rccEnableTIM4(TRUE);

  enc->SMCR = 3;        // encoder mode 3
  enc->CCER = 0;        // rising edge polarity
  enc->ARR = 0xffff;    // count from 0-ARR or ARR-0
  enc->CCMR1 = 0xc1c1;  // f_DTS/16, N=8 IC1->TI1, IC2->TI2
  enc->CNT = 0;         // initialize counter
  enc->EGR = 1;         // generate an update event
  enc->CR1 = 1;         // enable the counter


For my case, where I intend to use TIM15 and PA2/PA3 I have:

Code: Select all

#define MYTIMER TIM15

  palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(0));
  palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(0));
  GPIOA->PUPDR |= 0x50; // enable pullups.

  rccEnableTIM15 (FALSE);

  MYTIMER->CR1 = 0;
  MYTIMER->CR2 = 0;
  MYTIMER->SMCR = 3 * TIM_SMCR_SMS_0;
  //MYTIMER->SMCR = 0;
  MYTIMER->DIER = 0;
  MYTIMER->EGR = 0;
  //  MYTIMER->CCMR1 = 0xf1f1;
  MYTIMER->CCMR1 = 0xc1c1;
  //  MYTIMER->CCER = 0x91;
  MYTIMER->CCER = 0x00;
  MYTIMER->PSC = 0;
  MYTIMER->ARR = 0xffff;
  MYTIMER->RCR = 0;
  MYTIMER->CCR1 = 0;
  MYTIMER->CCR2 = 0;
  MYTIMER->BDTR = 0;
  MYTIMER->DCR  = 0;
  MYTIMER->CNT  = 0;
  MYTIMER->DMAR = 0;
  MYTIMER->EGR  = 1;

  MYTIMER->CR1 = TIM_CR1_CEN;
I've tried to initialize all registers, even though a bunch of course don't matter. I've verified that the RCC enable for the timer is neccessary and works. (if I remove the call rccEnable... the counter registers ALL read back as zero).

The counter register (TIM15->CNT) ALWAYS reads back as zero. (unless I initialize it to another value, then it remains at that value).


Anything I'm missing here?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Counter in Encoder mode.

Post by Giovanni »

Hi,

An encoder driver was submitted a while back, see hal_qei.c/h in the community directory.

Is that what you need?

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: Counter in Encoder mode.

Post by rew »

I copied over all the code from lld_qei to my own code. No change: counter remains at zero.....

Hardware question: Do the TIMxCH1 and TIMxCH2 pins need to be in AF mode assigned to the timer? I would think that in this case the INPUT side of the timer could continue to work?

Hardware question: The qei driver seems to support timers 1-8, I'm trying to use 15. Is there a bug in the reference manual that TIM15 does not support encoder mode, even though the manual states that it does? (The manual also mentions CCMR2, in the TIM15 section. That register does not exist in TIM15 on STM32F072).

OK. I have continued to try to use TIM1.... Changed the hardware, updated the software implemnetation for the other pins and... voila it works! The software and the hardware counters run in sync.

Reliability has dropped a lot: I think I have enabled the pullups, I have verfiied the PUPDR, but it looks as if PA8/PA9 require more pullup to function reliably than PA2 PA3. Odd.... I just verified the pullup on PA2, 3 and 9: All 80-90 microamps.

So.... What could be the difference between TIM1 and TIM15?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Counter in Encoder mode.

Post by Giovanni »

Internal pullups are very weak.

Are clocks enabled?

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: Counter in Encoder mode.

Post by rew »

Yeah. I verified that if I leave out the rccEnableTIM15 (); all register writes are lost. Are there other "clocks" that need to be enabled? If I do not put the timer in SLAVE mode, it starts counting, so I think it has clocks.... Any other clocks that need enabling?

The "unreliable with PA8/PA9 pullups" is not a problem. This was a test, and that encoder was one I happened to have lying around. It's twenty years old. The datasheet recommends 2k7 pullups. The STM pullup current of 80 microamps calculates to about 40k. Sounds about right. Just a little less (i.e. stronger pullup) than what ATMEL specifies for the atmega328.

So now I have it working with TIM1 on STM32F072, and I want to port this to one of my other USB-capable boards, to try to diagnose what's wrong with TIM15 on STM32F072. What is the proper procedure to port this application to one of my other boards?
dsc06714.jpg
(the 030 doesn't have USB, so that leaves 9 boards to try.... )

(The STM32F405 stops in unhandled exception with a track into 0x55555554, which means it's ran out of stack, right?)
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Counter in Encoder mode.

Post by Giovanni »

The RCC clock for that timer.

Porting the application requires edits to the Makefile and replacing mcuconf.h with the proper one.

Giovanni
rew
Posts: 383
Joined: Sat Jul 19, 2014 12:59 pm
Has thanked: 2 times
Been thanked: 14 times

Re: Counter in Encoder mode.

Post by rew »

AND editing that mcuconf.h file with my changes to enable the things I need.
AND editing that Makefile with my changes to allow the things I need.
Post Reply