Skip to content

Commit 5fc7de9

Browse files
committed
setPeriod / setNextPeriod for the TMR timers
1 parent 89e878d commit 5fc7de9

File tree

2 files changed

+49
-37
lines changed

2 files changed

+49
-37
lines changed

src/TimerModules/GPT/GPTChannel.h

+5-5
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,12 @@ namespace TeensyTimerTool
115115
errorCode GptChannel::setPeriod(float us) // not good, will generate one too long period if called before cnt == oldPeriod
116116
{ // need to redo the timing using free running timer to get setPeriod and setNewPeriod working correctly
117117
uint32_t newPeriod = us2ticks(us);
118-
uint32_t now = regs->CNT;
118+
// uint32_t now = regs->CNT;
119119

120-
if (now > newPeriod)
121-
{
122-
(*pCallback)();
123-
}
120+
// if (now > newPeriod)
121+
// {
122+
// (*pCallback)(); // might generate reentrance issues, not a good idea...
123+
// }
124124

125125
regs->OCR1 = newPeriod;
126126
return errorCode::OK;

src/TimerModules/TMR/TMRChannel.h

+44-32
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace TeensyTimerTool
2222
inline float getMaxPeriod() const override;
2323

2424
inline errorCode setPeriod(float us) override;
25+
inline errorCode setNextPeriod(float us) override;
2526
inline void setPrescaler(uint32_t psc); // psc 0..7 -> prescaler: 1..128
2627

2728
protected:
@@ -30,7 +31,7 @@ namespace TeensyTimerTool
3031
float pscValue;
3132
uint32_t pscBits;
3233

33-
inline float_t microsecondToCounter(const float_t us) const;
34+
errorCode us2Ticks(const float us, uint16_t *ticks) const;
3435
inline float_t counterToMicrosecond(const float_t cnt) const;
3536
};
3637

@@ -63,24 +64,17 @@ namespace TeensyTimerTool
6364
return errorCode::OK;
6465
}
6566

66-
errorCode TMRChannel::begin(callback_t cb, float tcnt, bool periodic)
67+
errorCode TMRChannel::begin(callback_t cb, float period, bool periodic)
6768
{
68-
const float_t t = microsecondToCounter(tcnt);
6969
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);
7871

7972
regs->CTRL = 0x0000;
8073
regs->LOAD = 0x0000;
8174
regs->COMP1 = reload;
8275
regs->CMPLD1 = reload;
8376
regs->CNTR = 0x0000;
77+
regs->CSCTRL = TMR_CSCTRL_CL1(1);
8478
setCallback(cb);
8579

8680
if (!periodic)
@@ -90,13 +84,16 @@ namespace TeensyTimerTool
9084
regs->CTRL = TMR_CTRL_CM(1) | TMR_CTRL_PCS(pscBits) | TMR_CTRL_LENGTH;
9185

9286
start();
93-
return t > 0xFFFF ? errorCode::periodOverflow : errorCode::OK;
87+
return status;
9488
}
9589

96-
errorCode TMRChannel::trigger(float tcnt) // quick and dirty, should be optimized
90+
errorCode TMRChannel::trigger(float us) // quick and dirty, should be optimized
9791
{
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);
10097

10198
regs->CTRL = 0x0000;
10299
regs->LOAD = 0x0000;
@@ -109,7 +106,7 @@ namespace TeensyTimerTool
109106

110107
regs->CTRL = TMR_CTRL_CM(1) | TMR_CTRL_PCS(pscBits) | TMR_CTRL_ONCE | TMR_CTRL_LENGTH;
111108

112-
return errorCode::OK;
109+
return status;
113110
}
114111

115112
void TMRChannel::setPrescaler(uint32_t psc) // psc 0..7 -> prescaler: 1..128
@@ -123,10 +120,13 @@ namespace TeensyTimerTool
123120
return pscValue / 150'000'000.0f * 0xFFFE;
124121
}
125122

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+
}
130130

131131
// errorCode TMRChannel::_setCurrentPeriod(const uint16_t cnt)
132132
// {
@@ -151,21 +151,33 @@ namespace TeensyTimerTool
151151

152152
errorCode TMRChannel::setPeriod(float us)
153153
{
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;
164167
}
165168

166-
float_t TMRChannel::microsecondToCounter(const float_t us) const
169+
errorCode TMRChannel::us2Ticks(const float us, uint16_t *ticks) const
167170
{
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;
169181
}
170182

171183
float_t TMRChannel::counterToMicrosecond(const float_t cnt) const

0 commit comments

Comments
 (0)