Port Flexitimer2 for ESP32

SoCalPinPlayer
Posts: 3
Joined: Sun Aug 20, 2017 1:35 am

Port Flexitimer2 for ESP32

Postby SoCalPinPlayer » Sun Aug 20, 2017 1:41 am

I am building a quadruped robot and the example code uses a library call Flexitimer2. I have search through google and can't find where anyone has ported this library over for the ESP32. I am using the Sparkfun ESP32 Thing board which is so far working great.

Any help or direction as to how to port this library to work for the ESP32 would be greatly appreciated.

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Re: Port Flexitimer2 for ESP32

Postby kolban » Sun Aug 20, 2017 5:14 am

Do you have a link to the original source for that library?
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

SoCalPinPlayer
Posts: 3
Joined: Sun Aug 20, 2017 1:35 am

Re: Port Flexitimer2 for ESP32

Postby SoCalPinPlayer » Sun Aug 20, 2017 7:52 pm

Hi Kolban

Thanks for the quick response.

Here is the link to the GitHub for Flexitimer2...

https://github.com/wimleers/flexitimer2

They did add the capability for it work with the teensy as well.

Here is the .cpp

/*
FlexiTimer2.h - Using timer2 with a configurable resolution
Wim Leers <work@wimleers.com>
Based on MsTimer2
Javier Valencia <javiervalencia80@gmail.com>
History:
6/Jun/2014 - Added Teensy 3.0 & 3.1 support
16/Dec/2011 - Added Teensy/Teensy++ support (bperrybap)
note: teensy uses timer4 instead of timer2
25/April/10 - Based on MsTimer2 V0.5 (from 29/May/09)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <FlexiTimer2.h>

unsigned long FlexiTimer2::time_units;
void (*FlexiTimer2::func)();
volatile unsigned long FlexiTimer2::count;
volatile char FlexiTimer2::overflowing;
volatile unsigned int FlexiTimer2::tcnt2;
#if defined(__arm__) && defined(TEENSYDUINO)
static IntervalTimer itimer;
#endif

void FlexiTimer2::set(unsigned long ms, void (*f)()) {
FlexiTimer2::set(ms, 0.001, f);
}


/**
* @param resolution
* 0.001 implies a 1 ms (1/1000s = 0.001s = 1ms) resolution. Therefore,
* 0.0005 implies a 0.5 ms (1/2000s) resolution. And so on.
*/
void FlexiTimer2::set(unsigned long units, double resolution, void (*f)()) {
float prescaler = 0.0;

if (units == 0)
time_units = 1;
else
time_units = units;

func = f;

#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined (__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
ASSR &= ~(1<<AS2);
TIMSK2 &= ~(1<<OCIE2A);

if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
TCCR2B |= (1<<CS22);
TCCR2B &= ~((1<<CS21) | (1<<CS20));
prescaler = 64.0;
} else if (F_CPU < 1000000UL) { // prescaler set to 8
TCCR2B |= (1<<CS21);
TCCR2B &= ~((1<<CS22) | (1<<CS20));
prescaler = 8.0;
} else { // F_CPU > 16Mhz, prescaler set to 128
TCCR2B |= ((1<<CS22) | (1<<CS20));
TCCR2B &= ~(1<<CS21);
prescaler = 128.0;
}
#elif defined (__AVR_ATmega8__)
TIMSK &= ~(1<<TOIE2);
TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
TIMSK &= ~(1<<OCIE2);
ASSR &= ~(1<<AS2);

if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
TCCR2 |= (1<<CS22);
TCCR2 &= ~((1<<CS21) | (1<<CS20));
prescaler = 64.0;
} else if (F_CPU < 1000000UL) { // prescaler set to 8
TCCR2 |= (1<<CS21);
TCCR2 &= ~((1<<CS22) | (1<<CS20));
prescaler = 8.0;
} else { // F_CPU > 16Mhz, prescaler set to 128
TCCR2 |= ((1<<CS22) && (1<<CS20));
TCCR2 &= ~(1<<CS21);
prescaler = 128.0;
}
#elif defined (__AVR_ATmega128__)
TIMSK &= ~(1<<TOIE2);
TCCR2 &= ~((1<<WGM21) | (1<<WGM20));
TIMSK &= ~(1<<OCIE2);

if ((F_CPU >= 1000000UL) && (F_CPU <= 16000000UL)) { // prescaler set to 64
TCCR2 |= ((1<<CS21) | (1<<CS20));
TCCR2 &= ~(1<<CS22);
prescaler = 64.0;
} else if (F_CPU < 1000000UL) { // prescaler set to 8
TCCR2 |= (1<<CS21);
TCCR2 &= ~((1<<CS22) | (1<<CS20));
prescaler = 8.0;
} else { // F_CPU > 16Mhz, prescaler set to 256
TCCR2 |= (1<<CS22);
TCCR2 &= ~((1<<CS21) | (1<<CS20));
prescaler = 256.0;
}
#elif defined (__AVR_ATmega32U4__)
TCCR4B = 0;
TCCR4A = 0;
TCCR4C = 0;
TCCR4D = 0;
TCCR4E = 0;
if (F_CPU >= 16000000L) {
TCCR4B = (1<<CS43) | (1<<PSR4);
prescaler = 128.0;
} else if (F_CPU >= 8000000L) {
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4);
prescaler = 64.0;
} else if (F_CPU >= 4000000L) {
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<PSR4);
prescaler = 32.0;
} else if (F_CPU >= 2000000L) {
TCCR4B = (1<<CS42) | (1<<CS40) | (1<<PSR4);
prescaler = 16.0;
} else if (F_CPU >= 1000000L) {
TCCR4B = (1<<CS42) | (1<<PSR4);
prescaler = 8.0;
} else if (F_CPU >= 500000L) {
TCCR4B = (1<<CS41) | (1<<CS40) | (1<<PSR4);
prescaler = 4.0;
} else {
TCCR4B = (1<<CS41) | (1<<PSR4);
prescaler = 2.0;
}
tcnt2 = (int)((float)F_CPU * resolution / prescaler) - 1;
OCR4C = tcnt2;
return;
#elif defined(__arm__) && defined(TEENSYDUINO)
// TODO: should this emulate the limitations and numerical
// range bugs from the versions above?
tcnt2 = resolution * 1000000.0;
return;
#else
#error Unsupported CPU type
#endif

tcnt2 = 256 - (int)((float)F_CPU * resolution / prescaler);
}

void FlexiTimer2::start() {
count = 0;
overflowing = 0;
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
TCNT2 = tcnt2;
TIMSK2 |= (1<<TOIE2);
#elif defined (__AVR_ATmega128__)
TCNT2 = tcnt2;
TIMSK |= (1<<TOIE2);
#elif defined (__AVR_ATmega8__)
TCNT2 = tcnt2;
TIMSK |= (1<<TOIE2);
#elif defined (__AVR_ATmega32U4__)
TIFR4 = (1<<TOV4);
TCNT4 = 0;
TIMSK4 = (1<<TOIE4);
#elif defined(__arm__) && defined(TEENSYDUINO)
itimer.begin(FlexiTimer2::_overflow, tcnt2);
#endif
}

void FlexiTimer2::stop() {
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
TIMSK2 &= ~(1<<TOIE2);
#elif defined (__AVR_ATmega128__)
TIMSK &= ~(1<<TOIE2);
#elif defined (__AVR_ATmega8__)
TIMSK &= ~(1<<TOIE2);
#elif defined (__AVR_ATmega32U4__)
TIMSK4 = 0;
#elif defined(__arm__) && defined(TEENSYDUINO)
itimer.end();
#endif
}

void FlexiTimer2::_overflow() {
count += 1;

if (count >= time_units && !overflowing) {
overflowing = 1;
count = count - time_units; // subtract time_uints to catch missed overflows
// set to 0 if you don't want this.
(*func)();
overflowing = 0;
}
}

#if defined (__AVR__)
#if defined (__AVR_ATmega32U4__)
ISR(TIMER4_OVF_vect) {
#else
ISR(TIMER2_OVF_vect) {
#endif
#if defined (__AVR_ATmega168__) || defined (__AVR_ATmega48__) || defined (__AVR_ATmega88__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
TCNT2 = FlexiTimer2::tcnt2;
#elif defined (__AVR_ATmega128__)
TCNT2 = FlexiTimer2::tcnt2;
#elif defined (__AVR_ATmega8__)
TCNT2 = FlexiTimer2::tcnt2;
#elif defined (__AVR_ATmega32U4__)
// not necessary on 32u4's high speed timer4
#endif
FlexiTimer2::_overflow();
}
#endif // AVR

izince
Posts: 1
Joined: Tue Feb 21, 2023 12:23 pm

Re: Port Flexitimer2 for ESP32

Postby izince » Tue Feb 21, 2023 12:26 pm

I used your "flexitimer2.h" library in an Arduino project. It was very useful for my project. Now, in order to obtain data more effectively from this project, I need to use an ESP32 (NodeMCU ESP32S). Would it be very difficult to modify the flexitimer2.h library to use it with ESP32S? Could you please help me with this?

Who is online

Users browsing this forum: No registered users and 63 guests