Przeglądaj źródła

Move SAMD51 Temperature timer to RTC (#16868)

Giuliano Zaro 4 lat temu
rodzic
commit
199a1ba0e5
No account linked to committer's email address

+ 69
- 37
Marlin/src/HAL/HAL_SAMD51/timers.cpp Wyświetl plik

37
 // Private Variables
37
 // Private Variables
38
 // --------------------------------------------------------------------------
38
 // --------------------------------------------------------------------------
39
 
39
 
40
-const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS] = {
41
-  { TC0, TC0_IRQn, TC_PRIORITY(0) },
42
-  { TC1, TC1_IRQn, TC_PRIORITY(1) },
43
-  { TC2, TC2_IRQn, TC_PRIORITY(2) },  // Reserved by framework tone function
44
-  { TC3, TC3_IRQn, TC_PRIORITY(3) },  // Reserved by servo library
45
-  { TC4, TC4_IRQn, TC_PRIORITY(4) },
46
-  { TC5, TC5_IRQn, TC_PRIORITY(5) },
47
-  { TC6, TC6_IRQn, TC_PRIORITY(6) },
48
-  { TC7, TC7_IRQn, TC_PRIORITY(7) }
40
+const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS+1] = {
41
+  { {.pTc=TC0},  TC0_IRQn, TC_PRIORITY(0) },  // 0 - stepper
42
+  { {.pTc=TC1},  TC1_IRQn, TC_PRIORITY(1) },  // 1 - stepper (needed by 32 bit timers)
43
+  { {.pTc=TC2},  TC2_IRQn, TC_PRIORITY(2) },  // 2 - tone (framework)
44
+  { {.pTc=TC3},  TC3_IRQn, TC_PRIORITY(3) },  // 3 - servo
45
+  { {.pTc=TC4},  TC4_IRQn, TC_PRIORITY(4) },
46
+  { {.pTc=TC5},  TC5_IRQn, TC_PRIORITY(5) },
47
+  { {.pTc=TC6},  TC6_IRQn, TC_PRIORITY(6) },
48
+  { {.pTc=TC7},  TC7_IRQn, TC_PRIORITY(7) },
49
+  { {.pRtc=RTC}, RTC_IRQn, TC_PRIORITY(8) }   // 8 - temperature
49
 };
50
 };
50
 
51
 
51
 // --------------------------------------------------------------------------
52
 // --------------------------------------------------------------------------
66
 // --------------------------------------------------------------------------
67
 // --------------------------------------------------------------------------
67
 
68
 
68
 void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
69
 void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
69
-  Tc * const tc = TimerConfig[timer_num].pTimer;
70
   IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
70
   IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
71
 
71
 
72
   // Disable interrupt, just in case it was already enabled
72
   // Disable interrupt, just in case it was already enabled
73
   Disable_Irq(irq);
73
   Disable_Irq(irq);
74
 
74
 
75
-  // Disable timer interrupt
76
-  tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
75
+  if (timer_num == RTC_TIMER_NUM) {
76
+    Rtc * const rtc = TimerConfig[timer_num].pRtc;
77
 
77
 
78
-  // TCn clock setup
79
-  const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num];
80
-  GCLK->PCHCTRL[clockID].bit.CHEN = false;
81
-  SYNC(GCLK->PCHCTRL[clockID].bit.CHEN);
82
-  GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;   // 120MHz startup code programmed
83
-  SYNC(!GCLK->PCHCTRL[clockID].bit.CHEN);
78
+    // Disable timer interrupt
79
+    rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
84
 
80
 
85
-  // Stop timer, just in case, to be able to reconfigure it
86
-  tc->COUNT32.CTRLA.bit.ENABLE = false;
87
-  SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
81
+    // RTC clock setup
82
+    OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K;  // External 32.768KHz oscillator
88
 
83
 
89
-  // Reset timer
90
-  tc->COUNT32.CTRLA.bit.SWRST = true;
91
-  SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST);
84
+    // Stop timer, just in case, to be able to reconfigure it
85
+    rtc->MODE0.CTRLA.bit.ENABLE = false;
86
+    SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
92
 
87
 
93
-  NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
88
+    // Mode, reset counter on match
89
+    rtc->MODE0.CTRLA.reg = RTC_MODE0_CTRLA_MODE_COUNT32 | RTC_MODE0_CTRLA_MATCHCLR;
90
+
91
+    // Set compare value
92
+    rtc->MODE0.COMP[0].reg = (32768 + frequency / 2) / frequency;
93
+    SYNC(rtc->MODE0.SYNCBUSY.bit.COMP0);
94
+
95
+    // Enable interrupt on compare
96
+    rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;    // reset pending interrupt
97
+    rtc->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;  // enable compare 0 interrupt
98
+
99
+    // And start timer
100
+    rtc->MODE0.CTRLA.bit.ENABLE = true;
101
+    SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
102
+  }
103
+  else {
104
+    Tc * const tc = TimerConfig[timer_num].pTc;
105
+
106
+    // Disable timer interrupt
107
+    tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
94
 
108
 
95
-  // Wave mode, reset counter on overflow on 0 (I use count down to prevent double buffer use)
96
-  tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
97
-  tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1;
98
-  tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_DIR;
99
-  SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
109
+    // TCn clock setup
110
+    const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num];   // TC clock are preceeded by TCC ones
111
+    GCLK->PCHCTRL[clockID].bit.CHEN = false;
112
+    SYNC(GCLK->PCHCTRL[clockID].bit.CHEN);
113
+    GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN;   // 120MHz startup code programmed
114
+    SYNC(!GCLK->PCHCTRL[clockID].bit.CHEN);
100
 
115
 
101
-  // Set compare value
102
-  tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency;
116
+    // Stop timer, just in case, to be able to reconfigure it
117
+    tc->COUNT32.CTRLA.bit.ENABLE = false;
118
+    SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
103
 
119
 
104
-  // And start timer
105
-  tc->COUNT32.CTRLA.bit.ENABLE = true;
106
-  SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
120
+    // Reset timer
121
+    tc->COUNT32.CTRLA.bit.SWRST = true;
122
+    SYNC(tc->COUNT32.SYNCBUSY.bit.SWRST);
107
 
123
 
108
-  // Enable interrupt on RC compare
109
-  tc->COUNT32.INTENSET.reg = TC_INTENCLR_OVF; // enable overflow interrupt
124
+    // Wave mode, reset counter on overflow on 0 (I use count down to prevent double buffer use)
125
+    tc->COUNT32.WAVE.reg = TC_WAVE_WAVEGEN_MFRQ;
126
+    tc->COUNT32.CTRLA.reg = TC_CTRLA_MODE_COUNT32 | TC_CTRLA_PRESCALER_DIV1;
127
+    tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_DIR;
128
+    SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
129
+
130
+    // Set compare value
131
+    tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency;
132
+
133
+    // Enable interrupt on compare
134
+    tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;   // reset pending interrupt
135
+    tc->COUNT32.INTENSET.reg = TC_INTENSET_OVF; // enable overflow interrupt
136
+
137
+    // And start timer
138
+    tc->COUNT32.CTRLA.bit.ENABLE = true;
139
+    SYNC(tc->COUNT32.SYNCBUSY.bit.ENABLE);
140
+  }
110
 
141
 
111
   // Finally, enable IRQ
142
   // Finally, enable IRQ
143
+  NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
112
   NVIC_EnableIRQ(irq);
144
   NVIC_EnableIRQ(irq);
113
 }
145
 }
114
 
146
 

+ 28
- 10
Marlin/src/HAL/HAL_SAMD51/timers.h Wyświetl plik

25
 // --------------------------------------------------------------------------
25
 // --------------------------------------------------------------------------
26
 // Defines
26
 // Defines
27
 // --------------------------------------------------------------------------
27
 // --------------------------------------------------------------------------
28
+#define RTC_TIMER_NUM       8   // This is not a TC but a RTC
28
 
29
 
29
 typedef uint32_t hal_timer_t;
30
 typedef uint32_t hal_timer_t;
30
 #define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
31
 #define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
33
 
34
 
34
 #define STEP_TIMER_NUM      0  // index of timer to use for stepper (also +1 for 32bits counter)
35
 #define STEP_TIMER_NUM      0  // index of timer to use for stepper (also +1 for 32bits counter)
35
 #define PULSE_TIMER_NUM     STEP_TIMER_NUM
36
 #define PULSE_TIMER_NUM     STEP_TIMER_NUM
36
-#define TEMP_TIMER_NUM      4  // index of timer to use for temperature (also +1 for 32bits counter)
37
+#define TEMP_TIMER_NUM      RTC_TIMER_NUM  // index of timer to use for temperature
37
 
38
 
38
 #define TEMP_TIMER_FREQUENCY   1000 // temperature interrupt frequency
39
 #define TEMP_TIMER_FREQUENCY   1000 // temperature interrupt frequency
39
 
40
 
40
 #define STEPPER_TIMER_RATE          HAL_TIMER_RATE   // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
41
 #define STEPPER_TIMER_RATE          HAL_TIMER_RATE   // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
41
-#define STEPPER_TIMER_TICKS_PER_US  ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
42
+#define STEPPER_TIMER_TICKS_PER_US  (STEPPER_TIMER_RATE / 1000000) // stepper timer ticks per µs
42
 #define STEPPER_TIMER_PRESCALE      (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
43
 #define STEPPER_TIMER_PRESCALE      (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
43
 
44
 
44
 #define PULSE_TIMER_RATE          STEPPER_TIMER_RATE
45
 #define PULSE_TIMER_RATE          STEPPER_TIMER_RATE
62
 #if STEP_TIMER_NUM != PULSE_TIMER_NUM
63
 #if STEP_TIMER_NUM != PULSE_TIMER_NUM
63
   #define HAL_PULSE_TIMER_ISR()  TC_HANDLER(PULSE_TIMER_NUM)
64
   #define HAL_PULSE_TIMER_ISR()  TC_HANDLER(PULSE_TIMER_NUM)
64
 #endif
65
 #endif
65
-#define HAL_TEMP_TIMER_ISR()  TC_HANDLER(TEMP_TIMER_NUM)
66
+#if TEMP_TIMER_NUM == RTC_TIMER_NUM
67
+  #define HAL_TEMP_TIMER_ISR()  void RTC_Handler()
68
+#else
69
+  #define HAL_TEMP_TIMER_ISR()  TC_HANDLER(TEMP_TIMER_NUM)
70
+#endif
66
 
71
 
67
 // --------------------------------------------------------------------------
72
 // --------------------------------------------------------------------------
68
 // Types
73
 // Types
69
 // --------------------------------------------------------------------------
74
 // --------------------------------------------------------------------------
70
 
75
 
71
 typedef struct {
76
 typedef struct {
72
-  Tc          *pTimer;
77
+  union {
78
+    Tc  *pTc;
79
+    Rtc *pRtc;
80
+  };
73
   IRQn_Type   IRQ_Id;
81
   IRQn_Type   IRQ_Id;
74
   uint8_t     priority;
82
   uint8_t     priority;
75
 } tTimerConfig;
83
 } tTimerConfig;
87
 void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
95
 void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
88
 
96
 
89
 FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
97
 FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
90
-  Tc * const tc = TimerConfig[timer_num].pTimer;
98
+  // Should never be called with timer RTC_TIMER_NUM
99
+  Tc * const tc = TimerConfig[timer_num].pTc;
91
   tc->COUNT32.CC[0].reg = HAL_TIMER_TYPE_MAX - compare;
100
   tc->COUNT32.CC[0].reg = HAL_TIMER_TYPE_MAX - compare;
92
 }
101
 }
93
 
102
 
94
 FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
103
 FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
95
-  Tc * const tc = TimerConfig[timer_num].pTimer;
104
+  // Should never be called with timer RTC_TIMER_NUM
105
+  Tc * const tc = TimerConfig[timer_num].pTc;
96
   return (hal_timer_t)(HAL_TIMER_TYPE_MAX - tc->COUNT32.CC[0].reg);
106
   return (hal_timer_t)(HAL_TIMER_TYPE_MAX - tc->COUNT32.CC[0].reg);
97
 }
107
 }
98
 
108
 
99
 FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
109
 FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
100
-  Tc * const tc = TimerConfig[timer_num].pTimer;
110
+  // Should never be called with timer RTC_TIMER_NUM
111
+  Tc * const tc = TimerConfig[timer_num].pTc;
101
   tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
112
   tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
102
   SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
113
   SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
103
   return HAL_TIMER_TYPE_MAX - tc->COUNT32.COUNT.reg;
114
   return HAL_TIMER_TYPE_MAX - tc->COUNT32.COUNT.reg;
108
 bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
119
 bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
109
 
120
 
110
 FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
121
 FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
111
-  Tc * const tc = TimerConfig[timer_num].pTimer;
112
-  // Clear interrupt flag
113
-  tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
122
+  if (timer_num == RTC_TIMER_NUM) {
123
+    Rtc * const rtc = TimerConfig[timer_num].pRtc;
124
+    // Clear interrupt flag
125
+    rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
126
+  }
127
+  else {
128
+    Tc * const tc = TimerConfig[timer_num].pTc;
129
+    // Clear interrupt flag
130
+    tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
131
+  }
114
 }
132
 }
115
 
133
 
116
 #define HAL_timer_isr_epilogue(timer_num)
134
 #define HAL_timer_isr_epilogue(timer_num)

Ładowanie…
Anuluj
Zapisz