arch/stm32h7: Fix timer capture

This patch fixes an incorrect call to stm32_cap_initialize() in
stm32_bringup.c: the call was made without the channel parameter.
Instead of adding the channel in the call, the channel is selected by
stm32_cap_gpio() (first available channel).

This patch also fixes incorrect driver registration in
drivers/timers/capture.c: the driver was registered with the wrong
name (/dev/cap -> /dev/capture). Also added more error checking in
cap_register_multiple().

Signed-off-by: Côme VINCENT <44554692+comejv@users.noreply.github.com>
This commit is contained in:
Côme VINCENT 2025-08-11 12:35:55 -04:00 committed by Xiang Xiao
parent e33a4c71b3
commit a4b17a2d14
4 changed files with 54 additions and 11 deletions

View file

@ -217,6 +217,32 @@ static inline
uint32_t stm32_cap_gpio(const struct stm32_cap_priv_s *priv,
int channel)
{
if (channel < 0) /* Special case: return first available channel */
{
uint32_t gpio;
/* Try counter channel first */
gpio = stm32_cap_gpio(priv, STM32_CAP_CHANNEL_COUNTER);
if (gpio)
{
return gpio;
}
/* Then try channels 1..4 */
for (int ch = 1; ch <= 4; ch++)
{
gpio = stm32_cap_gpio(priv, ch);
if (gpio)
{
return gpio;
}
}
return 0; /* None found */
}
switch (priv->base)
{
#ifdef CONFIG_STM32H7_TIM1_CAP
@ -1578,7 +1604,7 @@ static inline const struct stm32_cap_priv_s * stm32_cap_get_priv(int timer)
* Public Function - Initialization
****************************************************************************/
struct stm32_cap_dev_s *stm32_cap_init(int timer, uint8_t channel)
struct stm32_cap_dev_s *stm32_cap_init(int timer)
{
const struct stm32_cap_priv_s *priv = stm32_cap_get_priv(timer);
uint32_t gpio;
@ -1587,7 +1613,7 @@ struct stm32_cap_dev_s *stm32_cap_init(int timer, uint8_t channel)
{
stm32_cap_set_rcc(priv, true);
gpio = stm32_cap_gpio(priv, channel);
gpio = stm32_cap_gpio(priv, -1);
if (gpio)
{
stm32_configgpio(gpio);
@ -1601,7 +1627,7 @@ struct stm32_cap_dev_s *stm32_cap_init(int timer, uint8_t channel)
return (struct stm32_cap_dev_s *)priv;
}
int stm32_cap_deinit(struct stm32_cap_dev_s * dev, uint8_t channel)
int stm32_cap_deinit(struct stm32_cap_dev_s * dev)
{
const struct stm32_cap_priv_s *priv = (struct stm32_cap_priv_s *)dev;
uint32_t gpio;
@ -1612,7 +1638,7 @@ int stm32_cap_deinit(struct stm32_cap_dev_s * dev, uint8_t channel)
stm32_modifyreg16(priv, STM32_BTIM_CR1_OFFSET, ATIM_CR1_CEN, 0);
gpio = stm32_cap_gpio(priv, channel);
gpio = stm32_cap_gpio(priv, -1);
if (gpio)
{
stm32_unconfiggpio(gpio);

View file

@ -204,11 +204,11 @@ struct stm32_cap_ops_s
/* Power-up timer and get its structure */
struct stm32_cap_dev_s *stm32_cap_init(int timer, uint8_t channel);
struct stm32_cap_dev_s *stm32_cap_init(int timer);
/* Power-down timer, mark it as unused */
int stm32_cap_deinit(struct stm32_cap_dev_s *dev, uint8_t channel);
int stm32_cap_deinit(struct stm32_cap_dev_s *dev);
/****************************************************************************
* Name: stm32_cap_initialize
@ -228,7 +228,7 @@ int stm32_cap_deinit(struct stm32_cap_dev_s *dev, uint8_t channel);
****************************************************************************/
#ifdef CONFIG_CAPTURE
struct cap_lowerhalf_s *stm32_cap_initialize(int timer, uint8_t channel);
struct cap_lowerhalf_s *stm32_cap_initialize(int timer);
#endif
#undef EXTERN

View file

@ -576,7 +576,7 @@ struct cap_lowerhalf_s *stm32_cap_initialize(int timer)
/* Initialize the elements of lower half state structure */
lower->started = false;
lower->cap = stm32_cap_init(timer, lower->channel);
lower->cap = stm32_cap_init(timer);
if (lower->cap == NULL)
{

View file

@ -472,17 +472,34 @@ int cap_register_multiple(FAR const char *devpath,
FAR struct cap_lowerhalf_s **lower,
int n)
{
char fullpath[16];
char fullpath[32];
int ret;
if (n < 1)
if (!devpath || !lower || n < 1)
{
return -EINVAL;
}
size_t devlen = strlen(devpath);
if (devlen == 0 || devlen > sizeof(fullpath) - 2)
{
return -ENAMETOOLONG;
}
for (int i = 0; i < n; i++)
{
snprintf(fullpath, sizeof(fullpath), "%s%d", devpath, i);
int written = snprintf(fullpath, sizeof(fullpath), "%s%d", devpath, i);
if (written < 0)
{
return -EIO;
}
if ((size_t)written >= sizeof(fullpath))
{
return -ENAMETOOLONG;
}
ret = cap_register(fullpath, lower[i]);
if (ret < 0)
{