FspTimer: using AGT timer issues

@ptillisch and others, not sure if best to ask here, or up on Github issues?

As I mentioned in the Servo library Issue, plus forum post, I have not handled the case where the FsPTimer ends up trying to use an AGT timer. I thought I would try to make it work. If it works, will also update my Charlieplex code as well. So not sure best place. But as this is a stand alone issue, decided to ask on new thread:

In a test program, I preallocated all of the GTP timers so it then continued on to try to allocate a AGT timer, which it did, but it is not working the way I would expect.

The sketch:

#include "FspTimer.h"
#include <UNOR4_digitalWriteFast.h>
static FspTimer servo_timer;

void setup() {
  while (!Serial && millis() < 5000)
    ;

  Serial.begin(9600);
  delay(500);
  Serial.println("Servo test program");
  pinMode(9, OUTPUT);

  // We will start off with the first servo at 1500

  // See if we can force the usage of AGT
  FspTimer::set_initial_timer_channel_as_pwm(GPT_TIMER, 4);
  FspTimer::set_initial_timer_channel_as_pwm(GPT_TIMER, 5);
  FspTimer::set_initial_timer_channel_as_pwm(GPT_TIMER, 6);
  uint8_t type = 0;
  int8_t channel = FspTimer::get_available_timer(type);
  Serial.print("\nservo_timer_config: type:");
  Serial.print(type, DEC);
  Serial.print(" Channel: ");
  Serial.println(channel, DEC);

  // lets initially configure the servo to 50ms
  if (!servo_timer.begin(TIMER_MODE_PERIODIC, type, channel,
                    1000000.0f / 20000, 50.0f, servo_timer_callback, nullptr)) {
    Serial.println("Timer failed to start");
  }

  // First pass assume GPT timer
  servo_timer.setup_overflow_irq();
  servo_timer.open();
  servo_timer.start();

  Serial.print("Raw Period: ");
  Serial.println(servo_timer.get_period_raw(), DEC);

}

void loop() {
}

void servo_timer_callback(timer_callback_args_t *args) {
  (void)args;  // remove warning
  digitalToggleFast(9);
}

(Sorry I cheated and used my own digitalToggleFast code)

I was expecting 20ms for the period:

But instead, it is about 1.77ms

Serial output:

Servo test program

servo_timer_config: type:1 Channel: 1

Raw Period: 960000

Note: servo_timer.get_period_raw() returned a period of 960000
Which does not make sense, as I am pretty sure this is a 16 bit counter.

Wonder maybe it did not like to do a period that long.
So tried changing to 1500.
Raw Period: 71999
image

Tried 750 -> 35999
image

Thoughts? Are there known issues with FSP and AGT?

Thanks
Kurt

1 Like

Probably should be a github issue:

Found first problems:

/* -------------------------------------------------------------------------- */
bool FspTimer::begin(timer_mode_t mode, uint8_t tp, uint8_t channel, float freq_hz, float duty_perc, GPTimerCbk_f cbk /*= nullptr*/ , void *ctx /*= nullptr*/  ) {
/* -------------------------------------------------------------------------- */

Problem is that it was using the member variable type to know if it was GPT or AGT, however
this is not set until it calls:

    if(init_ok) {
        init_ok = begin(mode, tp, channel, _period_counts, _duty_cycle_counts, _sd, cbk, ctx);
    }

I also needed to update
void FspTimer::set_period_counts(uint8_t tp, float period, uint32_t _max) {
To pass in the type.

And now test sketch is getting the frequency it is expecting.
image

Now to try it on my version of the servo code.

1 Like

Created Pull Request:
FspTimer does not initialize properly if AGT timer is selected. by KurtE · Pull Request #120 · arduino/ArduinoCore-renesas (github.com)

3 Likes

The fix should now be in the latest boards release.