drivers: counter: add Andes atcpit100 counter driver
atcpit100 counter driver support 4 32-bit PIT channel, using channel 3 as the default counter. Signed-off-by: Jimmy Zheng <jimmyzhe@andestech.com>
This commit is contained in:
parent
88aa873fbc
commit
a2cc4b702f
|
@ -29,3 +29,4 @@ zephyr_library_sources_ifdef(CONFIG_COUNTER_XLNX_AXI_TIMER counter_xlnx_axi
|
|||
zephyr_library_sources_ifdef(CONFIG_COUNTER_TMR_ESP32 counter_esp32_tmr.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_COUNTER_RTC_ESP32 counter_esp32_rtc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_COUNTER_MICROCHIP_MCP7940N rtc_mcp7940n.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_COUNTER_ANDES_ATCPIT100 counter_andes_atcpit100.c)
|
||||
|
|
|
@ -70,4 +70,6 @@ source "drivers/counter/Kconfig.mcp7940n"
|
|||
|
||||
source "drivers/counter/Kconfig.mcux_ctimer"
|
||||
|
||||
source "drivers/counter/Kconfig.andes_atcpit100"
|
||||
|
||||
endif # COUNTER
|
||||
|
|
12
drivers/counter/Kconfig.andes_atcpit100
Normal file
12
drivers/counter/Kconfig.andes_atcpit100
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Kconfig Andes ATCPIT100 configuration option
|
||||
#
|
||||
# Copyright (c) 2022 Andes Technology Corporation.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config COUNTER_ANDES_ATCPIT100
|
||||
bool "Andes ATCPIT100 PIT driver"
|
||||
default y
|
||||
depends on DT_HAS_ANDESTECH_ATCPIT100_ENABLED
|
||||
help
|
||||
Enable driver for the Andes ATCPIT100 PIT controller.
|
507
drivers/counter/counter_andes_atcpit100.c
Normal file
507
drivers/counter/counter_andes_atcpit100.c
Normal file
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Andes Technology
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/counter.h>
|
||||
#include <string.h>
|
||||
|
||||
#define DT_DRV_COMPAT andestech_atcpit100
|
||||
|
||||
/* register definitions */
|
||||
#define REG_IDR 0x00 /* ID and Revision Reg. */
|
||||
#define REG_CFG 0x10 /* Configuration Reg. */
|
||||
#define REG_INTE 0x14 /* Interrupt Enable Reg. */
|
||||
#define REG_ISTA 0x18 /* Interrupt Status Reg. */
|
||||
#define REG_CHEN 0x1C /* Channel Enable Reg. */
|
||||
#define REG_CTRL0 0x20 /* Channel 0 Control Reg. */
|
||||
#define REG_RELD0 0x24 /* Channel 0 Reload Reg. */
|
||||
#define REG_CNTR0 0x28 /* Channel 0 Counter Reg. */
|
||||
#define REG_CTRL1 0x30 /* Channel 1 Control Reg. */
|
||||
#define REG_RELD1 0x34 /* Channel 1 Reload Reg. */
|
||||
#define REG_CNTR1 0x38 /* Channel 1 Counter Reg. */
|
||||
#define REG_CTRL2 0x40 /* Channel 2 Control Reg. */
|
||||
#define REG_RELD2 0x44 /* Channel 2 Reload Reg. */
|
||||
#define REG_CNTR2 0x48 /* Channel 2 Counter Reg. */
|
||||
#define REG_CTRL3 0x50 /* Channel 3 Control Reg. */
|
||||
#define REG_RELD3 0x54 /* Channel 3 Reload Reg. */
|
||||
#define REG_CNTR3 0x58 /* Channel 3 Counter Reg. */
|
||||
|
||||
#define PIT_BASE (((const struct atcpit100_config *)(dev)->config)->base)
|
||||
#define PIT_INTE(dev) (PIT_BASE + REG_INTE)
|
||||
#define PIT_ISTA(dev) (PIT_BASE + REG_ISTA)
|
||||
#define PIT_CHEN(dev) (PIT_BASE + REG_CHEN)
|
||||
#define PIT_CH_CTRL(dev, ch) (PIT_BASE + REG_CTRL0 + (ch << 4))
|
||||
#define PIT_CH_RELD(dev, ch) (PIT_BASE + REG_RELD0 + (ch << 4))
|
||||
#define PIT_CH_CNTR(dev, ch) (PIT_BASE + REG_CNTR0 + (ch << 4))
|
||||
|
||||
#define CTRL_CH_SRC_PCLK BIT(3)
|
||||
#define CTRL_CH_MODE_32BIT BIT(0)
|
||||
|
||||
#define CHANNEL_NUM (4)
|
||||
#define CH_NUM_PER_COUNTER (CHANNEL_NUM - 1)
|
||||
#define TIMER0_CHANNEL(ch) BIT(((ch) * CHANNEL_NUM))
|
||||
|
||||
typedef void (*atcpit100_cfg_func_t)(void);
|
||||
|
||||
struct atcpit100_config {
|
||||
struct counter_config_info info;
|
||||
uint32_t base;
|
||||
uint32_t divider;
|
||||
uint32_t irq_num;
|
||||
atcpit100_cfg_func_t cfg_func;
|
||||
};
|
||||
|
||||
struct counter_atcpit100_ch_data {
|
||||
counter_alarm_callback_t alarm_callback;
|
||||
void *alarm_user_data;
|
||||
};
|
||||
|
||||
struct atcpit100_data {
|
||||
counter_top_callback_t top_callback;
|
||||
void *top_user_data;
|
||||
uint32_t guard_period;
|
||||
struct k_spinlock lock;
|
||||
struct counter_atcpit100_ch_data ch_data[CH_NUM_PER_COUNTER];
|
||||
};
|
||||
|
||||
static inline uint32_t get_current_tick(const struct device *dev, uint32_t ch)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
uint32_t top, now_cnt;
|
||||
|
||||
/* Preload cycles is reload register + 1 */
|
||||
top = sys_read32(PIT_CH_RELD(dev, ch)) + 1;
|
||||
now_cnt = top - sys_read32(PIT_CH_CNTR(dev, ch));
|
||||
|
||||
return (now_cnt / config->divider);
|
||||
}
|
||||
|
||||
static void atcpit100_irq_handler(void *arg)
|
||||
{
|
||||
struct device *dev = (struct device *)arg;
|
||||
struct atcpit100_data *data = dev->data;
|
||||
counter_alarm_callback_t cb;
|
||||
uint32_t int_status, int_enable, ch_enable, cur_ticks;
|
||||
uint8_t i;
|
||||
|
||||
ch_enable = sys_read32(PIT_CHEN(dev));
|
||||
int_enable = sys_read32(PIT_INTE(dev));
|
||||
int_status = sys_read32(PIT_ISTA(dev));
|
||||
|
||||
if (int_status & TIMER0_CHANNEL(3)) {
|
||||
if (data->top_callback) {
|
||||
data->top_callback(dev, data->top_user_data);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < CH_NUM_PER_COUNTER; i++) {
|
||||
if (int_status & TIMER0_CHANNEL(i)) {
|
||||
int_enable &= ~TIMER0_CHANNEL(i);
|
||||
ch_enable &= ~TIMER0_CHANNEL(i);
|
||||
|
||||
cb = data->ch_data[i].alarm_callback;
|
||||
data->ch_data[i].alarm_callback = NULL;
|
||||
|
||||
cur_ticks = get_current_tick(dev, 3);
|
||||
cb(dev, i, cur_ticks, data->ch_data[i].alarm_user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable channel and interrupt */
|
||||
sys_write32(int_enable, PIT_INTE(dev));
|
||||
sys_write32(ch_enable, PIT_CHEN(dev));
|
||||
|
||||
/* Clear interrupt status */
|
||||
sys_write32(int_status, PIT_ISTA(dev));
|
||||
}
|
||||
|
||||
static int counter_atcpit100_init(const struct device *dev)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
uint32_t reg;
|
||||
|
||||
/* Disable all channels */
|
||||
sys_write32(0, PIT_CHEN(dev));
|
||||
|
||||
/* Channel 0 ~ 3, 32 bits timer, PCLK source */
|
||||
reg = CTRL_CH_MODE_32BIT | CTRL_CH_SRC_PCLK;
|
||||
sys_write32(reg, PIT_CH_CTRL(dev, 0));
|
||||
sys_write32(reg, PIT_CH_CTRL(dev, 1));
|
||||
sys_write32(reg, PIT_CH_CTRL(dev, 2));
|
||||
sys_write32(reg, PIT_CH_CTRL(dev, 3));
|
||||
|
||||
/* Disable all interrupt and clear all pending interrupt */
|
||||
sys_write32(0, PIT_INTE(dev));
|
||||
sys_write32(UINT32_MAX, PIT_ISTA(dev));
|
||||
|
||||
/* Select channel 3 as default counter and set max top value */
|
||||
reg = config->info.max_top_value * config->divider;
|
||||
|
||||
/* Set cycle - 1 to reload register */
|
||||
sys_write32((reg - 1), PIT_CH_RELD(dev, 3));
|
||||
|
||||
config->cfg_func();
|
||||
|
||||
irq_enable(config->irq_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atcpit100_start(const struct device *dev)
|
||||
{
|
||||
struct atcpit100_data *data = dev->data;
|
||||
k_spinlock_key_t key;
|
||||
uint32_t reg;
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
/* Enable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg |= TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atcpit100_stop(const struct device *dev)
|
||||
{
|
||||
struct atcpit100_data *data = dev->data;
|
||||
k_spinlock_key_t key;
|
||||
uint32_t reg;
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
/* Disable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg &= ~TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
|
||||
/* Disable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg &= ~TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
|
||||
/* Clear interrupt status */
|
||||
sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atcpit100_get_value(const struct device *dev, uint32_t *ticks)
|
||||
{
|
||||
struct atcpit100_data *data = dev->data;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
*ticks = get_current_tick(dev, 3);
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atcpit100_set_alarm(const struct device *dev, uint8_t chan_id,
|
||||
const struct counter_alarm_cfg *alarm_cfg)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
struct atcpit100_data *data = dev->data;
|
||||
uint32_t top, now_cnt, remain_cnt, alarm_cnt, flags, reg;
|
||||
k_spinlock_key_t key;
|
||||
int err = 0;
|
||||
|
||||
if (chan_id >= CH_NUM_PER_COUNTER) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
if (!alarm_cfg->callback) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->ch_data[chan_id].alarm_callback) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
/* Preload cycles is reload register + 1 */
|
||||
top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
|
||||
remain_cnt = sys_read32(PIT_CH_CNTR(dev, 3));
|
||||
alarm_cnt = alarm_cfg->ticks * config->divider;
|
||||
|
||||
if (alarm_cnt > top) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
flags = alarm_cfg->flags;
|
||||
data->ch_data[chan_id].alarm_callback = alarm_cfg->callback;
|
||||
data->ch_data[chan_id].alarm_user_data = alarm_cfg->user_data;
|
||||
|
||||
if (flags & COUNTER_ALARM_CFG_ABSOLUTE) {
|
||||
uint32_t irq_on_late, max_rel_val;
|
||||
|
||||
now_cnt = top - remain_cnt;
|
||||
max_rel_val = top - (data->guard_period * config->divider);
|
||||
irq_on_late = flags & COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE;
|
||||
|
||||
if (now_cnt < alarm_cnt) {
|
||||
/* Absolute alarm is in this round counting */
|
||||
reg = alarm_cnt - now_cnt;
|
||||
irq_on_late = 0;
|
||||
} else {
|
||||
/* Absolute alarm is in the next round counting */
|
||||
reg = alarm_cnt + remain_cnt;
|
||||
}
|
||||
|
||||
if (reg > max_rel_val) {
|
||||
/* Absolute alarm is in the guard period */
|
||||
err = -ETIME;
|
||||
if (!irq_on_late) {
|
||||
data->ch_data[chan_id].alarm_callback = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (irq_on_late) {
|
||||
/* Trigger interrupt immediately */
|
||||
reg = 1;
|
||||
}
|
||||
} else {
|
||||
/* Round up decreasing counter to tick boundary */
|
||||
now_cnt = remain_cnt + config->divider - 1;
|
||||
now_cnt = (now_cnt / config->divider) * config->divider;
|
||||
|
||||
/* Adjusting relative alarm counter to tick boundary */
|
||||
reg = alarm_cnt - (now_cnt - remain_cnt);
|
||||
}
|
||||
|
||||
/* Set cycle - 1 to reload register */
|
||||
sys_write32((reg - 1), PIT_CH_RELD(dev, chan_id));
|
||||
|
||||
/* Enable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg |= TIMER0_CHANNEL(chan_id);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
|
||||
/* Enable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg |= TIMER0_CHANNEL(chan_id);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
|
||||
out:
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int atcpit100_cancel_alarm(const struct device *dev, uint8_t chan_id)
|
||||
{
|
||||
struct atcpit100_data *data = dev->data;
|
||||
k_spinlock_key_t key;
|
||||
uint32_t reg;
|
||||
|
||||
if (chan_id >= CH_NUM_PER_COUNTER) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
/* Disable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg &= ~TIMER0_CHANNEL(chan_id);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
|
||||
/* Disable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg &= ~TIMER0_CHANNEL(chan_id);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
|
||||
/* Clear interrupt status */
|
||||
sys_write32(TIMER0_CHANNEL(chan_id), PIT_ISTA(dev));
|
||||
|
||||
data->ch_data[chan_id].alarm_callback = NULL;
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atcpit100_set_top_value(const struct device *dev,
|
||||
const struct counter_top_cfg *cfg)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
struct atcpit100_data *data = dev->data;
|
||||
uint32_t ticks, reg, reset_counter = 1;
|
||||
k_spinlock_key_t key;
|
||||
int err = 0;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < counter_get_num_of_channels(dev); i++) {
|
||||
if (data->ch_data[i].alarm_callback) {
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg->ticks > config->info.max_top_value) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&data->lock);
|
||||
|
||||
if (cfg->callback) {
|
||||
/* Disable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg &= ~TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
|
||||
data->top_callback = cfg->callback;
|
||||
data->top_user_data = cfg->user_data;
|
||||
|
||||
/* Enable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg |= TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
}
|
||||
|
||||
if (cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
|
||||
/* Don't reset counter */
|
||||
reset_counter = 0;
|
||||
ticks = get_current_tick(dev, 3);
|
||||
if (ticks >= cfg->ticks) {
|
||||
err = -ETIME;
|
||||
if (cfg->flags & COUNTER_TOP_CFG_RESET_WHEN_LATE) {
|
||||
/* Reset counter if current is late */
|
||||
reset_counter = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set cycle - 1 to reload register */
|
||||
reg = cfg->ticks * config->divider;
|
||||
sys_write32((reg - 1), PIT_CH_RELD(dev, 3));
|
||||
|
||||
if (reset_counter) {
|
||||
/* Disable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg &= ~TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
|
||||
/* Clear interrupt status */
|
||||
sys_write32(TIMER0_CHANNEL(3), PIT_ISTA(dev));
|
||||
|
||||
/* Enable channel interrupt */
|
||||
reg = sys_read32(PIT_INTE(dev));
|
||||
reg |= TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_INTE(dev));
|
||||
|
||||
/* Enable channel */
|
||||
reg = sys_read32(PIT_CHEN(dev));
|
||||
reg |= TIMER0_CHANNEL(3);
|
||||
sys_write32(reg, PIT_CHEN(dev));
|
||||
}
|
||||
|
||||
k_spin_unlock(&data->lock, key);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static uint32_t atcpit100_get_pending_int(const struct device *dev)
|
||||
{
|
||||
uint32_t reg = sys_read32(PIT_ISTA(dev));
|
||||
|
||||
reg &= (TIMER0_CHANNEL(0) | TIMER0_CHANNEL(1) |
|
||||
TIMER0_CHANNEL(2) | TIMER0_CHANNEL(3));
|
||||
|
||||
return !(!reg);
|
||||
}
|
||||
|
||||
static uint32_t atcpit100_get_top_value(const struct device *dev)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
|
||||
|
||||
return (top / config->divider);
|
||||
}
|
||||
|
||||
static uint32_t atcpit100_get_guard_period(const struct device *dev,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct atcpit100_data *data = dev->data;
|
||||
|
||||
return data->guard_period;
|
||||
}
|
||||
|
||||
static int atcpit100_set_guard_period(const struct device *dev,
|
||||
uint32_t ticks, uint32_t flags)
|
||||
{
|
||||
const struct atcpit100_config *config = dev->config;
|
||||
struct atcpit100_data *data = dev->data;
|
||||
uint32_t top = sys_read32(PIT_CH_RELD(dev, 3)) + 1;
|
||||
|
||||
if ((ticks * config->divider) > top) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->guard_period = ticks;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct counter_driver_api atcpit100_driver_api = {
|
||||
.start = atcpit100_start,
|
||||
.stop = atcpit100_stop,
|
||||
.get_value = atcpit100_get_value,
|
||||
.set_alarm = atcpit100_set_alarm,
|
||||
.cancel_alarm = atcpit100_cancel_alarm,
|
||||
.set_top_value = atcpit100_set_top_value,
|
||||
.get_pending_int = atcpit100_get_pending_int,
|
||||
.get_top_value = atcpit100_get_top_value,
|
||||
.get_guard_period = atcpit100_get_guard_period,
|
||||
.set_guard_period = atcpit100_set_guard_period,
|
||||
};
|
||||
|
||||
#define COUNTER_ATCPIT100_INIT(n) \
|
||||
static void counter_atcpit100_cfg_##n(void); \
|
||||
static struct atcpit100_data atcpit100_data_##n; \
|
||||
\
|
||||
static const struct atcpit100_config atcpit100_config_##n = { \
|
||||
.info = { \
|
||||
.max_top_value = \
|
||||
(UINT32_MAX/DT_INST_PROP(n, prescaler)),\
|
||||
.freq = (DT_INST_PROP(n, clock_frequency) / \
|
||||
DT_INST_PROP(n, prescaler)), \
|
||||
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
|
||||
.channels = CH_NUM_PER_COUNTER, \
|
||||
}, \
|
||||
.base = DT_INST_REG_ADDR(n), \
|
||||
.divider = DT_INST_PROP(n, prescaler), \
|
||||
.irq_num = DT_INST_IRQN(n), \
|
||||
.cfg_func = counter_atcpit100_cfg_##n, \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(n, \
|
||||
counter_atcpit100_init, \
|
||||
NULL, \
|
||||
&atcpit100_data_##n, \
|
||||
&atcpit100_config_##n, \
|
||||
POST_KERNEL, \
|
||||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, \
|
||||
&atcpit100_driver_api); \
|
||||
\
|
||||
static void counter_atcpit100_cfg_##n(void) \
|
||||
{ \
|
||||
IRQ_CONNECT(DT_INST_IRQN(n), \
|
||||
DT_INST_IRQ(n, priority), \
|
||||
atcpit100_irq_handler, \
|
||||
DEVICE_DT_INST_GET(n), \
|
||||
0); \
|
||||
}
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(COUNTER_ATCPIT100_INIT)
|
Loading…
Reference in a new issue