Skip to content

Commit a493b4e

Browse files
committed
PWM: properly handle A/B channel cohexistence
1 parent 8e814ad commit a493b4e

File tree

5 files changed

+40
-21
lines changed

5 files changed

+40
-21
lines changed

cores/arduino/FspTimer.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,25 @@ void FspTimer::end() {
3939
bool FspTimer::begin_pwm(uint8_t tp, uint8_t channel, TimerPWMChannel_t pwm_channel) {
4040
/* -------------------------------------------------------------------------- */
4141
init_ok = true;
42-
42+
4343
init_ok = begin(TIMER_MODE_PWM,tp,channel, STANDARD_PWM_FREQ_HZ ,STANDARD_DUTY_CYCLE_PERC);
44-
44+
4545
if(tp == GPT_TIMER) {
4646
add_pwm_extended_cfg();
4747
}
48-
48+
4949
enable_pwm_channel(pwm_channel);
5050

5151
if(init_ok) {
5252
init_ok &= open();
5353
init_ok &= start();
5454
}
55-
55+
5656
return init_ok;
5757
}
5858

59+
extern FspTimer* __get_timer_for_channel(int channel);
60+
5961
/* begin function RAW mode */
6062
/* -------------------------------------------------------------------------- */
6163
bool FspTimer::begin(timer_mode_t mode, uint8_t tp, uint8_t channel, uint32_t period_counts, uint32_t pulse_counts, timer_source_div_t sd, GPTimerCbk_f cbk /*= nullptr*/ , void *ctx /*= nullptr*/ ) {
@@ -72,7 +74,6 @@ bool FspTimer::begin(timer_mode_t mode, uint8_t tp, uint8_t channel, uint32_t pe
7274
timer_cfg.cycle_end_ipl = (BSP_IRQ_DISABLED);
7375
timer_cfg.cycle_end_irq = FSP_INVALID_VECTOR;
7476

75-
7677
if(tp == GPT_TIMER) {
7778
type = GPT_TIMER;
7879
gpt_timer = new GPTimer(timer_cfg);
@@ -83,6 +84,12 @@ bool FspTimer::begin(timer_mode_t mode, uint8_t tp, uint8_t channel, uint32_t pe
8384
timer_cfg.channel = channel;
8485
gpt_used_channel[channel] = TIMER_USED;
8586
init_ok = true;
87+
} else if (mode == TIMER_USED) {
88+
// check if compatible PWM on another channel
89+
timer_cfg.channel = channel;
90+
memcpy(&(gpt_timer->ext_cfg), __get_timer_for_channel(channel)->get_cfg()->p_extend, sizeof(gpt_extended_cfg_t));
91+
timer_cfg.duty_cycle_counts = __get_timer_for_channel(channel)->get_duty_cycle();
92+
init_ok = true;
8693
}
8794
}
8895
else {
@@ -551,7 +558,8 @@ bool FspTimer::start() {
551558

552559
/* -------------------------------------------------------------------------- */
553560
bool FspTimer::set_duty_cycle(uint32_t const duty_cycle_counts, TimerPWMChannel_t pwm_ch) {
554-
/* -------------------------------------------------------------------------- */
561+
/* -------------------------------------------------------------------------- */
562+
_duty_cycle_counts = duty_cycle_counts;
555563
if(type == GPT_TIMER && gpt_timer != nullptr) {
556564
uint32_t pin = (pwm_ch == CHANNEL_A) ? GPT_IO_PIN_GTIOCA : GPT_IO_PIN_GTIOCB;
557565
if (R_GPT_DutyCycleSet(&(gpt_timer->ctrl), duty_cycle_counts, pin) != FSP_SUCCESS) {

cores/arduino/FspTimer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class FspTimer {
115115
void enable_pwm_channel(TimerPWMChannel_t pwm_channel);
116116
uint32_t get_counter();
117117
uint32_t get_freq_hz();
118+
uint32_t get_duty_cycle() { return _duty_cycle_counts; };
118119
uint32_t get_channel();
119120

120121
static void set_timer_is_used(uint8_t type, int index) {

cores/arduino/analog.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,16 @@ class PwmArray {
765765
}
766766
return nullptr;
767767
}
768+
PwmOut *get_from_channel(int channel) {
769+
size_t i = 0;
770+
while (i < last_index) {
771+
if (pwm_outs[i]->get_timer()->get_cfg()->channel == channel) {
772+
return pwm_outs[i];
773+
}
774+
i++;
775+
}
776+
return nullptr;
777+
}
768778
bool set(int pinNumber, PwmOut *p) {
769779
if (last_index < sizeof(chans)/sizeof(chans[0]) && p != nullptr) {
770780
chans[last_index] = pinNumber;
@@ -801,7 +811,7 @@ void analogWrite(pin_size_t pinNumber, int value)
801811
bool added = pwms.set(pinNumber, ptr);
802812
if(!added || !ptr->begin()) {
803813
delete ptr;
804-
return;
814+
ptr = nullptr;
805815
}
806816
}
807817

@@ -810,3 +820,6 @@ void analogWrite(pin_size_t pinNumber, int value)
810820
}
811821
}
812822

823+
FspTimer* __get_timer_for_channel(int channel) {
824+
return pwms.get_from_channel(channel)->get_timer();
825+
}

cores/arduino/pwm.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@ PwmOut::PwmOut(int pinNumber) :
1515
PwmOut::~PwmOut() {
1616
}
1717

18-
19-
20-
2118
bool PwmOut::cfg_pin(int max_index) {
2219
/* verify index are good */
2320
if(_pin < 0 || _pin >= max_index) {
@@ -26,20 +23,20 @@ bool PwmOut::cfg_pin(int max_index) {
2623
/* getting configuration from table */
2724
const uint16_t *cfg = g_pin_cfg[_pin].list;
2825
uint16_t pin_cgf = getPinCfg(cfg, PIN_CFG_REQ_PWM,false);
29-
26+
3027
/* verify configuration are good */
3128
if(pin_cgf == 0) {
3229
return false;
3330
}
34-
31+
3532
timer_channel = GET_CHANNEL(pin_cgf);
3633

37-
_is_gtp = IS_PIN_GPT_PWM(pin_cgf);
34+
_is_agt = IS_PIN_AGT_PWM(pin_cgf);
3835

3936
_pwm_channel = IS_PWM_ON_A(pin_cgf) ? CHANNEL_A : CHANNEL_B;
4037

4138
/* actually configuring PIN function */
42-
R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[_pin].pin, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_GPT1));
39+
R_IOPORT_PinCfg(&g_ioport_ctrl, g_pin_cfg[_pin].pin, (uint32_t) (IOPORT_CFG_PERIPHERAL_PIN | (_is_agt ? IOPORT_PERIPHERAL_AGT : IOPORT_PERIPHERAL_GPT1)));
4340
return true;
4441

4542
}
@@ -49,14 +46,14 @@ bool PwmOut::begin() {
4946
bool rv = true;
5047
int max_index = g_pin_cfg_size / sizeof(g_pin_cfg[0]);
5148
rv &= cfg_pin(max_index);
52-
49+
5350
if(rv) {
5451
/* extended PWM CFG*/
55-
if(_is_gtp) {
56-
rv &= timer.begin_pwm(GPT_TIMER, timer_channel, _pwm_channel);
52+
if(_is_agt) {
53+
rv &= timer.begin_pwm(AGT_TIMER, timer_channel, _pwm_channel);
5754
}
5855
else {
59-
rv &= timer.begin_pwm(AGT_TIMER, timer_channel, _pwm_channel);
56+
rv &= timer.begin_pwm(GPT_TIMER, timer_channel, _pwm_channel);
6057
}
6158
}
6259
_enabled = rv;
@@ -76,13 +73,13 @@ bool PwmOut::begin(uint32_t period_width, uint32_t pulse_width, bool raw /*= fal
7673

7774
if(_enabled) {
7875
if(raw) {
79-
_enabled &= timer.begin(TIMER_MODE_PWM, (_is_gtp) ? GPT_TIMER : AGT_TIMER , timer_channel, period_width, pulse_width, sd);
76+
_enabled &= timer.begin(TIMER_MODE_PWM, (_is_agt) ? AGT_TIMER : GPT_TIMER, timer_channel, period_width, pulse_width, sd);
8077
}
8178
else {
8279
/* NOTE: I suppose period and pulse are expressed in us */
8380
float freq_hz = (1000000.0 / (float)period_width);
8481
float duty_perc = ((float)pulse_width * 100.0 / (float)period_width);
85-
_enabled &= timer.begin(TIMER_MODE_PWM, (_is_gtp) ? GPT_TIMER : AGT_TIMER , timer_channel, freq_hz, duty_perc);
82+
_enabled &= timer.begin(TIMER_MODE_PWM, (_is_agt) ? AGT_TIMER : GPT_TIMER, timer_channel, freq_hz, duty_perc);
8683
}
8784

8885
timer.add_pwm_extended_cfg();

cores/arduino/pwm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class PwmOut {
3939
bool cfg_pin(int max_index);
4040
int _pin;
4141
bool _enabled;
42-
bool _is_gtp;
42+
bool _is_agt;
4343
TimerPWMChannel_t _pwm_channel;
4444

4545
uint8_t timer_channel;

0 commit comments

Comments
 (0)