summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCYFS <[email protected]>2026-08-26 10:27:33 +0800
committerRbb666 <[email protected]>2026-09-09 10:33:04 +0800
commitd7ea2bce99c4dc1e63b28638674e1b94d1791417 (patch)
treebdf69608a7af2e9412a0836aa088c8461f2ffc75
parent6664825546a945dc6076d433681b9887648dd97d (diff)
[bsp/renesas][drivers] Read PWM settings from GPT registers
-rw-r--r--bsp/renesas/libraries/HAL_Drivers/drivers/drv_pwm.c116
1 files changed, 94 insertions, 22 deletions
diff --git a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_pwm.c b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_pwm.c
index 6564bff2f7..b615f9285c 100644
--- a/bsp/renesas/libraries/HAL_Drivers/drivers/drv_pwm.c
+++ b/bsp/renesas/libraries/HAL_Drivers/drivers/drv_pwm.c
@@ -65,28 +65,75 @@ static struct ra_pwm ra6m4_pwm_obj[BSP_PWMS_NUM] =
#endif
};
-#ifdef SOC_SERIES_R9A07G0
- #define FSP_PRIV_CLOCK FSP_PRIV_CLOCK_PCLKGPTL
-#else
- #define FSP_PRIV_CLOCK FSP_PRIV_CLOCK_PCLKD
-#endif
+#define RA_PWM_GTCCRC_INDEX 2U
+#define RA_PWM_GTCCRE_INDEX 3U
+#define RA_PWM_DUTY_MODE_REGISTER 0U
+#define RA_PWM_DUTY_MODE_0_PERCENT 2U
+#define RA_PWM_DUTY_MODE_100_PERCENT 3U
/* Convert the raw PWM period counts into ns */
-static rt_uint32_t _convert_counts_ns(uint32_t source_div, uint32_t raw)
+static rt_uint32_t _convert_counts_ns(uint32_t clock_frequency, uint32_t raw)
{
- uint32_t pclkd_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK) >> source_div;
- uint32_t ns = (uint32_t)(((uint64_t)raw * 1000000000ULL) / pclkd_freq_hz);
+ uint32_t ns = (uint32_t)(((uint64_t)raw * 1000000000ULL) / clock_frequency);
return ns;
}
/* Convert ns into raw PWM period counts */
-static rt_uint32_t _convert_ns_counts(uint32_t source_div, uint32_t raw)
+static rt_uint32_t _convert_ns_counts(uint32_t clock_frequency, uint32_t raw)
{
- uint32_t pclkd_freq_hz = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK) >> source_div;
- uint32_t counts = (uint32_t)(((uint64_t)raw * (uint64_t)pclkd_freq_hz) / 1000000000ULL);
+ uint32_t counts = (uint32_t)(((uint64_t)raw * (uint64_t)clock_frequency) / 1000000000ULL);
return counts;
}
+static rt_err_t drv_pwm_pin_pulse_counts_get(struct ra_pwm *device,
+ uint32_t period_counts,
+ gpt_io_pin_t pin,
+ uint32_t *pulse_counts)
+{
+ uint32_t duty_mode;
+ uint32_t gtior;
+ uint32_t compare_index;
+ rt_bool_t first_level_low;
+
+ if (pin == GPT_IO_PIN_GTIOCA)
+ {
+ duty_mode = device->g_ctrl->p_reg->GTUDDTYC_b.OADTY;
+ gtior = device->g_ctrl->p_reg->GTIOR_b.GTIOA;
+ compare_index = RA_PWM_GTCCRC_INDEX;
+ }
+ else
+ {
+ duty_mode = device->g_ctrl->p_reg->GTUDDTYC_b.OBDTY;
+ gtior = device->g_ctrl->p_reg->GTIOR_b.GTIOB;
+ compare_index = RA_PWM_GTCCRE_INDEX;
+ }
+
+ if (duty_mode == RA_PWM_DUTY_MODE_REGISTER)
+ {
+ *pulse_counts = device->g_ctrl->p_reg->GTCCR[compare_index] + 1U;
+ return RT_EOK;
+ }
+ if (duty_mode != RA_PWM_DUTY_MODE_0_PERCENT &&
+ duty_mode != RA_PWM_DUTY_MODE_100_PERCENT)
+ {
+ return -RT_ERROR;
+ }
+
+ /* FSP represents 0% and 100% with a forced output level. */
+ first_level_low = (gtior & 0xCU) == 0x4U;
+ if ((first_level_low && duty_mode == RA_PWM_DUTY_MODE_0_PERCENT) ||
+ (!first_level_low && duty_mode == RA_PWM_DUTY_MODE_100_PERCENT))
+ {
+ *pulse_counts = period_counts;
+ }
+ else
+ {
+ *pulse_counts = 0U;
+ }
+
+ return RT_EOK;
+}
+
/* PWM_CMD_ENABLE or PWM_CMD_DISABLE */
static rt_err_t drv_pwm_enable(struct ra_pwm *device,
@@ -112,13 +159,34 @@ static rt_err_t drv_pwm_get(struct ra_pwm *device,
struct rt_pwm_configuration *configuration)
{
timer_info_t info;
- if (R_GPT_InfoGet(device->g_ctrl, &info) != FSP_SUCCESS)
+ uint32_t period_counts;
+ uint32_t pulse_counts_a;
+ uint32_t pulse_counts_b;
+
+ if (device->g_cfg->mode != TIMER_MODE_PWM)
+ {
+ return -RT_ENOSYS;
+ }
+ if (R_GPT_InfoGet(device->g_ctrl, &info) != FSP_SUCCESS ||
+ info.clock_frequency == 0U)
+ {
return -RT_ERROR;
+ }
+
+ period_counts = device->g_ctrl->p_reg->GTPBR + 1U;
+ if (drv_pwm_pin_pulse_counts_get(device, period_counts,
+ GPT_IO_PIN_GTIOCA, &pulse_counts_a) != RT_EOK ||
+ drv_pwm_pin_pulse_counts_get(device, period_counts,
+ GPT_IO_PIN_GTIOCB, &pulse_counts_b) != RT_EOK ||
+ pulse_counts_a != pulse_counts_b)
+ {
+ return -RT_ERROR;
+ }
configuration->pulse =
- _convert_counts_ns(device->g_cfg->source_div, device->g_cfg->duty_cycle_counts);
+ _convert_counts_ns(info.clock_frequency, pulse_counts_a);
configuration->period =
- _convert_counts_ns(device->g_cfg->source_div, info.period_counts);
+ _convert_counts_ns(info.clock_frequency, period_counts);
configuration->channel = device->g_cfg->channel;
return RT_EOK;
@@ -128,18 +196,21 @@ static rt_err_t drv_pwm_get(struct ra_pwm *device,
static rt_err_t drv_pwm_set(struct ra_pwm *device,
struct rt_pwm_configuration *conf)
{
+ timer_info_t info;
uint32_t counts;
fsp_err_t fsp_erra;
fsp_err_t fsp_errb;
- rt_err_t rt_err;
uint32_t pulse;
uint32_t period;
- struct rt_pwm_configuration orig_conf;
- rt_err = drv_pwm_get(device, &orig_conf);
- if (rt_err != RT_EOK)
+ if (device->g_cfg->mode != TIMER_MODE_PWM)
+ {
+ return -RT_ENOSYS;
+ }
+ if (R_GPT_InfoGet(device->g_ctrl, &info) != FSP_SUCCESS ||
+ info.clock_frequency == 0U)
{
- return rt_err;
+ return -RT_ERROR;
}
/* Pulse cannot last longer than period. */
@@ -147,9 +218,10 @@ static rt_err_t drv_pwm_set(struct ra_pwm *device,
pulse = (period >= conf->pulse) ? conf->pulse : period;
/* Not to set period again if it's not changed. */
- if (period != orig_conf.period)
+ if (period != _convert_counts_ns(info.clock_frequency,
+ device->g_ctrl->p_reg->GTPBR + 1U))
{
- counts = _convert_ns_counts(device->g_cfg->source_div, period);
+ counts = _convert_ns_counts(info.clock_frequency, period);
fsp_erra = R_GPT_PeriodSet(device->g_ctrl, counts);
if (fsp_erra != FSP_SUCCESS)
{
@@ -158,7 +230,7 @@ static rt_err_t drv_pwm_set(struct ra_pwm *device,
}
/* Two pins of a channel will not be separated. */
- counts = _convert_ns_counts(device->g_cfg->source_div, pulse);
+ counts = _convert_ns_counts(info.clock_frequency, pulse);
fsp_erra = R_GPT_DutyCycleSet(device->g_ctrl, counts, GPT_IO_PIN_GTIOCA);
fsp_errb = R_GPT_DutyCycleSet(device->g_ctrl, counts, GPT_IO_PIN_GTIOCB);
if (fsp_erra != FSP_SUCCESS || fsp_errb != FSP_SUCCESS)