GY-63_MS5611/libraries/PulsePattern/PulsePattern.cpp

166 lines
3.5 KiB
C++
Raw Normal View History

2013-09-30 12:29:52 -04:00
//
2013-09-30 12:32:34 -04:00
// FILE: PulsePattern.cpp
2017-07-16 10:01:09 -04:00
// AUTHOR: Rob dot Tillaart at gmail dot com
2022-03-11 04:36:49 -05:00
// VERSION: 0.1.5
2020-11-27 05:28:57 -05:00
// DATE: 2012-11-23
// PURPOSE: Arduino Library to generate repeating pulse patterns
2013-09-30 12:29:52 -04:00
//
2021-01-29 06:31:58 -05:00
// HISTORY:
// 0.0.1 2012-11-23 initial version
// 0.0.2 2012-11-23 adapted a static PPO
// 0.0.3 2012-12-27 renamed to PulsePattern
// 0.0.4 2012-12-27 code stable(?) enough to publish
2021-12-24 09:10:06 -05:00
// 0.0.5 2012-12-27 code clean up + comment
2021-01-29 06:31:58 -05:00
// 0.0.6 2015-04-18 completed the state machine
// 0.0.7 2017-07-16 refactor & review
// 0.0.8 2018-12-13 refactor -> remove some warnings
// 0.1.0 2020-06-19 #pragma once; remove pre 1.0 support; refactor
// 0.1.1 2020-07-04 add continue function, fix spaces.
// 0.1.2 2020-08-07 speed up toggle pin + get/setFactor()
2021-12-24 09:10:06 -05:00
// 0.1.3 2021-01-06 Arduino-CI (no unit test)
// 0.1.4 2021-12-24 update library.json, license, minor edits
2022-03-11 04:36:49 -05:00
// 0.1.5 2022-03-10 add times to start(), 0 = continuous mode
2013-09-30 12:29:52 -04:00
2013-09-30 12:32:34 -04:00
#include "PulsePattern.h"
2013-09-30 12:29:52 -04:00
2013-09-30 12:38:54 -04:00
// Predefined generator (singleton)
PulsePattern PPGenerator;
2022-03-11 04:36:49 -05:00
ISR(TIMER1_COMPA_vect)
2013-09-30 12:29:52 -04:00
{
2013-09-30 12:38:54 -04:00
PPGenerator.worker();
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2013-09-30 12:32:34 -04:00
PulsePattern::PulsePattern()
2013-09-30 12:29:52 -04:00
{
2017-07-16 10:01:09 -04:00
_size = 0;
_state = NOTINIT;
_ar = NULL;
_cnt = 0;
_level = LOW;
_prescaler = 0;
_pin = 0;
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2020-11-27 05:28:57 -05:00
void PulsePattern::init(const uint8_t pin, const uint16_t * ar, const uint8_t size,
const uint8_t level, const uint8_t prescaler)
2017-07-16 10:01:09 -04:00
{
_pin = pin;
pinMode(_pin, OUTPUT);
stop();
2020-11-27 05:28:57 -05:00
_ar = (uint16_t *) ar;
2017-07-16 10:01:09 -04:00
_size = size;
2020-11-27 05:28:57 -05:00
_level = level ? LOW : HIGH;
2017-07-16 10:01:09 -04:00
_prescaler = constrain(prescaler, PRESCALE_1, PRESCALE_1024);
_cnt = 0;
2017-07-16 10:01:09 -04:00
digitalWrite(_pin, _level);
_state = STOPPED;
2020-11-27 05:28:57 -05:00
// fast low level AVR ports
uint8_t _pinport = digitalPinToPort(_pin);
_pinout = portOutputRegister(_pinport);
_pinbit = digitalPinToBitMask(_pin);
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2022-03-11 04:36:49 -05:00
void PulsePattern::start(uint32_t times)
2013-09-30 12:29:52 -04:00
{
2017-07-16 10:01:09 -04:00
if (_state == RUNNING) return; // no restart
2022-03-11 04:36:49 -05:00
_cnt = 0; // start from begin
_times = times;
2020-11-27 05:28:57 -05:00
cont();
}
2021-12-24 09:10:06 -05:00
2020-11-27 05:28:57 -05:00
void PulsePattern::cont()
{
if (_state == RUNNING) return; // no continue
if (_size == 0) return; // no pattern
2017-07-16 10:01:09 -04:00
setTimer(1); // start asap
_state = RUNNING;
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2013-09-30 12:32:34 -04:00
void PulsePattern::stop()
2013-09-30 12:29:52 -04:00
{
2017-07-16 10:01:09 -04:00
stopTimer();
_state = STOPPED;
_level = LOW;
digitalWrite(_pin, _level);
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2013-09-30 12:32:34 -04:00
void PulsePattern::worker()
2013-09-30 12:29:52 -04:00
{
2017-07-16 10:01:09 -04:00
if (_state != RUNNING) return;
// set next period & flip signal
_level = !_level;
2020-11-27 05:28:57 -05:00
// digitalWrite(_pin, _level);
// direct port much faster
if (_level == 0) *_pinout &= ~_pinbit;
else *_pinout |= _pinbit;
if (_factor != 4096)
{
OCR1A = _ar[_cnt] * _factor * (F_CPU/1000000UL) / 4096;
}
else
{
OCR1A = _ar[_cnt] * (F_CPU/1000000UL);
}
2017-07-16 10:01:09 -04:00
_cnt++;
2022-03-11 04:36:49 -05:00
if (_cnt >= _size)
{
_cnt = 0; // reset pattern
switch(_times)
{
case PP_CONTINUOUS:
break;
case 1:
_times--;
case 0:
stop();
break;
default:
_times--;
break;
}
}
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2013-09-30 12:29:52 -04:00
// TIMER code based upon - http://www.gammon.com.au/forum/?id=11504
2013-09-30 12:32:34 -04:00
void PulsePattern::stopTimer()
2013-09-30 12:29:52 -04:00
{
2017-07-16 10:01:09 -04:00
TCCR1A = 0; // reset timer 1
TCCR1B = 0;
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2017-07-16 10:01:09 -04:00
void PulsePattern::setTimer(const uint16_t cc) const
2013-09-30 12:29:52 -04:00
{
2020-11-27 05:28:57 -05:00
TCCR1A = 0; // stop timer first
2017-07-16 10:01:09 -04:00
TCCR1B = 0;
2020-11-27 05:28:57 -05:00
TCNT1 = 0; // reset counter
OCR1A = cc * 16; // compare A register value;
2017-07-16 10:01:09 -04:00
// * 16 makes max period 4095
// min period 12?
// 4: CTC mode, top = OCR1A
2020-11-27 05:28:57 -05:00
TCCR1A = _BV (COM1A1); // clear on compare
2017-07-16 10:01:09 -04:00
TCCR1B = _BV (WGM12) | _prescaler;
TIFR1 |= _BV (OCF1A); // clear interrupt flag
TIMSK1 = _BV (OCIE1A); // interrupt on Compare A Match
2013-09-30 12:29:52 -04:00
}
2021-12-24 09:10:06 -05:00
2020-11-27 05:28:57 -05:00
// -- END OF FILE --
2021-12-24 09:10:06 -05:00