From 2c8a3bc38002be1eb176fb63302cc6688fe3e5c4 Mon Sep 17 00:00:00 2001 From: kurte Date: Sun, 10 Sep 2023 07:15:19 -0700 Subject: [PATCH] Add method to allow the GPT Timer period not to be buffered During code review of changes I made to the Servo library: https://github.com/arduino-libraries/Servo/pull/116 @iabdalkader requested that I move all of the platform specific timer changes into the core instead of being in the hardware specific sub-directory of the Servo library. This change adds a method to tell the GPT timer, that when I make a change to the pseriod (set_period(p) ) that I want the change to happen now and not be buffered. And updated the set_period method to check for this and directly set the not buffered register with the new period. --- cores/arduino/FspTimer.cpp | 39 +++++++++++++++++++++++++++++++++++++- cores/arduino/FspTimer.h | 3 +++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/cores/arduino/FspTimer.cpp b/cores/arduino/FspTimer.cpp index f613d5dc..2345707c 100644 --- a/cores/arduino/FspTimer.cpp +++ b/cores/arduino/FspTimer.cpp @@ -11,7 +11,7 @@ bool FspTimer::force_pwm_reserved = false; TimerAvail_t FspTimer::gpt_used_channel[GPT_HOWMANY] = { TIMER_FREE }; TimerAvail_t FspTimer::agt_used_channel[AGT_HOWMANY] = { TIMER_FREE }; -FspTimer::FspTimer(): init_ok(false), agt_timer(nullptr), gpt_timer(nullptr), type(GPT_TIMER) { +FspTimer::FspTimer(): init_ok(false), agt_timer(nullptr), gpt_timer(nullptr), type(GPT_TIMER), _buffer_period(true) { // AGT0 is always used for timekeeping (millis() and micros()) // agt_used_channel[0] = TIMER_USED; timer_cfg.cycle_end_irq = FSP_INVALID_VECTOR; @@ -453,9 +453,15 @@ bool FspTimer::set_period(uint32_t p) { /* -------------------------------------------------------------------------- */ if(type == GPT_TIMER && gpt_timer != nullptr) { + if (_buffer_period) { if (R_GPT_PeriodSet(&(gpt_timer->ctrl), p) != FSP_SUCCESS) { return false; } + } + else { + // Not buffered set it directl + gpt_timer->ctrl.p_reg->GTPR = p; + } } else if(type == AGT_TIMER && agt_timer != nullptr) { if (R_AGT_PeriodSet(&(agt_timer->ctrl), p) != FSP_SUCCESS) { @@ -470,6 +476,37 @@ bool FspTimer::set_period(uint32_t p) { +/* -------------------------------------------------------------------------- */ +bool FspTimer::use_period_buffer(bool buffer_period) { +/* -------------------------------------------------------------------------- */ + + if (_buffer_period == (uint8_t)buffer_period) { + return true; + } + + _buffer_period = (uint8_t)buffer_period; + if(type == GPT_TIMER && gpt_timer != nullptr) { + + if (buffer_period) { + gpt_timer->ctrl.p_reg->GTBER_b.PR = 1; + gpt_timer->ctrl.p_reg->GTBER_b.BD1 = 0; + } + else { + gpt_timer->ctrl.p_reg->GTBER_b.PR = 0; + gpt_timer->ctrl.p_reg->GTBER_b.BD1 = 1; + } + } + else if(type == AGT_TIMER && agt_timer != nullptr) { + // not buffered.. + } + else { + return false; + } + return true; +} + + + /* -------------------------------------------------------------------------- */ bool FspTimer::open() { /* -------------------------------------------------------------------------- */ diff --git a/cores/arduino/FspTimer.h b/cores/arduino/FspTimer.h index ffd2c801..2de77837 100644 --- a/cores/arduino/FspTimer.h +++ b/cores/arduino/FspTimer.h @@ -95,6 +95,7 @@ class FspTimer { uint32_t _duty_cycle_counts; timer_source_div_t _sd; uint8_t type; + uint8_t _buffer_period; void set_period_counts(uint8_t tp, float period, uint32_t max); TimerIrqCfg_t get_cfg_for_irq(); static bool force_pwm_reserved; @@ -111,6 +112,8 @@ class FspTimer { bool reset(); bool set_duty_cycle(uint32_t const duty_cycle_counts, TimerPWMChannel_t pwm_ch); bool set_period(uint32_t p); + bool use_period_buffer(bool buffer_period); + bool close(); void enable_pwm_channel(TimerPWMChannel_t pwm_channel); uint32_t get_counter();