|
@@ -162,24 +162,148 @@ extern "C" {
|
162
|
162
|
* (otherwise, characters will be lost due to UART overflow).
|
163
|
163
|
* Then: Stepper, Endstops, Temperature, and -finally- all others.
|
164
|
164
|
*/
|
165
|
|
-#define HAL_timer_isr_prologue_0 do{ DISABLE_TEMPERATURE_INTERRUPT(); sei(); }while(0)
|
166
|
|
-#define HAL_timer_isr_epilogue_0 do{ cli(); ENABLE_TEMPERATURE_INTERRUPT(); }while(0)
|
167
|
|
-
|
168
|
|
-#define HAL_timer_isr_prologue_1 \
|
169
|
|
- const bool temp_isr_was_enabled = TEMPERATURE_ISR_ENABLED(); \
|
170
|
|
- do{ \
|
171
|
|
- DISABLE_TEMPERATURE_INTERRUPT(); \
|
172
|
|
- DISABLE_STEPPER_DRIVER_INTERRUPT(); \
|
173
|
|
- sei(); \
|
174
|
|
- }while(0)
|
175
|
|
-
|
176
|
|
-#define HAL_timer_isr_epilogue_1 do{ cli(); ENABLE_STEPPER_DRIVER_INTERRUPT(); if (temp_isr_was_enabled) ENABLE_TEMPERATURE_INTERRUPT(); }while(0)
|
177
|
|
-
|
178
|
|
-#define HAL_timer_isr_prologue(TIMER_NUM) _CAT(HAL_timer_isr_prologue_, TIMER_NUM)
|
179
|
|
-#define HAL_timer_isr_epilogue(TIMER_NUM) _CAT(HAL_timer_isr_epilogue_, TIMER_NUM)
|
180
|
|
-
|
181
|
|
-#define HAL_STEP_TIMER_ISR ISR(TIMER1_COMPA_vect)
|
182
|
|
-#define HAL_TEMP_TIMER_ISR ISR(TIMER0_COMPB_vect)
|
|
165
|
+#define HAL_timer_isr_prologue(TIMER_NUM)
|
|
166
|
+#define HAL_timer_isr_epilogue(TIMER_NUM)
|
|
167
|
+
|
|
168
|
+/* 18 cycles maximum latency */
|
|
169
|
+#define HAL_STEP_TIMER_ISR \
|
|
170
|
+extern "C" void TIMER1_COMPA_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
|
|
171
|
+extern "C" void TIMER1_COMPA_vect_bottom (void) asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
|
172
|
+void TIMER1_COMPA_vect (void) { \
|
|
173
|
+ __asm__ __volatile__ ( \
|
|
174
|
+ A("push r16") /* 2 Save R16 */ \
|
|
175
|
+ A("in r16, __SREG__") /* 1 Get SREG */ \
|
|
176
|
+ A("push r16") /* 2 Save SREG into stack */ \
|
|
177
|
+ A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
|
|
178
|
+ A("push r16") /* 2 Save TIMSK0 into the stack */ \
|
|
179
|
+ A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
|
|
180
|
+ A("sts %[timsk0], r16") /* 2 And set the new value */ \
|
|
181
|
+ A("lds r16, %[timsk1]") /* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
|
|
182
|
+ A("andi r16,~%[msk1]") /* 1 Disable the stepper ISR */ \
|
|
183
|
+ A("sts %[timsk1], r16") /* 2 And set the new value */ \
|
|
184
|
+ A("sei") /* 1 Enable global interrupts - stepper and temperature ISRs are disabled, so no risk of reentry or being preempted by the temperature ISR */ \
|
|
185
|
+ A("push r16") /* 2 Save TIMSK1 into stack */ \
|
|
186
|
+ A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
|
|
187
|
+ A("push r16") /* 2 Save RAMPZ into stack */ \
|
|
188
|
+ A("in r16, 0x3C") /* 1 Get EIND register */ \
|
|
189
|
+ A("push r0") /* C runtime can modify all the following registers without restoring them */ \
|
|
190
|
+ A("push r1") \
|
|
191
|
+ A("push r18") \
|
|
192
|
+ A("push r19") \
|
|
193
|
+ A("push r20") \
|
|
194
|
+ A("push r21") \
|
|
195
|
+ A("push r22") \
|
|
196
|
+ A("push r23") \
|
|
197
|
+ A("push r24") \
|
|
198
|
+ A("push r25") \
|
|
199
|
+ A("push r26") \
|
|
200
|
+ A("push r27") \
|
|
201
|
+ A("push r30") \
|
|
202
|
+ A("push r31") \
|
|
203
|
+ A("clr r1") /* C runtime expects this register to be 0 */ \
|
|
204
|
+ A("call TIMER1_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
|
205
|
+ A("pop r31") \
|
|
206
|
+ A("pop r30") \
|
|
207
|
+ A("pop r27") \
|
|
208
|
+ A("pop r26") \
|
|
209
|
+ A("pop r25") \
|
|
210
|
+ A("pop r24") \
|
|
211
|
+ A("pop r23") \
|
|
212
|
+ A("pop r22") \
|
|
213
|
+ A("pop r21") \
|
|
214
|
+ A("pop r20") \
|
|
215
|
+ A("pop r19") \
|
|
216
|
+ A("pop r18") \
|
|
217
|
+ A("pop r1") \
|
|
218
|
+ A("pop r0") \
|
|
219
|
+ A("out 0x3C, r16") /* 1 Restore EIND register */ \
|
|
220
|
+ A("pop r16") /* 2 Get the original RAMPZ register value */ \
|
|
221
|
+ A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
|
|
222
|
+ A("pop r16") /* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
|
|
223
|
+ A("ori r16,%[msk1]") /* 1 Reenable the stepper ISR */ \
|
|
224
|
+ A("cli") /* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
|
|
225
|
+ A("sts %[timsk1], r16") /* 2 And restore the old value - This reenables the stepper ISR */ \
|
|
226
|
+ A("pop r16") /* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
|
|
227
|
+ A("sts %[timsk0], r16") /* 2 And restore the old value - This reenables the temperature ISR */ \
|
|
228
|
+ A("pop r16") /* 2 Get the old SREG value */ \
|
|
229
|
+ A("out __SREG__, r16") /* 1 And restore the SREG value */ \
|
|
230
|
+ A("pop r16") /* 2 Restore R16 value */ \
|
|
231
|
+ A("reti") /* 4 Return from interrupt */ \
|
|
232
|
+ : \
|
|
233
|
+ : [timsk0] "i" ((uint16_t)&TIMSK0), \
|
|
234
|
+ [timsk1] "i" ((uint16_t)&TIMSK1), \
|
|
235
|
+ [msk0] "M" ((uint8_t)(1<<OCIE0B)),\
|
|
236
|
+ [msk1] "M" ((uint8_t)(1<<OCIE1A)) \
|
|
237
|
+ : \
|
|
238
|
+ ); \
|
|
239
|
+} \
|
|
240
|
+void TIMER1_COMPA_vect_bottom(void)
|
|
241
|
+
|
|
242
|
+/* 14 cycles maximum latency */
|
|
243
|
+#define HAL_TEMP_TIMER_ISR \
|
|
244
|
+extern "C" void TIMER0_COMPB_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
|
|
245
|
+extern "C" void TIMER0_COMPB_vect_bottom(void) asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
|
246
|
+void TIMER0_COMPB_vect (void) { \
|
|
247
|
+ __asm__ __volatile__ ( \
|
|
248
|
+ A("push r16") /* 2 Save R16 */ \
|
|
249
|
+ A("in r16, __SREG__") /* 1 Get SREG */ \
|
|
250
|
+ A("push r16") /* 2 Save SREG into stack */ \
|
|
251
|
+ A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
|
|
252
|
+ A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
|
|
253
|
+ A("sts %[timsk0], r16") /* 2 And set the new value */ \
|
|
254
|
+ A("sei") /* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
|
|
255
|
+ A("push r16") /* 2 Save TIMSK0 into stack */ \
|
|
256
|
+ A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
|
|
257
|
+ A("push r16") /* 2 Save RAMPZ into stack */ \
|
|
258
|
+ A("in r16, 0x3C") /* 1 Get EIND register */ \
|
|
259
|
+ A("push r0") /* C runtime can modify all the following registers without restoring them */ \
|
|
260
|
+ A("push r1") \
|
|
261
|
+ A("push r18") \
|
|
262
|
+ A("push r19") \
|
|
263
|
+ A("push r20") \
|
|
264
|
+ A("push r21") \
|
|
265
|
+ A("push r22") \
|
|
266
|
+ A("push r23") \
|
|
267
|
+ A("push r24") \
|
|
268
|
+ A("push r25") \
|
|
269
|
+ A("push r26") \
|
|
270
|
+ A("push r27") \
|
|
271
|
+ A("push r30") \
|
|
272
|
+ A("push r31") \
|
|
273
|
+ A("clr r1") /* C runtime expects this register to be 0 */ \
|
|
274
|
+ A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
|
275
|
+ A("pop r31") \
|
|
276
|
+ A("pop r30") \
|
|
277
|
+ A("pop r27") \
|
|
278
|
+ A("pop r26") \
|
|
279
|
+ A("pop r25") \
|
|
280
|
+ A("pop r24") \
|
|
281
|
+ A("pop r23") \
|
|
282
|
+ A("pop r22") \
|
|
283
|
+ A("pop r21") \
|
|
284
|
+ A("pop r20") \
|
|
285
|
+ A("pop r19") \
|
|
286
|
+ A("pop r18") \
|
|
287
|
+ A("pop r1") \
|
|
288
|
+ A("pop r0") \
|
|
289
|
+ A("out 0x3C, r16") /* 1 Restore EIND register */ \
|
|
290
|
+ A("pop r16") /* 2 Get the original RAMPZ register value */ \
|
|
291
|
+ A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
|
|
292
|
+ A("pop r16") /* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
|
|
293
|
+ A("ori r16,%[msk0]") /* 1 Enable temperature ISR */ \
|
|
294
|
+ A("cli") /* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don´t want to reenter this handler until the current one is done */ \
|
|
295
|
+ A("sts %[timsk0], r16") /* 2 And restore the old value */ \
|
|
296
|
+ A("pop r16") /* 2 Get the old SREG */ \
|
|
297
|
+ A("out __SREG__, r16") /* 1 And restore the SREG value */ \
|
|
298
|
+ A("pop r16") /* 2 Restore R16 */ \
|
|
299
|
+ A("reti") /* 4 Return from interrupt */ \
|
|
300
|
+ : \
|
|
301
|
+ : [timsk0] "i"((uint16_t)&TIMSK0), \
|
|
302
|
+ [msk0] "M" ((uint8_t)(1<<OCIE0B)) \
|
|
303
|
+ : \
|
|
304
|
+ ); \
|
|
305
|
+} \
|
|
306
|
+void TIMER0_COMPB_vect_bottom(void)
|
183
|
307
|
|
184
|
308
|
// ADC
|
185
|
309
|
#ifdef DIDR2
|