-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.c
154 lines (131 loc) · 4.05 KB
/
common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdint.h>
typedef uint8_t bool;
#include "inc/tm4c123gh6pm.h"
#include "inc/hw_types.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom_map.h"
#include "driverlib/rom.h"
#include "driverlib/timer.h"
#include "common.h"
#include "inc/hw_gpio.h"
#include "driverlib/gpio.h"
// Thread timer variables
static uint8_t nextTimer = 0;
static uint32_t commonTimer[TIMERS] = {0};
static volatile timerCallback timerCb[TIMER_CALLBACKS] = {0};
// Timer helper variables
static volatile uint8_t timerTriggered = 0;
static volatile uint8_t timerLatencyError = 255; // Timer triggered before it was handled (will decrease on error)
// These are left as globals for now
volatile uint8_t waitMutex; // Lock for the exact wait timer
volatile timerCallback waitCb; // Callback for exact waitCb
void delayMicrosec(uint32_t time)
{
// ROM_SysCtlDelay(ROM_SysCtlClockGet()/3000000 * time);
SysCtlDelay(SysCtlClockGet()/3000000 * time);
}
void delayMillisec(uint32_t time)
{
// ROM_SysCtlDelay(ROM_SysCtlClockGet()/3000 * time);
SysCtlDelay(SysCtlClockGet()/3000 * time);
}
void __attribute__ ((interrupt)) timedFunctionsIntHandler(void)
{
uint8_t i;
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
waitMutex = TIMER_LOCK; // Timer stopped
if(waitCb.callback)
(*waitCb.callback)(timerCb[i].data, CALLER_TIMER); // Handle callback
}
void InitTimedFunctions(void)
{
// General timer, meant for one-shot accurate delays
if(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0))
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER0));
}
TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
TimerLoadSet64(TIMER0_BASE, (uint64_t)SysCtlClockGet()); // Default
TimerIntRegister(TIMER0_BASE, TIMER_A, timedFunctionsIntHandler);
TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
// TimerEnable(TIMER0_BASE, TIMER_A);
IntEnable(INT_TIMER0A);
}
// Interrupt for system timer
// This takes about 528 ns to run (not counting the main loop portion)
void __attribute__ ((interrupt)) timerIntHandler(void)
{
// This uses System Tick so the interrupt does not need to be reset
if(timerTriggered && timerLatencyError) timerLatencyError--;
timerTriggered = 1;
// TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
// slowTimerTriggered = 1;
}
void setupTimer(uint32_t timerInterval)
{
// Configure timers for reading sensors
// Generic timer for thread scheduling
// Using systick
SysTickPeriodSet((uint64_t)(SysCtlClockGet() / 1000000) * timerInterval);
SysTickIntRegister(timerIntHandler);
SysTickEnable();
// Second timer with multiple callbacks available
#if 0
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
TimerLoadSet64(TIMER1_BASE, (uint64_t)(SysCtlClockGet() / 1000000) * commonTimerStep);
TimerIntRegister(TIMER1_BASE, TIMER_A, commonTimerIntHandler);
TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
TimerEnable(TIMER1_BASE, TIMER_A);
IntEnable(INT_TIMER1A);
#endif
}
uint32_t *getFreeTimer(void)
{
if(nextTimer >= TIMERS) return 0;
return &commonTimer[nextTimer++];
}
void handleTimers(void)
{
uint8_t i;
if(timerTriggered)
{
timerTriggered = 0;
// Decrease timers
for(i=0; i<TIMERS; i++)
if(commonTimer[i]) commonTimer[i]--;
}
}
// Fast timer interrupt
// Intended to do short time critical sections
// Handler takes about 560 ... 600 ns / timer + time of any handler @ 80 MHz
// 580 ns / 1
// 940 ns / 2
// 1180 ns / 3
// 1420 ns / 4
// 1680 ns / 5
// 2940 ns / 10
// When callback is handled, to turn on/off a I/O and re-init the timer, it takes 2110 ns / 4 timers (1 callback)
void __attribute__ ((interrupt)) commonTimerIntHandler(void)
{
uint8_t i;
TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
// Handle callbacks
for(i=0; i < TIMER_CALLBACKS; i++)
{
if(timerCb[i].timer) {
timerCb[i].timer--;
if(!timerCb[i].timer && timerCb[i].callback) {
// Timer reached zero -> triggered
(*timerCb[i].callback)(timerCb[i].data, CALLER_TIMER);
}
}
}
}
uint32_t getTimerTime(uint8_t timer)
{
if(timer >= TIMERS) return 0;
return commonTimer[timer];
}