Skip to content

Commit b2fde58

Browse files
authored
🐛 Fix LPC1768 timer issues (#28374)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 6b41caf commit b2fde58

1 file changed

Lines changed: 30 additions & 9 deletions

File tree

Marlin/src/HAL/LPC1768/timers.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@
3232
#define SBIT_TIMER0 1
3333
#define SBIT_TIMER1 2
3434

35-
#define SBIT_CNTEN 0
36-
37-
#define SBIT_MR0I 0 // Timer 0 Interrupt when TC matches MR0
38-
#define SBIT_MR0R 1 // Timer 0 Reset TC on Match
39-
#define SBIT_MR0S 2 // Timer 0 Stop TC and PC on Match
35+
// TCR (Timer Control Register) bits
36+
#define SBIT_CNTEN 0 // Counter Enable
37+
#define SBIT_CRST 1 // Counter Reset (hold TC and PC at 0 while set)
38+
39+
// MCR (Match Control Register) bits — also doubles as IR (Interrupt Register) bit positions
40+
#define SBIT_MR0I 0 // Interrupt when TC matches MR0 (IR bit 0 = MR0 interrupt flag)
41+
#define SBIT_MR0R 1 // Reset TC on Match
42+
#define SBIT_MR0S 2 // Stop TC and PC on Match
4043
#define SBIT_MR1I 3
4144
#define SBIT_MR1R 4
4245
#define SBIT_MR1S 5
@@ -110,8 +113,25 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
110113

111114
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
112115
switch (timer_num) {
113-
case MF_TIMER_STEP: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0
114-
case MF_TIMER_TEMP: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0
116+
case MF_TIMER_STEP: {
117+
STEP_TIMER_PTR->MR0 = compare;
118+
// If the counter has already passed the compare value, reset it now to avoid
119+
// waiting for TC to wrap around (~171s at 25MHz) before the next interrupt.
120+
// Read TC once to minimize the window between the comparison and the reset.
121+
const hal_timer_t tc = STEP_TIMER_PTR->TC;
122+
if (tc >= compare) {
123+
SBI(STEP_TIMER_PTR->TCR, SBIT_CRST); // Assert counter reset (TC held at 0)
124+
CBI(STEP_TIMER_PTR->TCR, SBIT_CRST); // Release reset; TC starts counting from 0
125+
}
126+
} break;
127+
case MF_TIMER_TEMP: {
128+
TEMP_TIMER_PTR->MR0 = compare;
129+
const hal_timer_t tc = TEMP_TIMER_PTR->TC;
130+
if (tc >= compare) {
131+
SBI(TEMP_TIMER_PTR->TCR, SBIT_CRST);
132+
CBI(TEMP_TIMER_PTR->TCR, SBIT_CRST);
133+
}
134+
} break;
115135
}
116136
}
117137

@@ -165,8 +185,9 @@ FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
165185

166186
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
167187
switch (timer_num) {
168-
case MF_TIMER_STEP: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break;
169-
case MF_TIMER_TEMP: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break;
188+
// Clear the match interrupt flag (IR bit 0 = MR0 interrupt) by writing 1 to it
189+
case MF_TIMER_STEP: SBI(STEP_TIMER_PTR->IR, SBIT_MR0I); break;
190+
case MF_TIMER_TEMP: SBI(TEMP_TIMER_PTR->IR, SBIT_MR0I); break;
170191
}
171192
}
172193

0 commit comments

Comments
 (0)