Closed fpistm closed 5 years ago
I need this feature: https://github.com/rogerclarkmelbourne/Arduino_STM32/blob/master/STM32F1/libraries/A_STM32_Examples/examples/Maple/TimerInterrupts/TimerInterrupts.ino#L35
Something like this, but user friendly: https://github.com/adafruit/Adafruit_ZeroTimer/
Edit @fpistm: Add #104 request here.
On AVR, I usually use this library, the API is simple enough: https://www.pjrc.com/teensy/td_libs_TimerOne.html
But it only allows to use timers for interrupt callback. You cannot configure a timer as quadrature encoder counter from it for example.
Timer1 and Timer3 are good libs! This one too: https://github.com/wimleers/flexitimer2
My requirements: 1) Interrupt driven function call with resolution: 1us, 1ms, 1s. 2) better PWM generation: flexible PWM frequency, flexible counter, up-up/up-down (e.g. https://github.com/Adminius/Dimmer32u4)
Someone knows why libraries do not work Timer1 ... 2 ... flexitimer2 in board STMF303 - F303K8
@franciscogimeno2000 simply because not ported for stm32. Ex Flexitimer uses direct register acces but this is not the same for stm32. Goal of this issue is to collect requirements/proposal/API examples... to implement timers management useful for community. Any contributions are welcom 😉
OK, you have some example of using a basic timer.?
For my projects i usually use particle boards, the are also based on STM32. Take a look on their Software Timer https://docs.particle.io/reference/firmware/photon/#software-timers
They use Free RTOS, also available for more stm32 boards, but if you don't want use Free RTOS can you use the same interface for class.
PS: remember to use also std::function as callback.
I have a NUCLEO F1 and F4 and spent the weekend trying to use timer.h / timer.c with them. It was a struggle.
For example (I'm going to truncate my code, and I don't have to use timer_enable_clock(_timer.handle);
because I tried, and as far as I can tell it is called by these Inits), this does not work:
stimer_t _timer;
TimerHandleInit(&_timer, 100000, 384);
attachIntHandle(&_timer, handle_clock);
Yet, this does:
stimer_t _timer;
TimerPulseInit(&_timer, 500, 40000, pulse_clock);
TimerHandleInit(&_timer, 100000, 384);
In my callback I blinked an led and I used the following to debug after initializing:
Serial.println(getTimerIrq(_timer.handle.Instance)); Serial.println(getTimerClkSrc(_timer.handle.Instance)); Serial.println(getTimerClkFreq(_timer.handle.Instance));
In the first example I got: 0, 0, 0 In the second example I got: 28, 1, 84000000
From looking through the code, the TimerPulseInit actually assigns a timer:
obj->timer = TIMER_SERVO;
Whereas TimerHandleInit does not assign a timer.
In fact, I couldn't figure out for the life of me how to assign a specific timer to either of these functions, however I tried _timer.timer = TIM2;
and it worked:
stimer_t _timer;
_timer.timer = TIM2;
TimerHandleInit(&_timer, 100000, 384);
attachIntHandle(&_timer, handle_clock);
Can I suggest the following:
1) You should be able to assign a timer when you declare your stimer_t obj:
stimer_t _timer(TIM8);
2) You should be able to assign a callback to TimerHandleInit:
void TimerHandleInit(stimer_t *obj, uint16_t period, uint16_t prescaler, void (*irqHandle)(stimer_t *))
This would greatly simplify everything. I think this is almost there, and the efforts to simplify the setup are good so far... just needs a bit of polish.
Thanks for the feedback @marcdepape. I will review all inputs.
hello is this implimented already? http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/latest/lang/api/hardwaretimer.html
Currently not. Time is missing, this is in the task list... this will come.
Any updates on this request at all?
If not, is there at least any indication of which library / API you're looking to implement (ie Whether it will be the same as the existing HardwareTimer or one of the others mentioned)?
I know this is waited, unfortunately, I was not able to work on this. I hope work on this after all USB stuff and core release 1.5.0 done.
Maybe this one could be a good starting point: https://github.com/danieleff/STM32GENERIC/tree/master/STM32/libraries/HardwareTimer
/cc @ABOSTM
Currently using custom board with f407vgt and f103vet. Tried everything to create pulses (like rc controller) using pwm with no luck. So i decided to try configuring analog.h and c files. Simple configuration changes in pwm_start function solved this problem perfectly. After this point copied necessary functions to ino file. Basically tried everything even including rerouting include parts and using extra libraries external and internal. This method worked only in analog file. So added an extra function to analog h and c files. Working this way without problem so far.
Second problem is using timers with input capture mode. Trying to acquire timings of a ppm like coded pulse without interrupting running function. So far couldn't start any timer with input capture mode.
Can you give me any idea or point to a direction? If i can't solve this problem a huge code is needed to convert to another IDE and this requires massive work load.
Thank you to the team, project is going perfect this far.
@thedirectorone: difficult to understand what is wrong with 1st problem: what is your use case , what you tried, what changes you modified ... But at least that is great, as your solution is working so far. 2nd problem: Input capture is clearly part of our thoughts for hardware library.
Meanwhile you may consider using STM32 cube HAL or LL drivers. Those drivers are already included in Arduino_Core_STM32. Those drivers can be called directly from your sketch/application.
Example on how to use input capture with HAL is available here: https://www.st.com/en/embedded-software/stm32cubef4.html STM32Cube_FW_F4_V1.24.1\Projects\STM32F446ZE-Nucleo\Examples\TIM\TIM_InputCapture\
Similar example is available on github but for a different STM32 family: https://github.com/STMicroelectronics/STM32CubeG4/tree/master/Projects/NUCLEO-G474RE/Examples/TIM/TIM_InputCapture
Example on how to use input capture with LowLayer (LL) drivers is available here: https://www.st.com/en/embedded-software/stm32cubef1.html STM32Cube_FW_F1_V1.7.0\Projects\STM32F103RB-Nucleo\Examples_LL\TIM\TIM_InputCapture\ Note: LL drivers is recommended for expert (it needs in-deep MCU Hardware knowledge).
Maybe this one could be a good starting point: https://github.com/danieleff/STM32GENERIC/tree/master/STM32/libraries/HardwareTimer
Does this work out of the box @fpistm ? I can test this with a quadrature encoder...
@BennehBoy : unfortunately it doesn't work out of the box. And also quadrature encoder is not implemented.
@fpistm I'm currently using the STM32GENERIC HardwareTimer lib from https://github.com/huaweiwx/STM32GENERIC/tree/master/STM32/libraries/HardwareTimer it have more features than Daniel's and is full HAL compatible.
The lib ain't complete but is a good start. For setting a period, start and get into interrupts work well. PWM is at https://github.com/huaweiwx/STM32GENERIC/blob/master/STM32/cores/arduino/stm32/stm32_PWM.c
Hi ,
will we be able to use arduino timers interrupt commands after ?
François
Hi @Astroghost-Francois, Yes, it will be possible to use interrupts on HardwareTimer library (through dedicated API from HardwareTimer library) : on update event (timer rollover) as well as compare match event corresponding to one of the channel.
Hi all, @ABOSTM do the PR of the HarwareTimer implementation. Do not hesitate to give us your feedback. Thanks
I installed all latest libs/cores but i dont know how to enable the HardwareTimer:
'HardwareTimer' was not declared in this scope
code i used:
HAL_TIM_MODULE_ENABLED
#if defined(LED_BUILTIN)
#define pin LED_BUILTIN
#else
#define pin PA1
#endif
void setup()
{
// no need to configure pin, it will be done by HardwareTimer configuration
// pinMode(pin, OUTPUT);
// Automatically retrieve TIM instance and channel associated to pin
// This is used to be compatible with all STM32 series automatically.
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM);
uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
// Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished.
HardwareTimer *MyTim = new HardwareTimer(Instance);
// Configure and start PWM
// MyTim->setPWM(channel, pin, 5, 10, NULL, NULL); // No callback required, we can simplify the function call
MyTim->setPWM(channel, pin, 5, 10); // 5 Hertz, 10% dutycycle
}
void loop()
{
/* Nothing to do all is done by hardware. Even no interrupt required. */
}
i'm new with the st's core and not familiar with the HAL configs. I tried diffent stuff but i dont understand how to get it to work. How can i enable this lib?
You have to install the github version of the core & then apply this PR. The last release 1.6.1 will NOT include these changes.
On Sun, Aug 4, 2019 at 9:32 AM KJansun notifications@github.com wrote:
I installed all latest libs/cores but i dont know how to enable the HardwareTimer: 'HardwareTimer' was not declared in this scope
code i found:
`HAL_TIM_MODULE_ENABLED
if defined(LED_BUILTIN)
define pin LED_BUILTIN
else
define pin PA1
endif
void setup() { // no need to configure pin, it will be done by HardwareTimer configuration // pinMode(pin, OUTPUT);
// Automatically retrieve TIM instance and channel associated to pin // This is used to be compatible with all STM32 series automatically. TIM_TypeDef Instance = (TIM_TypeDef )pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM); uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
// Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished. HardwareTimer *MyTim = new HardwareTimer(Instance);
// Configure and start PWM // MyTim->setPWM(channel, pin, 5, 10, NULL, NULL); // No callback required, we can simplify the function call MyTim->setPWM(channel, pin, 5, 10); // 5 Hertz, 10% dutycycle }
void loop() { / Nothing to do all is done by hardware. Even no interrupt required. / }`
i'm new with the st's core and not familiar with the HAL configs. I tried diffent stuff but i dont understand to get it to work. How can i enable this lib?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/stm32duino/Arduino_Core_STM32/issues/146?email_source=notifications&email_token=AF6R4XQOFA3GH63JHULEZGTQC2HZNA5CNFSM4ECSN3NKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3P5CLI#issuecomment-517984557, or mute the thread https://github.com/notifications/unsubscribe-auth/AF6R4XXCRWO4EIYN25VOJFDQC2HZNANCNFSM4ECSN3NA .
You have to install the github version of the core & then apply this PR. The last release 1.6.1 will NOT include these changes. … On Sun, Aug 4, 2019 at 9:32 AM KJansun @.**> wrote: I installed all latest libs/cores but i dont know how to enable the HardwareTimer: 'HardwareTimer' was not declared in this scope code i found: `HAL_TIM_MODULE_ENABLED #if defined(LED_BUILTIN) #define pin LED_BUILTIN #else #define pin PA1 #endif void setup() { // no need to configure pin, it will be done by HardwareTimer configuration // pinMode(pin, OUTPUT); // Automatically retrieve TIM instance and channel associated to pin // This is used to be compatible with all STM32 series automatically. TIM_TypeDef Instance = (TIM_TypeDef )pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM); uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM)); // Instantiate HardwareTimer object. Thanks to 'new' instantiation, HardwareTimer is not destructed when setup() function is finished. HardwareTimer MyTim = new HardwareTimer(Instance); // Configure and start PWM // MyTim->setPWM(channel, pin, 5, 10, NULL, NULL); // No callback required, we can simplify the function call MyTim->setPWM(channel, pin, 5, 10); // 5 Hertz, 10% dutycycle } void loop() { / Nothing to do all is done by hardware. Even no interrupt required. / }` i'm new with the st's core and not familiar with the HAL configs. I tried diffent stuff but i dont understand to get it to work. How can i enable this lib? — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#146?email_source=notifications&email_token=AF6R4XQOFA3GH63JHULEZGTQC2HZNA5CNFSM4ECSN3NKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD3P5CLI#issuecomment-517984557>, or mute the thread https://github.com/notifications/unsubscribe-auth/AF6R4XXCRWO4EIYN25VOJFDQC2HZNANCNFSM4ECSN3NA .
Ok, thanks
Hello, I am using Arduino-IDE and STM32F407 Black Board and STM32GENERIC board definition. Here is my code to use timers:
// For Arduino-IDE
// Board: BLACK STM32F407, 168 MHz
// Hardware: STM32GENERIC (https://github.com/danieleff/STM32GENERIC)
// Board: F407Vxx
// Serial Comm SerialUART1
// Spec. Board Black F407VE (2.0)
// Upload SerialUART1 [TX:PA9, RX:PA10] connected via FTDI (3.3V)
#include <Arduino.h>
#include "HardwareTimer.h"
volatile uint32_t tick1, tick2, tick3;
// ----------------------------------------
// Attention: STM32F4 specific !!!
// fast GPIO set/reset:
#define GPIO_PIN_SET(PORT,pin) ((PORT)->BSRR = 1 << (uint32_t)pin)
#define GPIO_PIN_RESET(PORT,pin) ((PORT)->BSRR = (1 << (uint32_t)pin) << 16)
#define GPIO_HISPEED_SET(port,pin) (port)->OSPEEDR = (port)->OSPEEDR | (0b11 << (2*pin))
// ----------------------------------------
// ----------------------------------------
// Attention: STM32F4 specific !!!
// Timer1 clocks with 168 MHz
// Timer2,3 clocks with 84 MHz
// ----------------------------------------
// Interrupt routines
void Timer1_ISR() {
tick1++;
}
void Timer2_ISR() {
tick2++;
digitalWrite(PA7,!digitalRead(PA7));
}
void Timer3_ISR() {
tick3++;
// Simulate PWM dimmed LED 1/20 = 5% on
if ((tick3 % 20) == 0) GPIO_PIN_RESET (GPIOA,6); // == digitalWrite(P6,0);
else GPIO_PIN_SET (GPIOA,6);
}
void setup() {
Serial.begin(2000000);
pinMode(PA6,OUTPUT);
GPIO_HISPEED_SET(GPIOA,6);
pinMode(PA7,OUTPUT);
GPIO_HISPEED_SET(GPIOA,7);
Timer1.pause();
Timer1.setPrescaleFactor(1680 -1); // 0.1 MHz = 10 us / 1 tick = 1/168 us
Timer1.setMode(1, TIMER_OUTPUT_COMPARE_TOGGLE); // Pin toggles when counter reaches compare (effectively 50% PWM)
Timer1.setOverflow(20000 - 1); // 100000 / 20000 = 5 Interrupts /s
Timer1.setCompare(1, 10000); // Channel1, 10000 ticks = 50%
Timer1.attachInterrupt(1, Timer1_ISR); // channel1, handler
Timer1.resume();
Timer2.pause();
Timer2.setPrescaleFactor(840 -1); // 0.1 MHz = 10 us / 1 tick = 1/84 us
Timer2.setMode(2, TIMER_OUTPUT_COMPARE_TOGGLE); // Pin toggles when counter reaches compare (effectively 50% PWM)
Timer2.setOverflow(20000 - 1); // 100000 / 20000 = 5 Interrupts /s
Timer2.setCompare(2, 10000); // Channel3, 50%
Timer2.attachInterrupt( 2, Timer2_ISR); // channel3, handler
Timer2.resume();
Timer3.pause();
Timer3.setPrescaleFactor(84 -1); // 1 MHz = 1 us / 1 tick = 1/84 us
Timer3.setMode(3, TIMER_OUTPUT_COMPARE_TOGGLE); // Pin toggles when counter reaches compare (effectively 50% PWM)
Timer3.setOverflow(2 - 1); // every 2 us = >>>>>>> 500.000 Interrupts /s <<<<<<<<<<
Timer3.setCompare(3, 1); // Channel3, 50%
Timer3.attachInterrupt( 3, Timer3_ISR); // channel3, handler
Timer3.resume();
}
void loop() {
Serial.print(micros()); Serial.print("us: tick1: "); Serial.println(tick1);
Serial.print(micros()); Serial.print("us: tick2: "); Serial.println(tick2);
Serial.print(micros()); Serial.print("us: tick3: "); Serial.println(tick3);
delay(1000); // 1 second
}
1314059001us: tick1: 6570 1314059094us: tick2: 6570 1314059196us: tick3: 657000110 1315059001us: tick1: 6575 1315059094us: tick2: 6575 1315059196us: tick3: 657500110 1316059001us: tick1: 6580 1316059094us: tick2: 6580 1316059196us: tick3: 658000110
Using digitalWrite - not GPIO - it should work on most STM32 boards.
Hi @MacLeod-D
I am using Arduino-IDE and STM32F407 Black Board and STM32GENERIC board definition.
Don't know what did you expect? Here this is for the STM32 core not the STM32GENERIC . use the forum which is used for primary support.
This issue is to open discussion around Timer management in order to provide useful API. Current implementation is limited to support basic Arduino function. Any help/comment are welcome.