@@ -383,11 +383,24 @@ static void mcux_ftm_capture_second_edge(const struct device *dev, uint32_t chan
383
383
}
384
384
}
385
385
386
- static void mcux_ftm_isr (const struct device * dev )
386
+ static bool mcux_ftm_handle_overflow (const struct device * dev )
387
387
{
388
388
const struct mcux_ftm_config * config = dev -> config ;
389
389
struct mcux_ftm_data * data = dev -> data ;
390
- bool overflow = false;
390
+
391
+ if (FTM_GetStatusFlags (config -> base ) & kFTM_TimeOverflowFlag ) {
392
+ data -> overflows ++ ;
393
+ FTM_ClearStatusFlags (config -> base , kFTM_TimeOverflowFlag );
394
+ return true;
395
+ }
396
+
397
+ return false;
398
+ }
399
+
400
+ static void mcux_ftm_irq_handler (const struct device * dev , uint32_t chan_start , uint32_t chan_end )
401
+ {
402
+ const struct mcux_ftm_config * config = dev -> config ;
403
+ bool overflow ;
391
404
uint32_t flags ;
392
405
uint32_t irqs ;
393
406
uint16_t cnt ;
@@ -397,13 +410,9 @@ static void mcux_ftm_isr(const struct device *dev)
397
410
irqs = FTM_GetEnabledInterrupts (config -> base );
398
411
cnt = config -> base -> CNT ;
399
412
400
- if (flags & kFTM_TimeOverflowFlag ) {
401
- data -> overflows ++ ;
402
- overflow = true;
403
- FTM_ClearStatusFlags (config -> base , kFTM_TimeOverflowFlag );
404
- }
413
+ overflow = mcux_ftm_handle_overflow (dev );
405
414
406
- for (ch = 0 ; ch < MAX_CHANNELS ; ch ++ ) {
415
+ for (ch = chan_start ; ch < chan_end ; ch ++ ) {
407
416
if ((flags & BIT (ch )) && (irqs & BIT (ch ))) {
408
417
if (ch & 1 ) {
409
418
mcux_ftm_capture_second_edge (dev , ch , cnt , overflow );
@@ -496,13 +505,64 @@ static const struct pwm_driver_api mcux_ftm_driver_api = {
496
505
#define TO_FTM_PRESCALE_DIVIDE (val ) _DO_CONCAT(kFTM_Prescale_Divide_, val)
497
506
498
507
#ifdef CONFIG_PWM_CAPTURE
508
+ #if IS_EQ (DT_NUM_IRQS (DT_DRV_INST (0 )), 1 )
509
+ static void mcux_ftm_isr (const struct device * dev )
510
+ {
511
+ const struct mcux_ftm_config * cfg = dev -> config ;
512
+
513
+ mcux_ftm_irq_handler (dev , 0 , cfg -> channel_count );
514
+ }
515
+
499
516
#define FTM_CONFIG_FUNC (n ) \
500
517
static void mcux_ftm_config_func_##n(const struct device *dev) \
501
518
{ \
502
519
IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), \
503
520
mcux_ftm_isr, DEVICE_DT_INST_GET(n), 0); \
504
521
irq_enable(DT_INST_IRQN(n)); \
505
522
}
523
+ #else /* Multiple interrupts */
524
+ #define FTM_ISR_FUNC_NAME (suffix ) _DO_CONCAT(mcux_ftm_isr_, suffix)
525
+ #define FTM_ISR_FUNC (chan_start , chan_end ) \
526
+ static void mcux_ftm_isr_##chan_start##_##chan_end(const struct device *dev) \
527
+ { \
528
+ mcux_ftm_irq_handler(dev, chan_start, chan_end + 1); \
529
+ }
530
+
531
+ #define FTM_ISR_CONFIG (node_id , prop , idx ) \
532
+ do { \
533
+ IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
534
+ DT_IRQ_BY_IDX(node_id, idx, priority), \
535
+ FTM_ISR_FUNC_NAME(DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), \
536
+ DEVICE_DT_GET(node_id), \
537
+ 0); \
538
+ irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \
539
+ } while (false);
540
+
541
+ #define FTM_CONFIG_FUNC (n ) \
542
+ static void mcux_ftm_config_func_##n(const struct device *dev) \
543
+ { \
544
+ DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, FTM_ISR_CONFIG) \
545
+ }
546
+
547
+ #if DT_INST_IRQ_HAS_NAME (0 , overflow )
548
+ static void mcux_ftm_isr_overflow (const struct device * dev )
549
+ {
550
+ mcux_ftm_handle_overflow (dev );
551
+ }
552
+ #endif
553
+ #if DT_INST_IRQ_HAS_NAME (0 , 0 _1 )
554
+ FTM_ISR_FUNC (0 , 1 )
555
+ #endif
556
+ #if DT_INST_IRQ_HAS_NAME (0 , 2 _3 )
557
+ FTM_ISR_FUNC (2 , 3 )
558
+ #endif
559
+ #if DT_INST_IRQ_HAS_NAME (0 , 4 _5 )
560
+ FTM_ISR_FUNC (4 , 5 )
561
+ #endif
562
+ #if DT_INST_IRQ_HAS_NAME (0 , 6 _7 )
563
+ FTM_ISR_FUNC (6 , 7 )
564
+ #endif
565
+ #endif /* IS_EQ(DT_NUM_IRQS(DT_DRV_INST(0)), 1) */
506
566
#define FTM_CFG_CAPTURE_INIT (n ) \
507
567
.irq_config_func = mcux_ftm_config_func_##n
508
568
#define FTM_INIT_CFG (n ) FTM_DECLARE_CFG(n, FTM_CFG_CAPTURE_INIT(n))
0 commit comments