From 107d6336b2030f0e2b1e2e3aa5d99df2eb0a575f Mon Sep 17 00:00:00 2001 From: ccli8 Date: Mon, 19 Sep 2016 13:29:52 +0800 Subject: [PATCH] [NUC472/M453] Disable GPIO IRQ debounce by default Some application requires GPIO IRQ to be low latency. To complement it, open up GPIO IRQ debounce configuration through mbed_lib.json. --- .../TARGET_NUVOTON/TARGET_M451/mbed_lib.json | 18 +++++++++++ .../TARGET_NUC472/mbed_lib.json | 18 +++++++++++ .../TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c | 29 ++++++++++++++--- .../TARGET_NUC472/gpio_irq_api.c | 31 ++++++++++++++++--- 4 files changed, 87 insertions(+), 9 deletions(-) create mode 100644 hal/targets/hal/TARGET_NUVOTON/TARGET_M451/mbed_lib.json create mode 100644 hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json diff --git a/hal/targets/hal/TARGET_NUVOTON/TARGET_M451/mbed_lib.json b/hal/targets/hal/TARGET_NUVOTON/TARGET_M451/mbed_lib.json new file mode 100644 index 0000000000..3832d8f9ec --- /dev/null +++ b/hal/targets/hal/TARGET_NUVOTON/TARGET_M451/mbed_lib.json @@ -0,0 +1,18 @@ +{ + "name": "M451", + "config": { + "gpio-irq-debounce-enable": { + "help": "Enable GPIO IRQ debounce", + "value": 0 + }, + "gpio-irq-debounce-clock-source": { + "help": "Select GPIO IRQ debounce clock source: GPIO_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_LIRC", + "value": "GPIO_DBCTL_DBCLKSRC_LIRC" + }, + + "gpio-irq-debounce-sample-rate": { + "help": "Select GPIO IRQ debounce sample rate: GPIO_DBCTL_DBCLKSEL_1, GPIO_DBCTL_DBCLKSEL_2, GPIO_DBCTL_DBCLKSEL_4, ..., or GPIO_DBCTL_DBCLKSEL_32768", + "value": "GPIO_DBCTL_DBCLKSEL_16" + } + } +} diff --git a/hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json b/hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json new file mode 100644 index 0000000000..533c883f10 --- /dev/null +++ b/hal/targets/hal/TARGET_NUVOTON/TARGET_NUC472/mbed_lib.json @@ -0,0 +1,18 @@ +{ + "name": "NUC472", + "config": { + "gpio-irq-debounce-enable": { + "help": "Enable GPIO IRQ debounce", + "value": 0 + }, + "gpio-irq-debounce-clock-source": { + "help": "Select GPIO IRQ debounce clock source: GPIO_DBCTL_DBCLKSRC_HCLK or GPIO_DBCTL_DBCLKSRC_IRC10K", + "value": "GPIO_DBCTL_DBCLKSRC_IRC10K" + }, + + "gpio-irq-debounce-sample-rate": { + "help": "Select GPIO IRQ debounce sample rate: GPIO_DBCTL_DBCLKSEL_1, GPIO_DBCTL_DBCLKSEL_2, GPIO_DBCTL_DBCLKSEL_4, ..., or GPIO_DBCTL_DBCLKSEL_32768", + "value": "GPIO_DBCTL_DBCLKSEL_16" + } + } +} diff --git a/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c b/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c index c2adef9954..f08a6b0191 100644 --- a/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c +++ b/targets/TARGET_NUVOTON/TARGET_M451/gpio_irq_api.c @@ -52,6 +52,24 @@ static struct nu_gpio_irq_var gpio_irq_var_arr[] = { #define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0])) +#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE +#define M451_GPIO_IRQ_DEBOUNCE_ENABLE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_ENABLE +#else +#define M451_GPIO_IRQ_DEBOUNCE_ENABLE 0 +#endif + +#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#define M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#else +#define M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_LIRC +#endif + +#ifdef MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#define M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE MBED_CONF_M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#else +#define M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 +#endif + int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { if (pin == NC) { @@ -68,14 +86,19 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 obj->irq_handler = (uint32_t) handler; obj->irq_id = id; + GPIO_T *gpio_base = NU_PORT_BASE(port_index); //gpio_set(pin); +#if M451_GPIO_IRQ_DEBOUNCE_ENABLE // Configure de-bounce clock source and sampling cycle time - GPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_LIRC, GPIO_DBCTL_DBCLKSEL_16); + GPIO_SET_DEBOUNCE_TIME(M451_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, M451_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); +#else + GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); +#endif struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; - MBED_ASSERT(pin_index < NU_MAX_PIN_PER_PORT); var->obj_arr[pin_index] = obj; // NOTE: InterruptIn requires IRQ enabled by default. @@ -106,7 +129,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) switch (event) { case IRQ_RISE: if (enable) { - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING); } else { @@ -116,7 +138,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) case IRQ_FALL: if (enable) { - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING); } else { diff --git a/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c b/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c index bf73913b5d..62e036593c 100644 --- a/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c +++ b/targets/TARGET_NUVOTON/TARGET_NUC472/gpio_irq_api.c @@ -58,6 +58,24 @@ static struct nu_gpio_irq_var gpio_irq_var_arr[] = { #define NU_MAX_PORT (sizeof (gpio_irq_var_arr) / sizeof (gpio_irq_var_arr[0])) +#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE +#define NUC472_GPIO_IRQ_DEBOUNCE_ENABLE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_ENABLE +#else +#define NUC472_GPIO_IRQ_DEBOUNCE_ENABLE 0 +#endif + +#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#define NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE +#else +#define NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE GPIO_DBCTL_DBCLKSRC_IRC10K +#endif + +#ifdef MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#define NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE MBED_CONF_NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE +#else +#define NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE GPIO_DBCTL_DBCLKSEL_16 +#endif + int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { if (pin == NC) { @@ -74,14 +92,19 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 obj->irq_handler = (uint32_t) handler; obj->irq_id = id; + GPIO_T *gpio_base = NU_PORT_BASE(port_index); //gpio_set(pin); +#if NUC472_GPIO_IRQ_DEBOUNCE_ENABLE // Configure de-bounce clock source and sampling cycle time - GPIO_SET_DEBOUNCE_TIME(GPIO_DBCTL_DBCLKSRC_IRC10K, GPIO_DBCTL_DBCLKSEL_16); - + GPIO_SET_DEBOUNCE_TIME(NUC472_GPIO_IRQ_DEBOUNCE_CLOCK_SOURCE, NUC472_GPIO_IRQ_DEBOUNCE_SAMPLE_RATE); + GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); +#else + GPIO_DISABLE_DEBOUNCE(gpio_base, 1 << pin_index); +#endif + struct nu_gpio_irq_var *var = gpio_irq_var_arr + port_index; - MBED_ASSERT(pin_index < NU_MAX_PIN_PER_PORT); var->obj_arr[pin_index] = obj; // NOTE: InterruptIn requires IRQ enabled by default. @@ -112,7 +135,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) switch (event) { case IRQ_RISE: if (enable) { - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_RISING); } else { @@ -122,7 +144,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) case IRQ_FALL: if (enable) { - GPIO_ENABLE_DEBOUNCE(gpio_base, 1 << pin_index); GPIO_EnableInt(gpio_base, pin_index, GPIO_INT_FALLING); } else {