FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
tone_player.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
21#ifndef TONE_PLAYER_HH
22#define TONE_PLAYER_HH
23
24#include "../eeprom.h"
25#include "../flash.h"
26#include "tones.h"
27
29{
30 // Forward declaration
31 template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY> class AbstractTonePlayer;
32
39 namespace SpecialTone
40 {
44 static constexpr const Tone END = Tone::USER0;
45
51 static constexpr const Tone REPEAT_START = Tone::USER1;
52
59 static constexpr const Tone REPEAT_END = Tone::USER2;
60
71 static constexpr const Tone TIE = Tone::USER3;
72
85 static constexpr const Tone SLUR = TIE;
86 }
87
103 enum class Duration : uint8_t
104 {
105 // Common names for notes durations
107 WHOLE = 32,
109 HALF = 16,
111 QUARTER = 8,
113 EIGHTH = 4,
115 SIXTEENTH = 2,
116
117 // Synonyms for some notes durations
121 MINIM = HALF,
125 QUAVER = EIGHTH,
128 };
129
133 static constexpr Duration dotted(Duration d)
134 {
135 return Duration(uint8_t(d) + uint8_t(d) / 2);
136 }
137
141 static constexpr Duration triplet(Duration d)
142 {
143 return Duration(uint8_t(d) * 2 / 3);
144 }
145
162 {
163 public:
165 TonePlay(const TonePlay&) = default;
166 TonePlay& operator=(const TonePlay&) = default;
168
176 TonePlay() = default;
177
186 constexpr TonePlay(Tone tone, Duration duration) : tone_{tone}, duration_{duration} {}
187
196 constexpr TonePlay(Tone tone, uint8_t value = 0) : tone_{tone}, repeats_{value} {}
197
198 private:
199 Duration duration() const
200 {
201 return duration_;
202 }
203 bool is_tone() const
204 {
205 return tone_ > Tone::SILENCE;
206 }
207 bool is_pause() const
208 {
209 return tone_ == Tone::SILENCE;
210 }
211 bool is_end() const
212 {
213 return tone_ == SpecialTone::END;
214 }
215 bool is_repeat_start() const
216 {
217 return tone_ == SpecialTone::REPEAT_START;
218 }
219 bool is_repeat_end() const
220 {
221 return tone_ == SpecialTone::REPEAT_END;
222 }
223 uint8_t repeat_count() const
224 {
225 return repeats_;
226 }
227 bool is_tie() const
228 {
229 return tone_ == SpecialTone::TIE;
230 }
231 uint8_t num_ties() const
232 {
233 return ties_;
234 }
235
236 template<board::Timer NTIMER, board::PWMPin OUTPUT>
237 void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator) const
238 {
239 generator.start_tone(tone_);
240 }
241
242 Tone tone_;
243 union
244 {
245 Duration duration_;
246 uint8_t repeats_;
247 uint8_t ties_;
248 };
249
250 template<board::Timer, board::PWMPin, typename> friend class AbstractTonePlayer;
251 };
252
268 template<board::Timer NTIMER, board::PWMPin OUTPUT> class QTonePlay
269 {
270 public:
272 QTonePlay(const QTonePlay&) = default;
273 QTonePlay& operator=(const QTonePlay&) = default;
275
283 QTonePlay() = default;
284
293 constexpr QTonePlay(Tone tone, Duration duration)
294 : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, duration_{duration} {}
295
304 constexpr QTonePlay(Tone tone, uint8_t value = 0)
305 : flags_{flags(tone)}, prescaler_{prescaler(tone)}, counter_{counter(tone)}, repeats_{value} {}
306
307 private:
308 using CALC = timer::Calculator<NTIMER>;
309 using TIMER = timer::Timer<NTIMER>;
310 using PRESCALER = typename TIMER::PRESCALER;
311 using COUNTER = typename TIMER::TYPE;
312
313 Duration duration() const
314 {
315 return duration_;
316 }
317 bool is_tone() const
318 {
319 return flags_ == TONE;
320 }
321 bool is_pause() const
322 {
323 return flags_ == NONE;
324 }
325 bool is_end() const
326 {
327 return flags_ == END;
328 }
329 bool is_repeat_start() const
330 {
331 return flags_ == REPEAT_START;
332 }
333 bool is_repeat_end() const
334 {
335 return flags_ == REPEAT_END;
336 }
337 uint8_t repeat_count() const
338 {
339 return repeats_;
340 }
341 bool is_tie() const
342 {
343 return flags_ == TIE;
344 }
345 uint8_t num_ties() const
346 {
347 return ties_;
348 }
349
350 void generate_tone(ToneGenerator<NTIMER, OUTPUT>& generator) const
351 {
352 generator.start_tone(prescaler_, counter_);
353 }
354
355 // Flags meaning
356 static constexpr uint8_t TONE = 0x00;
357 static constexpr uint8_t NONE = 0x01;
358 static constexpr uint8_t END = 0x02;
359 static constexpr uint8_t REPEAT_START = 0x04;
360 static constexpr uint8_t REPEAT_END = 0x08;
361 static constexpr uint8_t TIE = 0x10;
362
363 uint8_t flags_ = END;
364 PRESCALER prescaler_;
365 COUNTER counter_;
366 union
367 {
368 Duration duration_;
369 uint8_t repeats_;
370 uint8_t ties_;
371 };
372
373 static constexpr uint32_t period(Tone tone)
374 {
375 return ONE_SECOND / 2 / uint16_t(tone);
376 }
377 static constexpr PRESCALER prescaler(Tone tone)
378 {
379 return (tone > Tone::SILENCE ? CALC::CTC_prescaler(period(tone)) : PRESCALER::NO_PRESCALING);
380 }
381 static constexpr COUNTER counter(Tone tone)
382 {
383 return (tone > Tone::SILENCE ? CALC::CTC_counter(prescaler(tone), period(tone)) : 0);
384 }
385 static constexpr uint8_t flags(Tone tone)
386 {
387 if (tone == Tone::SILENCE) return NONE;
388 if (tone == SpecialTone::END) return END;
389 if (tone == SpecialTone::REPEAT_START) return REPEAT_START;
390 if (tone == SpecialTone::REPEAT_END) return REPEAT_END;
391 if (tone == SpecialTone::TIE) return TIE;
392 return TONE;
393 }
394
395 friend class AbstractTonePlayer<NTIMER, OUTPUT, QTonePlay<NTIMER, OUTPUT>>;
396 };
397
404 class Beat
405 {
406 public:
408 explicit constexpr Beat(uint8_t bpm) : duration_{calculate_min_duration(bpm)} {}
409
410 constexpr uint16_t duration() const
411 {
412 return duration_;
413 }
415
416 private:
417 static constexpr uint16_t calculate_min_duration(uint8_t bpm)
418 {
419 // bpm defines the duration of a quarter note (in 4/4 mode)
420 // We want the minimum duration allowed (for a 32nd note, since we allow dotted sixteenth)
421 return (60U * 1000U / 8U) / bpm;
422 }
423
424 uint16_t duration_;
425 };
426
463 template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
465 {
466 protected:
468 AbstractTonePlayer(const AbstractTonePlayer&) = delete;
469 AbstractTonePlayer& operator=(const AbstractTonePlayer&) = delete;
471
473 using TONE_PLAY = TONEPLAY;
476
482 explicit AbstractTonePlayer(GENERATOR& tone_generator) : generator_{tone_generator} {}
483
490 void set_min_duration(uint16_t min_duration)
491 {
492 t32_duration_ms_ = min_duration;
493 }
494
499 uint16_t get_min_duration() const
500 {
501 return t32_duration_ms_;
502 }
503
509 void prepare_sram(const TONE_PLAY* melody)
510 {
511 prepare_(melody, load_sram);
512 }
513
519 void prepare_eeprom(const TONE_PLAY* melody)
520 {
521 prepare_(melody, load_eeprom);
522 }
523
529 void prepare_flash(const TONE_PLAY* melody)
530 {
531 prepare_(melody, load_flash);
532 }
533
545 {
546 return start_next_();
547 }
548
559 {
560 return stop_current_();
561 }
562
566 bool is_finished() const
567 {
568 return (loader_ == nullptr);
569 }
570
571 private:
572 static constexpr const uint16_t INTERTONE_DELAY_MS = 20;
573
574 using LOAD_TONE = const TONE_PLAY* (*) (const TONE_PLAY* address, TONE_PLAY& holder);
575
576 void prepare_(const TONE_PLAY* melody, LOAD_TONE load_tone)
577 {
578 loader_ = load_tone;
579 current_play_ = melody;
580 repeat_play_ = nullptr;
581 repeat_times_ = 0;
582 tie_notes_ = 0;
583 }
584
585 void reset_()
586 {
587 loader_ = nullptr;
588 current_play_ = nullptr;
589 repeat_play_ = nullptr;
590 repeat_times_ = 0;
591 tie_notes_ = 0;
592 }
593
594 uint16_t start_next_()
595 {
596 if (loader_ == nullptr) return 0;
597
598 TONE_PLAY holder;
599 const TONE_PLAY* current = loader_(current_play_, holder);
600 if (current->is_end())
601 {
602 reset_();
603 return 0;
604 }
605 uint16_t delay = 0;
606 no_delay_ = true;
607 if (current->is_repeat_start())
608 {
609 repeat_play_ = current_play_;
610 repeat_times_ = -1;
611 }
612 else if (current->is_repeat_end())
613 {
614 if (repeat_play_)
615 {
616 if (repeat_times_ == -1) repeat_times_ = current->repeat_count();
617 if (repeat_times_--)
618 current_play_ = repeat_play_;
619 else
620 repeat_play_ = nullptr;
621 }
622 }
623 else if (current->is_tie())
624 {
625 tie_notes_ = current->num_ties();
626 }
627 else
628 {
629 if (current->is_tone()) current->generate_tone(generator_);
630 if (tie_notes_)
631 --tie_notes_;
632 else
633 no_delay_ = false;
634 delay = duration(current->duration());
635 }
636 ++current_play_;
637 return delay;
638 }
639
640 uint16_t stop_current_()
641 {
642 if (no_delay_)
643 return 0;
644 generator_.stop_tone();
645 return INTERTONE_DELAY_MS;
646 }
647
648 uint16_t duration(Duration d) const
649 {
650 return uint8_t(d) * t32_duration_ms_;
651 }
652
653 static const TONE_PLAY* load_sram(const TONE_PLAY* address, TONE_PLAY& holder UNUSED)
654 {
655 return address;
656 }
657 static const TONE_PLAY* load_eeprom(const TONE_PLAY* address, TONE_PLAY& holder)
658 {
659 eeprom::EEPROM::read(address, holder);
660 return &holder;
661 }
662 static const TONE_PLAY* load_flash(const TONE_PLAY* address, TONE_PLAY& holder)
663 {
664 flash::read_flash(address, holder);
665 return &holder;
666 }
667
668 GENERATOR& generator_;
669 LOAD_TONE loader_ = nullptr;
670 uint16_t t32_duration_ms_ = 0U;
671 const TONE_PLAY* current_play_ = nullptr;
672 const TONE_PLAY* repeat_play_ = nullptr;
673 int8_t repeat_times_ = 0;
674 uint8_t tie_notes_ = 0;
675 bool no_delay_ = false;
676 };
677
711 template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
712 class TonePlayer : public AbstractTonePlayer<NTIMER, OUTPUT, TONEPLAY>
713 {
715
716 public:
718 using GENERATOR = typename BASE::GENERATOR;
720 using TONE_PLAY = typename BASE::TONE_PLAY;
721
727 explicit TonePlayer(GENERATOR& tone_generator) : BASE{tone_generator} {}
728
741 void play_sram(const TONE_PLAY* melody, const Beat& beat)
742 {
743 this->set_min_duration(beat.duration());
744 this->prepare_sram(melody);
745 play_();
746 }
747
760 void play_eeprom(const TONE_PLAY* melody, const Beat& beat)
761 {
762 this->set_min_duration(beat.duration());
763 this->prepare_eeprom(melody);
764 play_();
765 }
766
779 void play_flash(const TONE_PLAY* melody, const Beat& beat)
780 {
781 this->set_min_duration(beat.duration());
782 this->prepare_flash(melody);
783 play_();
784 }
785
790 void stop()
791 {
792 stop_ = true;
793 }
794
798 bool is_playing() const
799 {
800 return !stop_;
801 }
802
803 private:
804 void play_()
805 {
806 stop_ = false;
807 while (!stop_)
808 {
809 uint16_t delay = this->start_next_note();
810 if (delay) time::delay_ms(delay);
811 delay = this->stop_current_note();
812 if (delay) time::delay_ms(delay);
813 if (this->is_finished())
814 stop_ = true;
815 }
816 }
817
818 volatile bool stop_ = true;
819 };
820
855 template<board::Timer NTIMER, board::PWMPin OUTPUT, typename TONEPLAY = QTonePlay<NTIMER, OUTPUT>>
856 class AsyncTonePlayer : public AbstractTonePlayer<NTIMER, OUTPUT, TONEPLAY>
857 {
860
861 public:
863 using GENERATOR = typename BASE::GENERATOR;
865 using TONE_PLAY = typename BASE::TONE_PLAY;
866
872 explicit AsyncTonePlayer(GENERATOR& tone_generator) : BASE{tone_generator} {}
873
884 uint16_t get_min_duration() const
885 {
886 return BASE::get_min_duration();
887 }
888
903 void play_sram(const TONE_PLAY* melody, const Beat& beat)
904 {
905 status_ = Status::NOT_STARTED;
906 this->set_min_duration(beat.duration());
907 this->prepare_sram(melody);
908 next_time_ = 0;
909 status_ = Status::STARTED;
910 }
911
926 void play_eeprom(const TONE_PLAY* melody, const Beat& beat)
927 {
928 status_ = Status::NOT_STARTED;
929 this->set_min_duration(beat.duration());
930 this->prepare_eeprom(melody);
931 next_time_ = 0;
932 status_ = Status::STARTED;
933 }
934
949 void play_flash(const TONE_PLAY* melody, const Beat& beat)
950 {
951 status_ = Status::NOT_STARTED;
952 this->set_min_duration(beat.duration());
953 this->prepare_flash(melody);
954 next_time_ = 0;
955 status_ = Status::STARTED;
956 }
957
962 void stop()
963 {
964 status_ = Status::NOT_STARTED;
965 this->stop_current_note();
966 }
967
971 bool is_playing() const
972 {
973 return status_ != Status::NOT_STARTED;
974 }
975
986 void update(uint32_t rtt_millis)
987 {
988 if ((status_ != Status::NOT_STARTED) && (rtt_millis >= next_time_))
989 {
990 uint16_t delay;
991 Status next;
992 if (status_ == Status::PLAYING_NOTE)
993 {
994 delay = this->stop_current_note();
995 next = Status::PLAYING_INTERNOTE;
996 }
997 else
998 {
999 delay = this->start_next_note();
1000 next = Status::PLAYING_NOTE;
1001 }
1002
1003 if (this->is_finished())
1004 status_ = Status::NOT_STARTED;
1005 else
1006 {
1007 next_time_ = rtt_millis + delay;
1008 status_ = next;
1009 }
1010 }
1011 }
1012
1013 private:
1014 enum class Status : uint8_t
1015 {
1016 NOT_STARTED = 0,
1017 STARTED,
1018 PLAYING_NOTE,
1019 PLAYING_INTERNOTE
1020 };
1021
1022 Status status_ = Status::NOT_STARTED;
1023 uint32_t next_time_ = 0UL;
1024 };
1025}
1026
1027#endif /* TONE_PLAYER_HH */
This low-level API defines an abstract player of melodies (defined as a sequence of tones and duratio...
Definition: tone_player.h:465
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:499
void set_min_duration(uint16_t min_duration)
Set the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:490
void prepare_eeprom(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in EEPROM.
Definition: tone_player.h:519
ToneGenerator< NTIMER, OUTPUT > GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:475
uint16_t stop_current_note()
Ask this player to stop playing the current note of the melody.
Definition: tone_player.h:558
uint16_t start_next_note()
Ask this player to start playing the next note of the melody.
Definition: tone_player.h:544
TONEPLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:473
void prepare_sram(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in SRAM.
Definition: tone_player.h:509
AbstractTonePlayer(GENERATOR &tone_generator)
Create a new tone player, based on an existing ToneGenerator.
Definition: tone_player.h:482
bool is_finished() const
Indicate if the currently played melody is finished.
Definition: tone_player.h:566
void prepare_flash(const TONE_PLAY *melody)
Prepare playing of melody, which should be stored in Flash.
Definition: tone_player.h:529
This API defines a player of melodies, defined as a sequence of tones and durations.
Definition: tone_player.h:857
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:863
void update(uint32_t rtt_millis)
Ask this player to update current play if needed, based on current time (as returned by an timer::RTT...
Definition: tone_player.h:986
uint16_t get_min_duration() const
Get the duration, in milliseconds, of a 32nd note.
Definition: tone_player.h:884
void play_eeprom(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
Definition: tone_player.h:926
void play_sram(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
Definition: tone_player.h:903
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:865
bool is_playing() const
Tell if a melody is currently playing.
Definition: tone_player.h:971
void stop()
Stop playing current melody (if any).
Definition: tone_player.h:962
AsyncTonePlayer(GENERATOR &tone_generator)
Create a new asynchronous tone player, based on an existing ToneGenerator.
Definition: tone_player.h:872
void play_flash(const TONE_PLAY *melody, const Beat &beat)
Start playing a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
Definition: tone_player.h:949
This embeds minimum duration (duration of a 32nd note), in milliseconds, for a given tempo (beats per...
Definition: tone_player.h:405
An optimized surrogate to TonePlay structure.
Definition: tone_player.h:269
constexpr QTonePlay(Tone tone, uint8_t value=0)
Construct a "special" optimized tone play with the provided value.
Definition: tone_player.h:304
constexpr QTonePlay(Tone tone, Duration duration)
Construct an optimized tone play for the provided tone and duration.
Definition: tone_player.h:293
QTonePlay()=default
Default constructor, used only to declare an uninitialized QTonePlay variable.
API class for tone generation to a buzzer (or better an amplifier) connected to pin OUTPUT.
Definition: tones.h:183
void stop_tone()
Stop the tone being currently generated to the connected buzzer.
Definition: tones.h:242
This struct is the unit data manipulated by TonePlayer: it describes one Tone along with its duration...
Definition: tone_player.h:162
TonePlay()=default
Default constructor, used only to declare an uninitialized TonePlay variable.
constexpr TonePlay(Tone tone, Duration duration)
Construct a tone play with the provided tone and duration.
Definition: tone_player.h:186
constexpr TonePlay(Tone tone, uint8_t value=0)
Construct a "special" tone play with the provided value.
Definition: tone_player.h:196
This API defines a player of melodies, defined as a sequence of tones and durations.
Definition: tone_player.h:713
typename BASE::TONE_PLAY TONE_PLAY
The type that holds unit of information of a melody.
Definition: tone_player.h:720
void play_flash(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in Flash.
Definition: tone_player.h:779
void stop()
Stop playing current melody (if any).
Definition: tone_player.h:790
TonePlayer(GENERATOR &tone_generator)
Create a new synchronous tone player, based on an existing ToneGenerator.
Definition: tone_player.h:727
bool is_playing() const
Tell if a melody is currently playing.
Definition: tone_player.h:798
void play_sram(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in SRAM.
Definition: tone_player.h:741
void play_eeprom(const TONE_PLAY *melody, const Beat &beat)
Play a melody, defined by a sequence of TONE_PLAYs, stored in EEPROM.
Definition: tone_player.h:760
typename BASE::GENERATOR GENERATOR
The type of ToneGenerator to use as constructor's argument.
Definition: tone_player.h:718
static bool read(const T *address, T &value)
Read value of type T stored in EEPROM at address.
Definition: eeprom.h:149
General API to handle an AVR timer.
Definition: timer.h:705
typename TRAIT::TYPE TYPE
The type of this timer's counter (either uint8_t or uint16_t).
Definition: timer.h:725
typename PRESCALERS_TRAIT::TYPE PRESCALER
The enum type listing all available precaler values for this timer.
Definition: timer.h:735
#define UNUSED
Specific GCC attribute to declare an argument or variable unused, so that the compiler does not emit ...
Definition: defines.h:45
@ NONE
No interrupt will be generated by the Anolog Comparator.
static constexpr const Tone SLUR
This special tone marks the following notes to be slurred together, ie no intertone delay shall occur...
Definition: tone_player.h:85
static constexpr const Tone REPEAT_END
This special tone marks the end of a repeating sequence (started with REPEAT_START).
Definition: tone_player.h:59
static constexpr const Tone END
This special tone marks the end of a melody (as a sequence of Tones).
Definition: tone_player.h:44
static constexpr const Tone REPEAT_START
This special tone marks the beginning of sequence that shall be repeated later.
Definition: tone_player.h:51
static constexpr const Tone TIE
This special tone marks the following notes to be tied together, ie their durations are added with no...
Definition: tone_player.h:71
Defines API for audio tones (square waves) generation and simple melodies playing.
Definition: tone_player.h:29
static constexpr Duration dotted(Duration d)
Transforms a note duration to its dotted value (1.5 times the given duration).
Definition: tone_player.h:133
static constexpr Duration triplet(Duration d)
Transforms a note duration to allow it to use in a triplet.
Definition: tone_player.h:141
Duration
Possible duration of a note, following music theory.
Definition: tone_player.h:104
@ QUARTER
Duration of a quarter note; this is actually the duration of one beat.
@ SEMI_QUAVER
Other common name for a sixteenth note.
@ SIXTEENTH
Duration of a sixteenth note; a quarter the duration of a quarter!
@ CROTCHET
Other common name for a quarter note.
@ HALF
Duration of a half note; 2 times the duration of a quarter.
@ SEMI_BREVE
Other common name for a whole note.
@ WHOLE
Duration of a whole note; 4 times the duration of a quarter.
@ EIGHTH
Duration of an eighth note; half the duration of a quarter.
@ QUAVER
Other common name for an eighth note.
@ MINIM
Other common name for a half note.
Tone
This enum defines all possible audio tones that can be generated.
Definition: tones.h:57
T * read_flash(uint16_t address, T *buffer, uint8_t size)
Read flash memory content at given address into buffer.
Definition: flash.h:50
@ OUTPUT
Notification is dispatched whenever the Future output buffer gets filled, even partly.
void delay_ms(uint16_t ms) INLINE
Delay program execution for the given amount of milliseconds.
Definition: time.h:346
DELAY_PTR delay
Delay program execution for the given amount of milliseconds.
Definition: time.cpp:19
Defines a set of calculation methods for the given NTIMER_ The behavior of these methods is specific ...
Definition: timer.h:302
static constexpr TYPE CTC_counter(PRESCALER prescaler, uint32_t us)
Computes the value of counter to use for this timer, in TimerMode::CTC mode, with prescaler,...
Definition: timer.h:423
static constexpr PRESCALER CTC_prescaler(uint32_t us)
Computes the ideal prescaler value to use for this timer, in TimerMode::CTC mode, in order to be able...
Definition: timer.h:390
API to handle tones (simple square waves) generation to a buzzer.