Hello all,
I'm trying to handle a quadrature encoder without the Encoder library and interrupts on the NANO R4.
GPT helped me a lot, and it seems it should be possible - but it's not working - the count stays at zero.
Looking at https://www.renesas.com/en/document/dst/ra4m1-group-datasheet page 23 and ArduinoCore-renesas/variants/NANOR4/variant.cpp at main · arduino/ArduinoCore-renesas · GitHub I compiled the following mappings:
// G0A P107 D7
// G0B P106 D6~
// G1A P105 D2 P109 11~
// G1B P104 D3~ P110 12
// G2A P103 D4
// G2B P102 D5~
// G3A P111 D13
// G3B P112 D10~
// G4A P302 D1
// G4B P301 D0
// G5A P101 A4/SDA
// G5B P100 A5/SCL
// G6A P411 LED_BU
// G6B P410 LED_GN
// G7A P304 D8
// G7B P303 D9~
Here is a minimal example. For testing, all events are placed in the count_up not to worry about proper "waveforms" when manually touching the pins. I tried GTIOC0 with pins D7 and D6 and GTIOC2 with pins D4 and D5.
#include "hal_data.h"
#include <FspTimer.h>
//
gpt_instance_ctrl_t gpt_ctrl;
timer_cfg_t gpt_cfg;
gpt_extended_cfg_t gpt_ext;
// timer_instance_t gpt_timer;
//
void setup()
{
// Basic setup
Serial.begin(115200);
delay(1000);
// Encoders
{
Serial.println(R_PFS->PORT[1].PIN[3].PmnPFS, HEX);
Serial.println(R_PFS->PORT[1].PIN[2].PmnPFS, HEX);
pinMode(4, INPUT);
pinMode(5, INPUT);
R_IOPORT_PinCfg(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_03, //
IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_GPT2 |//
IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PULLUP_ENABLE);
R_IOPORT_PinCfg(&g_ioport_ctrl, BSP_IO_PORT_01_PIN_02, //
IOPORT_CFG_PERIPHERAL_PIN | IOPORT_PERIPHERAL_GPT2 |//
IOPORT_CFG_PORT_DIRECTION_INPUT | IOPORT_CFG_PULLUP_ENABLE);
memset(&gpt_cfg, 0, sizeof(gpt_cfg));
memset(&gpt_ext, 0, sizeof(gpt_ext));
gpt_cfg.mode = TIMER_MODE_PERIODIC;// TIMER_MODE_TRIANGLE_WAVE_ASYMMETRIC_PWM;
gpt_cfg.period_counts = 0xFFFFFFFF;
gpt_cfg.source_div = TIMER_SOURCE_DIV_1;
gpt_cfg.channel = 2;// GPT2
gpt_cfg.p_callback = NULL;
// gpt_ext.gtior_setting.gtior_b.gtioa = GPT_GTIO_PIN_CFG_INPUT;
// gpt_ext.gtior_setting.gtior_b.gtiob = GPT_GTIO_PIN_CFG_INPUT;
// gpt_ext.count_up_source =
// gpt_source_t(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
// GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW);
// gpt_ext.count_down_source =
// gpt_source_t(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
// GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH);
gpt_ext.count_up_source =
gpt_source_t(GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_LOW | GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_HIGH |
GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_HIGH | GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_LOW |
GPT_SOURCE_GTIOCA_RISING_WHILE_GTIOCB_HIGH | GPT_SOURCE_GTIOCA_FALLING_WHILE_GTIOCB_LOW |
GPT_SOURCE_GTIOCB_RISING_WHILE_GTIOCA_LOW | GPT_SOURCE_GTIOCB_FALLING_WHILE_GTIOCA_HIGH);
gpt_cfg.p_extend = &gpt_ext;
R_GPT_Open(&gpt_ctrl, &gpt_cfg);
R_GPT_Start(&gpt_ctrl);
Serial.println(R_PFS->PORT[1].PIN[3].PmnPFS, HEX);
Serial.println(R_PFS->PORT[1].PIN[2].PmnPFS, HEX);
}
}
void loop()
{
timer_status_t status;
R_GPT_StatusGet(&gpt_ctrl, &status);
Serial.println((int32_t)status.counter);
delay(250);
}
Am I missing something obvious? Why is this not working?