Firmware2/Marlin/src/HAL/HAL_ESP32/timers.cpp

175 lines
5.5 KiB
C++
Raw Normal View History

2017-10-08 18:38:10 +02:00
/**
* Marlin 3D Printer Firmware
2020-02-03 15:00:57 +01:00
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
2017-10-08 18:38:10 +02:00
*
* Based on Sprinter and grbl.
2019-06-28 06:57:50 +02:00
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
2017-10-08 18:38:10 +02: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/>.
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include <stdio.h>
#include <esp_types.h>
#include <soc/timer_group_struct.h>
#include <driver/periph_ctrl.h>
#include <driver/timer.h>
2017-10-08 18:38:10 +02:00
#include "HAL.h"
2019-09-03 02:49:58 +02:00
#include "timers.h"
2017-10-08 18:38:10 +02:00
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
// Local defines
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
#define NUM_HARDWARE_TIMERS 4
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
// Private Variables
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
{ TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3
2017-10-08 18:38:10 +02:00
};
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
// Public functions
2019-07-10 05:30:06 +02:00
// ------------------------
2017-10-08 18:38:10 +02:00
void IRAM_ATTR timer_isr(void *para) {
const tTimerConfig& timer = TimerConfig[(int)para];
2017-10-08 18:38:10 +02:00
// Retrieve the interrupt status and the counter value
// from the timer that reported the interrupt
uint32_t intr_status = TG[timer.group]->int_st_timers.val;
TG[timer.group]->hw_timer[timer.idx].update = 1;
2017-10-08 18:38:10 +02:00
// Clear the interrupt
if (intr_status & BIT(timer.idx)) {
switch (timer.idx) {
case TIMER_0: TG[timer.group]->int_clr_timers.t0 = 1; break;
case TIMER_1: TG[timer.group]->int_clr_timers.t1 = 1; break;
case TIMER_MAX: break;
2017-10-08 18:38:10 +02:00
}
}
timer.fn();
// After the alarm has been triggered
// Enable it again so it gets triggered the next time
TG[timer.group]->hw_timer[timer.idx].config.alarm_en = TIMER_ALARM_EN;
2017-10-08 18:38:10 +02:00
}
/**
* Enable and initialize the timer
* @param timer_num timer number to initialize
* @param frequency frequency of the timer
*/
void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
const tTimerConfig timer = TimerConfig[timer_num];
timer_config_t config;
config.divider = timer.divider;
2017-10-08 18:38:10 +02:00
config.counter_dir = TIMER_COUNT_UP;
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.intr_type = TIMER_INTR_LEVEL;
config.auto_reload = true;
// Select and initialize the timer
timer_init(timer.group, timer.idx, &config);
// Timer counter initial value and auto reload on alarm
timer_set_counter_value(timer.group, timer.idx, 0x00000000ULL);
// Configure the alam value and the interrupt on alarm
timer_set_alarm_value(timer.group, timer.idx, (HAL_TIMER_RATE) / timer.divider / frequency - 1);
timer_enable_intr(timer.group, timer.idx);
2020-02-04 01:36:51 +01:00
timer_isr_register(timer.group, timer.idx, timer_isr, (void*)(uint32_t)timer_num, 0, nullptr);
2017-10-08 18:38:10 +02:00
timer_start(timer.group, timer.idx);
}
/**
* Set the upper value of the timer, when the timer reaches this upper value the
* interrupt should be triggered and the counter reset
* @param timer_num timer number to set the count to
* @param count threshold at which the interrupt is triggered
*/
void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
const tTimerConfig timer = TimerConfig[timer_num];
timer_set_alarm_value(timer.group, timer.idx, count);
}
/**
* Get the current upper value of the timer
* @param timer_num timer number to get the count from
* @return the timer current threshold for the alarm to be triggered
*/
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
uint64_t alarm_value;
timer_get_alarm_value(timer.group, timer.idx, &alarm_value);
return alarm_value;
}
/**
* Get the current counter value between 0 and the maximum count (HAL_timer_set_count)
* @param timer_num timer number to get the current count
* @return the current counter of the alarm
*/
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
uint64_t counter_value;
timer_get_counter_value(timer.group, timer.idx, &counter_value);
return counter_value;
}
/**
* Enable timer interrupt on the timer
* @param timer_num timer number to enable interrupts on
*/
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
2019-05-26 00:06:00 +02:00
//const tTimerConfig timer = TimerConfig[timer_num];
2017-10-08 18:38:10 +02:00
//timer_enable_intr(timer.group, timer.idx);
}
/**
* Disable timer interrupt on the timer
* @param timer_num timer number to disable interrupts on
*/
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
2019-05-26 00:06:00 +02:00
//const tTimerConfig timer = TimerConfig[timer_num];
//timer_disable_intr(timer.group, timer.idx);
2017-10-08 18:38:10 +02:00
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const tTimerConfig timer = TimerConfig[timer_num];
return TG[timer.group]->int_ena.val | BIT(timer_num);
}
#endif // ARDUINO_ARCH_ESP32