comejv commented on issue #16762: URL: https://github.com/apache/nuttx/issues/16762#issuecomment-3161520338
I've got it working how I want by bypassing the stm32_capture_lowerhalf.c driver. Here's what I'm doing to get timer capture on 4 channels of timer 4: ```c /* Per-channel state */ struct chstate { volatile uint32_t last; volatile uint32_t delta; }; /* Global state for our 4-channel capture */ static struct { struct stm32_cap_dev_s *dev; struct chstate cs[CH_COUNT]; } gcap4; /* Single ISR to handle all four CCx interrupts */ static int capture4_isr(int irq, void *context, void *arg) { uint32_t flags = STM32_CAP_GETFLAGS(gcap4.dev); /* Acknowledge *all* CCxIF bits */ STM32_CAP_ACKFLAGS(gcap4.dev, flags); for (int i = 0; i < CH_COUNT; i++) { uint8_t ch = i + 1; uint32_t mask = STM32_CAP_FLAG_IRQ_CH(ch); if (flags & mask) { uint32_t now = STM32_CAP_GETCAPTURE(gcap4.dev, ch); uint32_t diff = (now - gcap4.cs[i].last) & CAP_MAXCNT; gcap4.cs[i].last = now; gcap4.cs[i].delta = diff; } } return OK; } int capture4_init(void) { struct stm32_cap_dev_s *dev; int ch, ret; /* 1) Bring up TIM4, channel=1 is only used to select the peripheral. */ dev = stm32_cap_init(CAP_TIMER, 1); if (!dev) { syslog(LOG_ERR, "capture4: stm32_cap_init failed"); return -ENODEV; } /* 2) Free‐running internal clock, no prescaler */ STM32_CAP_SETSMC(dev, STM32_CAP_SMS_INT); ret = STM32_CAP_SETCLOCK(dev, CAP_CLOCK_HZ, CAP_MAXCNT); if (ret < 0) { syslog(LOG_ERR, "capture4: setclock failed: %d", ret); return ret; } /* 3) Configure CC1..CC4 → TI1, rising‐edge, no filter, no prescale */ for (ch = 1; ch <= CH_COUNT; ch++) { stm32_cap_ch_cfg_t cfg = STM32_CAP_MAPPED_TI1 // | STM32_CAP_INPSC_NO // | STM32_CAP_FILTER_NO // | STM32_CAP_EDGE_RISING; ret = STM32_CAP_SETCHANNEL(dev, ch, cfg); if (ret < 0) { syslog(LOG_ERR, "capture4: SETCHANNEL ch=%d failed: %d (check GPIO_TIM4_CH%dIN)", ch, ret, ch); } } /* 4) Hook our single ISR and enable all 4 CCx interrupts */ ret = STM32_CAP_SETISR(dev, capture4_isr, NULL); if (ret < 0) { syslog(LOG_ERR, "capture4: SETISR failed: %d", ret); } STM32_CAP_ENABLEINT(dev, STM32_CAP_FLAG_IRQ_CH(1) | STM32_CAP_FLAG_IRQ_CH(2) | STM32_CAP_FLAG_IRQ_CH(3) | STM32_CAP_FLAG_IRQ_CH(4), true); gcap4.dev = dev; return OK; } ``` The only modification I needed in the existing driver that I ported (currently in #16809) was this patch in `arch/arm/src/stm32h7/stm32_capture.c` to initialize the channel properly: ```patch @@ -1539,7 +1575,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) +struct stm32_cap_dev_s *stm32_cap_init(int timer, uint8_t channel) { const struct stm32_cap_priv_s *priv = stm32_cap_get_priv(timer); uint32_t gpio; @@ -1548,7 +1584,7 @@ struct stm32_cap_dev_s *stm32_cap_init(int timer) { stm32_cap_set_rcc(priv, true); - gpio = stm32_cap_gpio(priv, STM32_CAP_CHANNEL_COUNTER); + gpio = stm32_cap_gpio(priv, channel); if (gpio) { stm32_configgpio(gpio); @@ -1562,7 +1598,7 @@ struct stm32_cap_dev_s *stm32_cap_init(int timer) return (struct stm32_cap_dev_s *)priv; } ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org