From 1beaef04521e60533cf39df67bf34c333c67839a Mon Sep 17 00:00:00 2001
From: Bob-the-Kuhn <bob.kuhn@att.net>
Date: Fri, 29 Sep 2017 23:52:17 -0500
Subject: [PATCH] fix 3S hang & enable SPLIT

---
 Marlin/src/HAL/HAL_LPC1768/HAL_timers.h | 12 +++-
 Marlin/src/module/stepper.cpp           | 74 ++++++++++++++-----------
 2 files changed, 51 insertions(+), 35 deletions(-)

diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h
index dcbaec67a9..03d782ba7e 100644
--- a/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h
+++ b/Marlin/src/HAL/HAL_LPC1768/HAL_timers.h
@@ -79,8 +79,16 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
 
 static FORCE_INLINE void HAL_timer_set_count(const uint8_t timer_num, const HAL_TIMER_TYPE count) {
   switch (timer_num) {
-    case 0: LPC_TIM0->MR0 = count; break;
-    case 1: LPC_TIM1->MR0 = count; break;
+    case 0:
+      LPC_TIM0->MR0 = count;
+      if (LPC_TIM0->TC > count)
+        LPC_TIM0->TC = count - 5; // generate an immediate stepper ISR
+      break;
+    case 1:
+      LPC_TIM1->MR0 = count;
+      if (LPC_TIM1->TC > count)
+        LPC_TIM1->TC = count - 5; // make sure we don't have one extra long period
+      break;
   }
 }
 
diff --git a/Marlin/src/module/stepper.cpp b/Marlin/src/module/stepper.cpp
index 7cfc0f630d..06af28f295 100644
--- a/Marlin/src/module/stepper.cpp
+++ b/Marlin/src/module/stepper.cpp
@@ -323,8 +323,13 @@ void Stepper::isr() {
 
   HAL_TIMER_TYPE ocr_val;
 
-  #define ENDSTOP_NOMINAL_OCR_VAL 3000    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
-  #define OCR_VAL_TOLERANCE 1000          // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
+  #if defined(CPU_32_BIT)
+    #define ENDSTOP_NOMINAL_OCR_VAL 1500 * HAL_TICKS_PER_US    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
+    #define OCR_VAL_TOLERANCE 500 * HAL_TICKS_PER_US           // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
+  #else
+    #define ENDSTOP_NOMINAL_OCR_VAL 3000    // check endstops every 1.5ms to guarantee two stepper ISRs within 5ms for BLTouch
+    #define OCR_VAL_TOLERANCE 1000          // First max delay is 2.0ms, last min delay is 0.5ms, all others 1.5ms
+  #endif
 
   #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
     // Disable Timer0 ISRs and enable global ISR again to capture UART events (incoming chars)
@@ -335,40 +340,45 @@ void Stepper::isr() {
     #endif
   #endif
 
-  #define _SPLIT(L) (ocr_val = (HAL_TIMER_TYPE)L)
-  #if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) || defined(CPU_32_BIT)
-    #define SPLIT(L) _SPLIT(L)
-  #else                 // sample endstops in between step pulses
-    static uint32_t step_remaining = 0;
-    #define SPLIT(L) do { \
-      _SPLIT(L); \
-      if (ENDSTOPS_ENABLED && L > ENDSTOP_NOMINAL_OCR_VAL) { \
-        const uint16_t remainder = (uint16_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
-        ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \
-        step_remaining = (uint16_t)L - ocr_val; \
-      } \
-    }while(0)
+  static uint32_t step_remaining = 0;  // SPLIT function always runs.  This allows 16 bit timers to be
+                                       // used to generate the stepper ISR.
+  #define SPLIT(L) do { \
+    if (L > ENDSTOP_NOMINAL_OCR_VAL) { \
+      const uint32_t remainder = (uint32_t)L % (ENDSTOP_NOMINAL_OCR_VAL); \
+      ocr_val = (remainder < OCR_VAL_TOLERANCE) ? ENDSTOP_NOMINAL_OCR_VAL + remainder : ENDSTOP_NOMINAL_OCR_VAL; \
+      step_remaining = (uint32_t)L - ocr_val; \
+    } \
+    else \
+      ocr_val = L;\
+  }while(0)
 
-    if (step_remaining && ENDSTOPS_ENABLED) {   // Just check endstops - not yet time for a step
+  if (step_remaining) {
+    if (ENDSTOPS_ENABLED)
       endstops.update();
-      if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) {
-        step_remaining -= ENDSTOP_NOMINAL_OCR_VAL;
-        ocr_val = ENDSTOP_NOMINAL_OCR_VAL;
-      }
-      else {
-        ocr_val = step_remaining;
-        step_remaining = 0;  //  last one before the ISR that does the step
-      }
-
-      _NEXT_ISR(ocr_val);
-
-      NOLESS(OCR1A, TCNT1 + 16);
-
-      HAL_ENABLE_ISRs(); // re-enable ISRs
-      return;
+    if (step_remaining > ENDSTOP_NOMINAL_OCR_VAL) {
+      step_remaining -= ENDSTOP_NOMINAL_OCR_VAL;
+      ocr_val = ENDSTOP_NOMINAL_OCR_VAL;
     }
+    else {
+      ocr_val = step_remaining;
+      step_remaining = 0;  //  last one before the ISR that does the step
+    }
+
+    _NEXT_ISR(ocr_val);
+
+  #if DISABLED(ADVANCE) && DISABLED(LIN_ADVANCE)
+    #ifdef CPU_32_BIT
+      HAL_timer_set_count(STEP_TIMER_NUM, ocr_val);
+    #else
+      NOLESS(OCR1A, TCNT1 + 16);
+    #endif
+    HAL_ENABLE_ISRs(); // re-enable ISRs
   #endif
 
+    return;
+  }
+
+
   if (cleaning_buffer_counter) {
     --cleaning_buffer_counter;
     current_block = NULL;
@@ -748,7 +758,6 @@ void Stepper::isr() {
 
     SPLIT(timer);  // split step into multiple ISRs if larger than  ENDSTOP_NOMINAL_OCR_VAL
     _NEXT_ISR(ocr_val);
-
     deceleration_time += timer;
 
     #if ENABLED(LIN_ADVANCE)
@@ -832,7 +841,6 @@ void Stepper::isr() {
   // Timer interrupt for E. e_steps is set in the main routine;
 
   void Stepper::advance_isr() {
-
     nextAdvanceISR = eISR_Rate;
 
     #if ENABLED(MK2_MULTIPLEXER)