drivers: pwm: mcux_ftm: support multiple interrupts
Rework the interrupt handlers of the FTM driver to support SoCs on which FTM channels and overflow are routed through individual interrupts, as opposed to a single OR'ed interrupt. Signed-off-by: Manuel Argüelles <manuel.arguelles@nxp.com>
This commit is contained in:
parent
747aacbf1c
commit
35e267d649
1 changed files with 68 additions and 8 deletions
|
@ -383,11 +383,24 @@ static void mcux_ftm_capture_second_edge(const struct device *dev, uint32_t chan
|
|||
}
|
||||
}
|
||||
|
||||
static void mcux_ftm_isr(const struct device *dev)
|
||||
static bool mcux_ftm_handle_overflow(const struct device *dev)
|
||||
{
|
||||
const struct mcux_ftm_config *config = dev->config;
|
||||
struct mcux_ftm_data *data = dev->data;
|
||||
bool overflow = false;
|
||||
|
||||
if (FTM_GetStatusFlags(config->base) & kFTM_TimeOverflowFlag) {
|
||||
data->overflows++;
|
||||
FTM_ClearStatusFlags(config->base, kFTM_TimeOverflowFlag);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void mcux_ftm_irq_handler(const struct device *dev, uint32_t chan_start, uint32_t chan_end)
|
||||
{
|
||||
const struct mcux_ftm_config *config = dev->config;
|
||||
bool overflow;
|
||||
uint32_t flags;
|
||||
uint32_t irqs;
|
||||
uint16_t cnt;
|
||||
|
@ -397,13 +410,9 @@ static void mcux_ftm_isr(const struct device *dev)
|
|||
irqs = FTM_GetEnabledInterrupts(config->base);
|
||||
cnt = config->base->CNT;
|
||||
|
||||
if (flags & kFTM_TimeOverflowFlag) {
|
||||
data->overflows++;
|
||||
overflow = true;
|
||||
FTM_ClearStatusFlags(config->base, kFTM_TimeOverflowFlag);
|
||||
}
|
||||
overflow = mcux_ftm_handle_overflow(dev);
|
||||
|
||||
for (ch = 0; ch < MAX_CHANNELS; ch++) {
|
||||
for (ch = chan_start; ch < chan_end; ch++) {
|
||||
if ((flags & BIT(ch)) && (irqs & BIT(ch))) {
|
||||
if (ch & 1) {
|
||||
mcux_ftm_capture_second_edge(dev, ch, cnt, overflow);
|
||||
|
@ -496,6 +505,14 @@ static const struct pwm_driver_api mcux_ftm_driver_api = {
|
|||
#define TO_FTM_PRESCALE_DIVIDE(val) _DO_CONCAT(kFTM_Prescale_Divide_, val)
|
||||
|
||||
#ifdef CONFIG_PWM_CAPTURE
|
||||
#if IS_EQ(DT_NUM_IRQS(DT_DRV_INST(0)), 1)
|
||||
static void mcux_ftm_isr(const struct device *dev)
|
||||
{
|
||||
const struct mcux_ftm_config *cfg = dev->config;
|
||||
|
||||
mcux_ftm_irq_handler(dev, 0, cfg->channel_count);
|
||||
}
|
||||
|
||||
#define FTM_CONFIG_FUNC(n) \
|
||||
static void mcux_ftm_config_func_##n(const struct device *dev) \
|
||||
{ \
|
||||
|
@ -503,6 +520,49 @@ static void mcux_ftm_config_func_##n(const struct device *dev) \
|
|||
mcux_ftm_isr, DEVICE_DT_INST_GET(n), 0); \
|
||||
irq_enable(DT_INST_IRQN(n)); \
|
||||
}
|
||||
#else /* Multiple interrupts */
|
||||
#define FTM_ISR_FUNC_NAME(suffix) _DO_CONCAT(mcux_ftm_isr_, suffix)
|
||||
#define FTM_ISR_FUNC(chan_start, chan_end) \
|
||||
static void mcux_ftm_isr_##chan_start##_##chan_end(const struct device *dev) \
|
||||
{ \
|
||||
mcux_ftm_irq_handler(dev, chan_start, chan_end + 1); \
|
||||
}
|
||||
|
||||
#define FTM_ISR_CONFIG(node_id, prop, idx) \
|
||||
do { \
|
||||
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), \
|
||||
DT_IRQ_BY_IDX(node_id, idx, priority), \
|
||||
FTM_ISR_FUNC_NAME(DT_STRING_TOKEN_BY_IDX(node_id, prop, idx)), \
|
||||
DEVICE_DT_GET(node_id), \
|
||||
0); \
|
||||
irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq)); \
|
||||
} while (false);
|
||||
|
||||
#define FTM_CONFIG_FUNC(n) \
|
||||
static void mcux_ftm_config_func_##n(const struct device *dev) \
|
||||
{ \
|
||||
DT_INST_FOREACH_PROP_ELEM(n, interrupt_names, FTM_ISR_CONFIG) \
|
||||
}
|
||||
|
||||
#if DT_INST_IRQ_HAS_NAME(0, overflow)
|
||||
static void mcux_ftm_isr_overflow(const struct device *dev)
|
||||
{
|
||||
mcux_ftm_handle_overflow(dev);
|
||||
}
|
||||
#endif
|
||||
#if DT_INST_IRQ_HAS_NAME(0, 0_1)
|
||||
FTM_ISR_FUNC(0, 1)
|
||||
#endif
|
||||
#if DT_INST_IRQ_HAS_NAME(0, 2_3)
|
||||
FTM_ISR_FUNC(2, 3)
|
||||
#endif
|
||||
#if DT_INST_IRQ_HAS_NAME(0, 4_5)
|
||||
FTM_ISR_FUNC(4, 5)
|
||||
#endif
|
||||
#if DT_INST_IRQ_HAS_NAME(0, 6_7)
|
||||
FTM_ISR_FUNC(6, 7)
|
||||
#endif
|
||||
#endif /* IS_EQ(DT_NUM_IRQS(DT_DRV_INST(0)), 1) */
|
||||
#define FTM_CFG_CAPTURE_INIT(n) \
|
||||
.irq_config_func = mcux_ftm_config_func_##n
|
||||
#define FTM_INIT_CFG(n) FTM_DECLARE_CFG(n, FTM_CFG_CAPTURE_INIT(n))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue