2019-02-12 21:06:53 +00:00
|
|
|
/**
|
|
|
|
* Marlin 3D Printer Firmware
|
2020-02-03 14:00:57 +00:00
|
|
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
2019-02-12 21:06:53 +00:00
|
|
|
*
|
|
|
|
* Based on Sprinter and grbl.
|
2019-06-28 04:57:50 +00:00
|
|
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
2019-02-12 21:06:53 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
2017-07-11 20:59:27 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Teensy3.5 __MK64FX512__
|
|
|
|
* Teensy3.6 __MK66FX1M0__
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
|
|
|
|
|
2018-04-13 01:25:08 +00:00
|
|
|
#include "HAL.h"
|
2019-09-03 00:49:58 +00:00
|
|
|
#include "timers.h"
|
2017-07-11 20:59:27 +00:00
|
|
|
|
2018-05-16 19:38:17 +00:00
|
|
|
/** \brief Instruction Synchronization Barrier
|
|
|
|
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
|
|
|
so that all instructions following the ISB are fetched from cache or
|
|
|
|
memory, after the instruction has been completed.
|
|
|
|
*/
|
2019-09-17 01:31:08 +00:00
|
|
|
FORCE_INLINE static void __ISB() {
|
2018-05-16 19:38:17 +00:00
|
|
|
__asm__ __volatile__("isb 0xF":::"memory");
|
|
|
|
}
|
|
|
|
|
|
|
|
/** \brief Data Synchronization Barrier
|
|
|
|
This function acts as a special kind of Data Memory Barrier.
|
|
|
|
It completes when all explicit memory accesses before this instruction complete.
|
|
|
|
*/
|
2019-09-17 01:31:08 +00:00
|
|
|
FORCE_INLINE static void __DSB() {
|
2018-05-16 19:38:17 +00:00
|
|
|
__asm__ __volatile__("dsb 0xF":::"memory");
|
|
|
|
}
|
2017-07-11 20:59:27 +00:00
|
|
|
|
2017-08-24 17:18:54 +00:00
|
|
|
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
2017-07-11 20:59:27 +00:00
|
|
|
switch (timer_num) {
|
2017-08-24 17:18:54 +00:00
|
|
|
case 0:
|
|
|
|
FTM0_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
|
|
|
|
FTM0_SC = 0x00; // Set this to zero before changing the modulus
|
|
|
|
FTM0_CNT = 0x0000; // Reset the count to zero
|
|
|
|
FTM0_MOD = 0xFFFF; // max modulus = 65535
|
2019-11-13 01:23:02 +00:00
|
|
|
FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value
|
2017-08-24 17:18:54 +00:00
|
|
|
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
|
|
|
|
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
FTM1_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN; // Disable write protection, Enable FTM1
|
|
|
|
FTM1_SC = 0x00; // Set this to zero before changing the modulus
|
|
|
|
FTM1_CNT = 0x0000; // Reset the count to zero
|
|
|
|
FTM1_MOD = 0xFFFF; // max modulus = 65535
|
2019-11-13 01:23:02 +00:00
|
|
|
FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535
|
2017-08-24 17:18:54 +00:00
|
|
|
FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4
|
|
|
|
FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
|
|
|
|
break;
|
2017-07-11 20:59:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-24 17:18:54 +00:00
|
|
|
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
|
2019-02-12 22:25:49 +00:00
|
|
|
switch (timer_num) {
|
2017-08-24 17:18:54 +00:00
|
|
|
case 0: NVIC_ENABLE_IRQ(IRQ_FTM0); break;
|
|
|
|
case 1: NVIC_ENABLE_IRQ(IRQ_FTM1); break;
|
2017-07-11 20:59:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-24 17:18:54 +00:00
|
|
|
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
|
2017-07-11 20:59:27 +00:00
|
|
|
switch (timer_num) {
|
2017-08-24 17:18:54 +00:00
|
|
|
case 0: NVIC_DISABLE_IRQ(IRQ_FTM0); break;
|
|
|
|
case 1: NVIC_DISABLE_IRQ(IRQ_FTM1); break;
|
2017-07-11 20:59:27 +00:00
|
|
|
}
|
2018-05-16 19:38:17 +00:00
|
|
|
|
|
|
|
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
|
|
|
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
|
|
|
__DSB();
|
|
|
|
__ISB();
|
2017-07-11 20:59:27 +00:00
|
|
|
}
|
|
|
|
|
2018-01-12 02:59:16 +00:00
|
|
|
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
|
|
|
|
switch (timer_num) {
|
|
|
|
case 0: return NVIC_IS_ENABLED(IRQ_FTM0);
|
|
|
|
case 1: return NVIC_IS_ENABLED(IRQ_FTM1);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-08-24 17:18:54 +00:00
|
|
|
void HAL_timer_isr_prologue(const uint8_t timer_num) {
|
2019-02-12 22:25:49 +00:00
|
|
|
switch (timer_num) {
|
2017-08-24 17:18:54 +00:00
|
|
|
case 0:
|
|
|
|
FTM0_CNT = 0x0000;
|
|
|
|
FTM0_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag
|
|
|
|
FTM0_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
FTM1_CNT = 0x0000;
|
|
|
|
FTM1_SC &= ~FTM_SC_TOF; // Clear FTM Overflow flag
|
|
|
|
FTM1_C0SC &= ~FTM_CSC_CHF; // Clear FTM Channel Compare flag
|
|
|
|
break;
|
2017-07-11 20:59:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // Teensy3.5 or Teensy3.6
|