Multiple R4 Timer Issue

Hello,
I used Phil Schatzmann's writeup to successfully get one timer working on the R4. I tried two timers with different rates but only the first timer runs. The index from FspTimer::get_available_timer is different for each timer so it would not appear to be that. I attached a test case. By commenting out either beginTimer0 or beginTimer1 I can get a single frequency to work.
Thanks for any help

#include <Wire.h>          // I2C
#include <FspTimer.h>      // Timer Support
FspTimer audio_timer;


/******************************************************/
//                  Timer                            //
/******************************************************/
// callback method used by timer0.  SPI DAC timer
uint8_t timer0_tog = 0;
void timer0_callback(timer_callback_args_t __attribute((unused)) *p_args) {
  if (timer0_tog) {
    digitalWrite(D0, HIGH);
    timer0_tog = 0;
  } else {
    digitalWrite(D0, LOW);
    timer0_tog = 1;
  }

}

bool beginTimer0(float rate) {
  uint8_t timer_type = GPT_TIMER;
  int8_t tindex = FspTimer::get_available_timer(timer_type);
  if (tindex < 0){
    tindex = FspTimer::get_available_timer(timer_type, true);
  }
  if (tindex < 0){
    return false;
  }
  FspTimer::force_use_of_pwm_reserved_timer();

  Serial.print("Timer0 Index = ");
  Serial.println(tindex);

  if(!audio_timer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, rate, 0.0f, timer0_callback)){
    return false;
  }

  if (!audio_timer.setup_overflow_irq()){
    return false;
  }

  if (!audio_timer.open()){
    return false;
  }

  if (!audio_timer.start()){
    return false;
  }
  return true;
}

// callback method used by timer1.  ADC Period Measurement
uint8_t timer1_tog = 0;
void timer1_callback(timer_callback_args_t __attribute((unused)) *p_args) {

  if (timer1_tog) {
    digitalWrite(D1, HIGH);
    timer1_tog = 0;
  } else {
    digitalWrite(D1, LOW);
    timer1_tog = 1;
  }

}

bool beginTimer1(float rate) {
  uint8_t timer_type = GPT_TIMER;
  int8_t tindex = FspTimer::get_available_timer(timer_type);
  if (tindex < 0){
    tindex = FspTimer::get_available_timer(timer_type, true);
  }
  if (tindex < 0){
    return false;
  }

  FspTimer::force_use_of_pwm_reserved_timer();
  Serial.print("Timer1 Index = ");
  Serial.println(tindex);


  if(!audio_timer.begin(TIMER_MODE_PERIODIC, timer_type, tindex, rate, 0.0f, timer1_callback)){
    return false;
  }

  if (!audio_timer.setup_overflow_irq()){
    return false;
  }

  if (!audio_timer.open()){
    return false;
  }

  if (!audio_timer.start()){
    return false;
  }
  return true;
}

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


/******************************************************/
//                                                    //
//                  Setup                             //
//                                                    //
/******************************************************/
void setup() {

  Serial.begin(115200);
  while (!Serial) {}   // This line stops script until serial monitor attached
  beginTimer0(3840);     
  beginTimer1(10000);    

  Wire.begin();         
  pinMode(D0, OUTPUT); 
  pinMode(D1, OUTPUT);  


}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void loop() {
  
}

The problem with the FSP code is that it's all pre-compiled and you can't go look to see what it actually does.

I've been going bare metal registers with the timers and have been having a lot more success that way.

Thanks, I haven't gone down the register poking route but I will take a look at the Renesas documentation some more. I did find FspTimer.cpp/h in C:\Users\gjacobs\AppData\Local\Arduino15\packages\arduino\hardware\renesas_uno\1.0.5\cores\arduino.

I will look for examples to get to the underlying processor regs

Yes, but if you keep chasing function calls down you eventually run into libfsp.a and you can't go any further.

fsp/ra/fsp/src at master · renesas/fsp · GitHub ?

I thought so too, but apparently we're getting a pared down version of that. I've run into a few places, the CAC for sure, that weren't in the code we have.

Ah. Yeah. Presumably that is the source for everything that is in the Arduino libfsp, but the Arduino library doesn't contain everything in the Renesas fsp library. For better or worse.

/usr/local/gcc-arm-none-eabi-10.3-2021.07/bin/arm-none-eabi-ar -t ./variants/MINIMA/libs/libfsp.a
rm_vee_flash.o
r_wdt.o
r_usb_pcdc_driver.o
r_usb_creg_abs.o
r_usb_creg_access.o
r_usb_creg_access.o
r_usb_dma.o
r_usb_hostelectrical.o
r_usb_hreg_abs.o
r_usb_hreg_access.o
r_usb_mcu.o
r_usb_preg_abs.o
r_usb_preg_access.o
r_usb_cdataio.o
r_usb_clibusbip.o
r_usb_cstd_rtos.o
r_usb_hbc.o
r_usb_hcontrolrw.o
r_usb_hdriver.o
r_usb_hhubsys.o
r_usb_hintfifo.o
r_usb_hinthandler_usbip0.o
r_usb_hinthandler_usbip1.o
r_usb_hlibusbip.o
r_usb_hmanager.o
r_usb_hscheduler.o
r_usb_hsignal.o
r_usb_hstdfunction.o
r_usb_pbc.o
r_usb_pcontrolrw.o
r_usb_pdriver.o
r_usb_pintfifo.o
r_usb_pinthandler_usbip0.o
r_usb_plibusbip.o
r_usb_psignal.o
r_usb_pstdfunction.o
r_usb_pstdrequest.o
r_usb_basic.o
r_spi.o
r_sci_uart.o
r_sci_spi.o
r_sci_i2c.o
<bunch of numbered sce (crtpto) functions, like hw_sce_func207.o, hw_sce_p00.o)
hw_sce_subprc01.o
hw_sce_subprc02.o
s_flash.o
r_sce_adapt.o
r_rtc.o
r_lpm.o
r_kint.o
r_ioport.o
r_iic_slave.o
r_iic_master.o
r_icu.o
r_gpt.o
r_flash_lp.o
r_elc.o
r_dtc.o
r_doc.o
r_dmac.o
r_dac.o
r_cgc.o
r_can.o
r_agt.o
r_adc.o
bsp_clocks.o
bsp_common.o
bsp_delay.o
bsp_group_irq.o
bsp_guard.o
bsp_io.o
bsp_irq.o
bsp_register_protection.o
bsp_rom_registers.o
bsp_sbrk.o
bsp_security.o
startup.o
system.o

My near term solution put both my timer functions into one timer callback and run at the higher timer frequency. Presumably the callback is effectively an ISR and its not good that I'm putting all that processing into an interrupt. Previous Arduinos had robust Timer API support, hope that will get added in the near future. Will also look at the RA4 register interface.
Thanks!

For what it is worth, I played with the timer code awhile ago trying to get the RC Servo library to work properly on these boards. I ran into issues where I wanted to change the interval on the fly and at the time the released code, only allowed you to set the new interval, such that it was buffered and as such would not happen until the current period completed and timer reset.

At first I did all of the work in the Servo library, but then was asked to migrate some of it into the layer above the FSP code, which was merged in awhile ago.

The Servo code was finally merged yesterday :smiley:
arduino-libraries/Servo: Servo Library for Arduino (github.com)

Not sure when they will create a new release... But at least it is there.

I got back to my timer issue. The problem was mine. I needed to declare two timers FspTimer audio_timer, and FspTimer audio_timer1 Timers work fine, tried mixing AGT and GPT timers worked fine.