@@ -119,16 +119,8 @@ int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t
119
119
}
120
120
Waveform * wave = & waveform [pin ];
121
121
// Adjust to shave off some of the IRQ time, approximately
122
- uint32_t delta = 0 ;
123
- #if F_CPU == 80000000
124
- if (timeHighUS > 2 ) {
125
- delta = MicrosecondsToCycles (1 ) + MicrosecondsToCycles (2 )/3 ;
126
- }
127
- #else // 160000000
128
- delta = MicrosecondsToCycles (1 ) >> 1 ; // 0.5 us off each edge
129
- #endif
130
- wave -> nextTimeHighCycles = MicrosecondsToCycles (timeHighUS ) - delta ;
131
- wave -> nextTimeLowCycles = MicrosecondsToCycles (timeLowUS ) - delta ;
122
+ wave -> nextTimeHighCycles = MicrosecondsToCycles (timeHighUS );
123
+ wave -> nextTimeLowCycles = MicrosecondsToCycles (timeLowUS );
132
124
wave -> expiryCycle = runTimeUS ? GetCycleCount () + MicrosecondsToCycles (runTimeUS ) : 0 ;
133
125
if (runTimeUS && !wave -> expiryCycle ) {
134
126
wave -> expiryCycle = 1 ; // expiryCycle==0 means no timeout, so avoid setting it
@@ -142,7 +134,7 @@ int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t
142
134
if (!timerRunning ) {
143
135
initTimer ();
144
136
}
145
- timer1_write (MicrosecondsToCycles (1 )); // Cause an interrupt post-haste
137
+ timer1_write (MicrosecondsToCycles (10 )); // Cause an interrupt post-haste
146
138
while (waveformToEnable ) {
147
139
delay (0 ); // Wait for waveform to update
148
140
}
@@ -159,7 +151,7 @@ int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t
159
151
160
152
static inline ICACHE_RAM_ATTR uint32_t GetCycleCountIRQ () {
161
153
uint32_t ccount ;
162
- __asm__ __volatile__("esync; rsr %0,ccount" :"=a" (ccount ));
154
+ __asm__ __volatile__("rsr %0,ccount" :"=a" (ccount ));
163
155
return ccount ;
164
156
}
165
157
@@ -183,7 +175,10 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
183
175
return false; //It's not running, nothing to do here
184
176
}
185
177
waveformToDisable |= mask ;
186
- timer1_write (MicrosecondsToCycles (1 ));
178
+ // Ensure tiomely service....
179
+ if (T1L > MicrosecondsToCycles (10 )) {
180
+ timer1_write (MicrosecondsToCycles (10 ));
181
+ }
187
182
while (waveformToDisable ) {
188
183
delay (1 ); // Wait for IRQ to update
189
184
}
@@ -194,25 +189,32 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
194
189
}
195
190
196
191
#if F_CPU == 80000000
197
- #define MINCYCLE MicrosecondsToCycles(6)
198
- #define DELTAIRQ MicrosecondsToCycles(5)
192
+ #define DELTAIRQ (MicrosecondsToCycles(3))
199
193
#else
200
- #define MINCYCLE MicrosecondsToCycles(4)
201
- #define DELTAIRQ (MicrosecondsToCycles(2) + MicrosecondsToCycles(3)/4)
194
+ #define DELTAIRQ (MicrosecondsToCycles(2))
202
195
#endif
203
196
204
- static ICACHE_RAM_ATTR void timer1Interrupt () {
205
- uint32_t nextEventCycles ;
197
+ static int startPin = 0 ;
198
+ static int endPin = 0 ;
206
199
207
- // Handle enable/disable requests from main app.
208
- waveformEnabled = (waveformEnabled & ~waveformToDisable ) | waveformToEnable ; // Set the requested waveforms on/off
209
- waveformState &= ~waveformToEnable ; // And clear the state of any just started
210
- waveformToEnable = 0 ;
211
- waveformToDisable = 0 ;
200
+ static ICACHE_RAM_ATTR void timer1Interrupt () {
201
+ uint32_t nextEventCycles = MicrosecondsToCycles (MAXIRQUS );
202
+ uint32_t timeoutCycle = GetCycleCountIRQ () + MicrosecondsToCycles (14 );
203
+
204
+ if (waveformToEnable || waveformToDisable ) {
205
+ // Handle enable/disable requests from main app.
206
+ waveformEnabled = (waveformEnabled & ~waveformToDisable ) | waveformToEnable ; // Set the requested waveforms on/off
207
+ waveformState &= ~waveformToEnable ; // And clear the state of any just started
208
+ waveformToEnable = 0 ;
209
+ waveformToDisable = 0 ;
210
+ startPin = __builtin_ffs (waveformEnabled ) - 1 ;
211
+ endPin = 32 - __builtin_clz (waveformEnabled );
212
+ }
212
213
213
- do {
214
+ bool done = false;
215
+ if (waveformEnabled ) do {
214
216
nextEventCycles = MicrosecondsToCycles (MAXIRQUS );
215
- for (size_t i = 0 ; i <= 16 ; i ++ ) {
217
+ for (int i = startPin ; i <= endPin ; i ++ ) {
216
218
uint32_t mask = 1 <<i ;
217
219
218
220
// If it's not on, ignore!
@@ -257,21 +259,27 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
257
259
nextEventCycles = min_u32 (nextEventCycles , deltaCycles );
258
260
}
259
261
}
260
- } while (nextEventCycles < MINCYCLE );
262
+ uint32_t now = GetCycleCountIRQ ();
263
+ done = false;
264
+ int32_t cycleDeltaNextEvent = timeoutCycle - (now + nextEventCycles );
265
+ if (cycleDeltaNextEvent < 0 ) done = true;
266
+ int32_t cyclesLeftTimeout = timeoutCycle - now ;
267
+ if (cyclesLeftTimeout < 0 ) done = true;
268
+ } while (!done );
261
269
262
270
if (timer1CB ) {
263
271
nextEventCycles = min_u32 (nextEventCycles , timer1CB ());
264
- if ( nextEventCycles < MINCYCLE ) {
265
- nextEventCycles = MINCYCLE ;
266
- }
272
+ }
273
+ if ( nextEventCycles < MicrosecondsToCycles ( 10 )) {
274
+ nextEventCycles = MicrosecondsToCycles ( 10 );
267
275
}
268
276
nextEventCycles -= DELTAIRQ ;
269
277
270
278
// Do it here instead of global function to save time and because we know it's edge-IRQ
271
- TEIE |= TEIE1 ; //edge int enable
272
279
#if F_CPU == 160000000
273
280
T1L = nextEventCycles >> 1 ; // Already know we're in range by MAXIRQUS
274
281
#else
275
282
T1L = nextEventCycles ; // Already know we're in range by MAXIRQUS
276
283
#endif
284
+ TEIE |= TEIE1 ; //edge int enable
277
285
}
0 commit comments