ASCII Serial Com
Serial communication library between computers, microcontrollers, FPGAs, etc. Uses only ASCII. Not the most efficient protocol, but meant to be easy to read
Loading...
Searching...
No Matches
millisec_timer.h
Go to the documentation of this file.
1/** @file
2 * \brief Portable millisecond timer
3 *
4 * On microcontrollers, \ref MILLISEC_TIMER_NOW will be declared
5 * and can be setup to increment every millisecond.
6 *
7 * For Cortex-M, put:
8 *
9 * 1) #include <libopencm3/cm3/nvic.h> at the top of your main file
10 *
11 * 2) \ref MILLISEC_TIMER_SYSTICK_IT; outside of any function to
12 * define the systick interrupt
13 *
14 * 3) \ref millisec_timer_systick_setup(); with rcc_ahb_frequency as
15 * its argument,in the setup portion of your main function. It's
16 * probably best to put before other things.
17 *
18 * For AVR, put:
19 *
20 * 1) #include <avr/interrupt.h>
21 * #include <avr/io.h>
22 * #include <util/atomic.h>
23 * at the top of your main file
24 *
25 * 2) \ref MILLISEC_TIMER_AVR_TIMER0_ISR; outside of any function to
26 * define Timer0 ISR.
27 *
28 * 3) \ref millisec_timer_avr_timer0_setup_16MHz(); in the setup portion
29 * of your main function to setup the timer for 16 MHz clock speed.
30 *
31 */
32
33#ifndef MILLISEC_TIMER_H
34#define MILLISEC_TIMER_H
35
36#include <inttypes.h>
37#include <stdbool.h>
38#include <stddef.h>
39#include <stdint.h>
40#ifdef linux
41#include <stdio.h>
42#endif
43#ifdef __ARM_ARCH
44#include <libopencm3/cm3/systick.h>
45#endif
46
47typedef uint32_t millisec_timer_unit_t;
48
49/** \brief portable millisecond timer
50 *
51 * It's designed to be easy to use and handle wraparound properly (which
52 * happens every 49.7 days for uint32_t).
53 *
54 */
55typedef struct __millisec_timer {
56 bool enabled;
57 millisec_timer_unit_t set_time;
58 millisec_timer_unit_t expire_time;
60
61/** \brief Set timer to expire in the future
62 *
63 * Sets and enables timer to expire rel ms in the future.
64 *
65 * This sets the set_time to now and the expire_time to set_time + rel
66 *
67 */
69 const millisec_timer_unit_t now,
70 const millisec_timer_unit_t rel);
71
72/** \brief Check if timer has expired & if so, disable it
73 *
74 * If timer is enabled and it's expired, return true and disable the timer.
75 * If not enabled or the time hasn't expired, return false.
76 *
77 */
79 const millisec_timer_unit_t now);
80
81/** \brief Check if timer has expired & if so, re-enable for the same interval
82 *
83 * If timer is enabled and it's set time has expired:
84 * 1) set the new expiration time to be the old expire time + (old expire time
85 * - old set time) 2) set the new set time to be the old expire time 3) return
86 * true. If not enabled or the time hasn't expired, return false.
87 *
88 */
90 const millisec_timer_unit_t now);
91
92#if defined(__ARM_ARCH) || defined(__AVR)
93#pragma GCC diagnostic ignored "-Wunused-variable"
94#pragma GCC diagnostic push
95/** \brief A counter that increments every millisecond
96 *
97 * This value will increment every millisecond, if everything is setup
98 * correctly.
99 *
100 */
101static uint32_t MILLISEC_TIMER_NOW = 0;
102#pragma GCC diagnostic pop
103#endif
104
105#ifdef __ARM_ARCH
106/** \brief Millisecond timer SysTick interrupt
107 *
108 * Implements an interrupt handler that increments MILLISEC_TIMER_NOW
109 *
110 */
111#define MILLISEC_TIMER_SYSTICK_IT \
112 void sys_tick_handler(void) { MILLISEC_TIMER_NOW++; }
113
114/** \brief Setup the systick timer
115 *
116 * Configures the systick timer to raise the interrupt every millisecond.
117 *
118 */
119void millisec_timer_systick_setup(uint32_t ahb_frequency);
120#endif
121
122#ifdef __AVR
123/** \brief Millisecond timer SysTick interrupt
124 *
125 * Implements an interrupt handler that increments MILLISEC_TIMER_NOW
126 *
127 */
128#define MILLISEC_TIMER_AVR_TIMER0_ISR \
129 ISR(TIMER0_COMPA_vect) { MILLISEC_TIMER_NOW++; }
130
131/** \brief Setup the systick timer
132 *
133 * Configures Timer0 to raise the TIMER0_COMPA interrupt every millisecond.
134 *
135 * It's a good idea to use ATOMIC blocks around MILLISEC_TIMER_NOW access.
136 *
137 */
138#define millisec_timer_avr_timer0_setup_16MHz() \
139 TCCR0B |= 0x3; \
140 TCCR0A |= 2; \
141 OCR0A = 250; \
142 TIMSK0 |= 1 << OCIE0A
143
144#endif
145
146#endif
static uint32_t MILLISEC_TIMER_NOW
A counter that increments every millisecond.
void millisec_timer_systick_setup(uint32_t ahb_frequency)
Setup the systick timer.
void millisec_timer_set_rel(millisec_timer *timer, const millisec_timer_unit_t now, const millisec_timer_unit_t rel)
Set timer to expire in the future.
struct __millisec_timer millisec_timer
portable millisecond timer
bool millisec_timer_is_expired_repeat(millisec_timer *timer, const millisec_timer_unit_t now)
Check if timer has expired & if so, re-enable for the same interval.
bool millisec_timer_is_expired(millisec_timer *timer, const millisec_timer_unit_t now)
Check if timer has expired & if so, disable it.
portable millisecond timer