@@ -22,6 +22,7 @@ namespace TeensyTimerTool
22
22
inline float getMaxPeriod () const override ;
23
23
24
24
inline errorCode setPeriod (float us) override ;
25
+ inline errorCode setNextPeriod (float us) override ;
25
26
inline void setPrescaler (uint32_t psc); // psc 0..7 -> prescaler: 1..128
26
27
27
28
protected:
@@ -30,7 +31,7 @@ namespace TeensyTimerTool
30
31
float pscValue;
31
32
uint32_t pscBits;
32
33
33
- inline float_t microsecondToCounter (const float_t us) const ;
34
+ errorCode us2Ticks (const float us, uint16_t *ticks ) const ;
34
35
inline float_t counterToMicrosecond (const float_t cnt) const ;
35
36
};
36
37
@@ -63,24 +64,17 @@ namespace TeensyTimerTool
63
64
return errorCode::OK;
64
65
}
65
66
66
- errorCode TMRChannel::begin (callback_t cb, float tcnt , bool periodic)
67
+ errorCode TMRChannel::begin (callback_t cb, float period , bool periodic)
67
68
{
68
- const float_t t = microsecondToCounter (tcnt);
69
69
uint16_t reload;
70
- if (t > 0xFFFF )
71
- {
72
- postError (errorCode::periodOverflow);
73
- reload = 0xFFFE ;
74
- } else
75
- {
76
- reload = (uint16_t )t - 1 ;
77
- }
70
+ errorCode status = us2Ticks (period, &reload);
78
71
79
72
regs->CTRL = 0x0000 ;
80
73
regs->LOAD = 0x0000 ;
81
74
regs->COMP1 = reload;
82
75
regs->CMPLD1 = reload;
83
76
regs->CNTR = 0x0000 ;
77
+ regs->CSCTRL = TMR_CSCTRL_CL1 (1 );
84
78
setCallback (cb);
85
79
86
80
if (!periodic)
@@ -90,13 +84,16 @@ namespace TeensyTimerTool
90
84
regs->CTRL = TMR_CTRL_CM (1 ) | TMR_CTRL_PCS (pscBits) | TMR_CTRL_LENGTH;
91
85
92
86
start ();
93
- return t > 0xFFFF ? errorCode::periodOverflow : errorCode::OK ;
87
+ return status ;
94
88
}
95
89
96
- errorCode TMRChannel::trigger (float tcnt ) // quick and dirty, should be optimized
90
+ errorCode TMRChannel::trigger (float us ) // quick and dirty, should be optimized
97
91
{
98
- const float_t t = microsecondToCounter (tcnt);
99
- uint16_t reload = t > 0xFFFF ? 0xFFFF : (uint16_t )t;
92
+ // const float_t t = us2Ticks(tcnt);
93
+ // uint16_t reload = t > 0xFFFF ? 0xFFFF : (uint16_t)t;
94
+
95
+ uint16_t reload;
96
+ errorCode status = us2Ticks (us, &reload);
100
97
101
98
regs->CTRL = 0x0000 ;
102
99
regs->LOAD = 0x0000 ;
@@ -109,7 +106,7 @@ namespace TeensyTimerTool
109
106
110
107
regs->CTRL = TMR_CTRL_CM (1 ) | TMR_CTRL_PCS (pscBits) | TMR_CTRL_ONCE | TMR_CTRL_LENGTH;
111
108
112
- return errorCode::OK ;
109
+ return status ;
113
110
}
114
111
115
112
void TMRChannel::setPrescaler (uint32_t psc) // psc 0..7 -> prescaler: 1..128
@@ -123,10 +120,13 @@ namespace TeensyTimerTool
123
120
return pscValue / 150'000'000 .0f * 0xFFFE ;
124
121
}
125
122
126
- // void TMRChannel::_setNextPeriod(const uint16_t cnt)
127
- // {
128
- // regs->CMPLD1 = cnt;
129
- // }
123
+ errorCode TMRChannel::setNextPeriod (float us)
124
+ {
125
+ uint16_t reload;
126
+ errorCode status = us2Ticks (us, &reload);
127
+ regs->CMPLD1 = reload;
128
+ return status;
129
+ }
130
130
131
131
// errorCode TMRChannel::_setCurrentPeriod(const uint16_t cnt)
132
132
// {
@@ -151,21 +151,33 @@ namespace TeensyTimerTool
151
151
152
152
errorCode TMRChannel::setPeriod (float us)
153
153
{
154
- // const float_t t = microsecondToCounter(us);
155
-
156
- // if (t <= 0xFFFF)
157
- // {
158
- // return _setCurrentPeriod(t);
159
- // } else
160
- // {
161
- // return errorCode::periodOverflow;
162
- // }
163
- return errorCode::notImplemented;
154
+ uint16_t newReload;
155
+ errorCode status = us2Ticks (us, &newReload);
156
+
157
+ regs->CMPLD1 = newReload; // counter will load this value to COMP1 at next trigger
158
+ //
159
+ noInterrupts (); // interrupting this code could lead to wrong cntr settings
160
+ if (regs->CNTR > newReload) // already too late for new period
161
+ regs->CNTR = regs->COMP1 ; // -> force trigger; will also load COMP1 with value from CMPLD1
162
+ else // not too late
163
+ regs->COMP1 = newReload; // -> change current compare value to new one (counter _might_ be > newReload in between.. watch and fix if necessary)
164
+ interrupts ();
165
+
166
+ return status;
164
167
}
165
168
166
- float_t TMRChannel::microsecondToCounter (const float_t us) const
169
+ errorCode TMRChannel::us2Ticks (const float us, uint16_t *ticks ) const
167
170
{
168
- return us * 150 .0f / pscValue;
171
+ constexpr uint16_t maxTicks = 0xFFFE ;
172
+
173
+ float tmpTicks = us * 150 .0f / pscValue;
174
+ if (tmpTicks > maxTicks)
175
+ {
176
+ *ticks = maxTicks;
177
+ return errorCode::periodOverflow;
178
+ }
179
+ *ticks = (uint16_t )tmpTicks;
180
+ return errorCode::OK;
169
181
}
170
182
171
183
float_t TMRChannel::counterToMicrosecond (const float_t cnt) const
0 commit comments