diff --git a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c deleted file mode 100644 index 127aae939d..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_api.c +++ /dev/null @@ -1,270 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) -#define CHANNEL_NUM (3) - -// Max pins for one line (max with EXTI4_15) -#define MAX_PIN_LINE (12) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0_1 - 0, // pin 0 - 1, // pin 1 - // EXTI2_3 - 0, // pin 2 - 1, // pin 3 - // EXTI4_15 - 0, // pin 4 - 1, // pin 5 - 2, // pin 6 - 3, // pin 7 - 4, // pin 8 - 5, // pin 9 - 6, // pin 10 - 7, // pin 11 - 8, // pin 12 - 9, // pin 13 - 10, // pin 14 - 11 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI lines 0 to 1 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 2); -} - -// EXTI lines 2 to 3 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 2); -} - -// EXTI lines 4 to 15 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 12); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - if ((pin_index == 0) || (pin_index == 1)) { - irq_n = EXTI0_1_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - } else if ((pin_index == 2) || (pin_index == 3)) { - irq_n = EXTI2_3_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - } else if ((pin_index > 3) && (pin_index < 16)) { - irq_n = EXTI4_15_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - } else { - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - uint32_t pull = GPIO_NOPULL; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h new file mode 100644 index 0000000000..5e2b0aa82b --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F0/gpio_irq_device.h @@ -0,0 +1,79 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#include "cmsis.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) +#define CHANNEL_NUM (3) + +#define EXTI_IRQ0_NUM_LINES 2 +#define EXTI_IRQ1_NUM_LINES 2 +#define EXTI_IRQ2_NUM_LINES 12 +// Max pins for one line (max with EXTI4_15) +#define MAX_PIN_LINE (EXTI_IRQ2_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0_1 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 0 + {.gpio_idx = 1, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 1 + // EXTI2_3 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 2 + {.gpio_idx = 1, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 3 + // EXTI4_15 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI4_15_IRQn}, // pin 4 + {.gpio_idx = 1, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 5 + {.gpio_idx = 2, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 6 + {.gpio_idx = 3, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 7 + {.gpio_idx = 4, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 8 + {.gpio_idx = 5, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 9 + {.gpio_idx = 6, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 10 + {.gpio_idx = 7, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 11 + {.gpio_idx = 8, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 12 + {.gpio_idx = 9, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 13 + {.gpio_idx = 10, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 14 + {.gpio_idx = 11, .irq_index = 2, .irq_n = EXTI4_15_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h new file mode 100644 index 0000000000..53ef8b96ac --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_device.h @@ -0,0 +1,82 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2014, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h new file mode 100644 index 0000000000..6244e3e7e7 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F2/gpio_irq_device.h @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f2xx_ll_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c deleted file mode 100644 index 6b40b8836b..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2014, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_TSC_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_INPUT; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h new file mode 100644 index 0000000000..30dd191015 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F3/gpio_irq_device.h @@ -0,0 +1,82 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_TSC_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h new file mode 100644 index 0000000000..e40f63115b --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F4/gpio_irq_device.h @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f4xx_ll_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h new file mode 100644 index 0000000000..afef8d314c --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32F7/gpio_irq_device.h @@ -0,0 +1,119 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +// when LL is available, below include can be used +// #include "stm32f0xx_f7_exti.h" +// until then let's define locally the required functions +__STATIC_INLINE void LL_EXTI_EnableRisingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableRisingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->RTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableFallingTrig_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableFallingTrig_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->FTSR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_EnableIT_0_31(uint32_t ExtiLine) +{ + SET_BIT(EXTI->IMR, ExtiLine); +} +__STATIC_INLINE void LL_EXTI_DisableIT_0_31(uint32_t ExtiLine) +{ + CLEAR_BIT(EXTI->IMR, ExtiLine); +} +// Above lines shall be later defined in LL + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c deleted file mode 100644 index 61fef17594..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_api.c +++ /dev/null @@ -1,269 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0_1, EXTI2_3, EXTI4_15) -#define CHANNEL_NUM (3) - -// Max pins for one line (max with EXTI4_15) -#define MAX_PIN_LINE (12) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0_1 - 0, // pin 0 - 1, // pin 1 - // EXTI2_3 - 0, // pin 2 - 1, // pin 3 - // EXTI4_15 - 0, // pin 4 - 1, // pin 5 - 2, // pin 6 - 3, // pin 7 - 4, // pin 8 - 5, // pin 9 - 6, // pin 10 - 7, // pin 11 - 8, // pin 12 - 9, // pin 13 - 10, // pin 14 - 11 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI lines 0 to 1 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 2); -} - -// EXTI lines 2 to 3 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 2); -} - -// EXTI lines 4 to 15 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 12); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - if ((pin_index == 0) || (pin_index == 1)) { - irq_n = EXTI0_1_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - } else if ((pin_index == 2) || (pin_index == 3)) { - irq_n = EXTI2_3_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - } else if ((pin_index > 3) && (pin_index < 16)) { - irq_n = EXTI4_15_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - } else { - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h new file mode 100644 index 0000000000..1bab36f7c5 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L0/gpio_irq_device.h @@ -0,0 +1,75 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +#include "stm32l0xx_ll_exti.h" +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (3) + +#define EXTI_IRQ0_NUM_LINES 2 +#define EXTI_IRQ1_NUM_LINES 2 +#define EXTI_IRQ2_NUM_LINES 12 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ2_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0_1 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 0 + {.gpio_idx = 1, .irq_index = 0, .irq_n = EXTI0_1_IRQn}, // pin 1 + // EXTI2_3 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 2 + {.gpio_idx = 1, .irq_index = 1, .irq_n = EXTI2_3_IRQn}, // pin 3 + // EXTI4_15 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI4_15_IRQn}, // pin 4 + {.gpio_idx = 1, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 5 + {.gpio_idx = 2, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 6 + {.gpio_idx = 3, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 7 + {.gpio_idx = 4, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 8 + {.gpio_idx = 5, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 9 + {.gpio_idx = 6, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 10 + {.gpio_idx = 7, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 11 + {.gpio_idx = 8, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 12 + {.gpio_idx = 9, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 13 + {.gpio_idx = 10, .irq_index = 2, .irq_n = EXTI4_15_IRQn},// pin 14 + {.gpio_idx = 11, .irq_index = 2, .irq_n = EXTI4_15_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h new file mode 100644 index 0000000000..740b0f6653 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L1/gpio_irq_device.h @@ -0,0 +1,82 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c deleted file mode 100644 index c595b98ba6..0000000000 --- a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_api.c +++ /dev/null @@ -1,334 +0,0 @@ -/* mbed Microcontroller Library - ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************* - */ -#include -#include "cmsis.h" -#include "gpio_irq_api.h" -#include "pinmap.h" -#include "mbed_error.h" - -#define EDGE_NONE (0) -#define EDGE_RISE (1) -#define EDGE_FALL (2) -#define EDGE_BOTH (3) - -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) - -typedef struct gpio_channel { - uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts - uint32_t channel_ids[MAX_PIN_LINE]; // mbed "gpio_irq_t gpio_irq" field of instance - uint32_t channel_gpio[MAX_PIN_LINE]; // base address of gpio port group - uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group -} gpio_channel_t; - -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - -static gpio_irq_handler irq_handler; - -static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) -{ - gpio_channel_t *gpio_channel = &channels[irq_index]; - uint32_t gpio_idx; - - for (gpio_idx = 0; gpio_idx < max_num_pin_line; gpio_idx++) { - uint32_t current_mask = (1 << gpio_idx); - - if (gpio_channel->pin_mask & current_mask) { - // Retrieve the gpio and pin that generate the irq - GPIO_TypeDef *gpio = (GPIO_TypeDef *)(gpio_channel->channel_gpio[gpio_idx]); - uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); - - // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { - __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; - - // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { - irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); - } - } - } - } -} - -// EXTI line 0 -static void gpio_irq0(void) -{ - handle_interrupt_in(0, 1); -} - -// EXTI line 1 -static void gpio_irq1(void) -{ - handle_interrupt_in(1, 1); -} - -// EXTI line 2 -static void gpio_irq2(void) -{ - handle_interrupt_in(2, 1); -} - -// EXTI line 3 -static void gpio_irq3(void) -{ - handle_interrupt_in(3, 1); -} - -// EXTI line 4 -static void gpio_irq4(void) -{ - handle_interrupt_in(4, 1); -} - -// EXTI lines 5 to 9 -static void gpio_irq5(void) -{ - handle_interrupt_in(5, 5); -} - -// EXTI lines 10 to 15 -static void gpio_irq6(void) -{ - handle_interrupt_in(6, 6); -} - -extern uint32_t Set_GPIO_Clock(uint32_t port_idx); -extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); - -int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) -{ - IRQn_Type irq_n = (IRQn_Type)0; - uint32_t vector = 0; - uint32_t irq_index; - gpio_channel_t *gpio_channel; - uint32_t gpio_idx; - - if (pin == NC) return -1; - - uint32_t port_index = STM_PORT(pin); - uint32_t pin_index = STM_PIN(pin); - - // Select irq number and interrupt routine - switch (pin_index) { - case 0: - irq_n = EXTI0_IRQn; - vector = (uint32_t)&gpio_irq0; - irq_index = 0; - break; - case 1: - irq_n = EXTI1_IRQn; - vector = (uint32_t)&gpio_irq1; - irq_index = 1; - break; - case 2: - irq_n = EXTI2_IRQn; - vector = (uint32_t)&gpio_irq2; - irq_index = 2; - break; - case 3: - irq_n = EXTI3_IRQn; - vector = (uint32_t)&gpio_irq3; - irq_index = 3; - break; - case 4: - irq_n = EXTI4_IRQn; - vector = (uint32_t)&gpio_irq4; - irq_index = 4; - break; - case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; - vector = (uint32_t)&gpio_irq5; - irq_index = 5; - break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; - vector = (uint32_t)&gpio_irq6; - irq_index = 6; - break; - default: - error("InterruptIn error: pin not supported.\n"); - return -1; - } - - // Enable GPIO clock - uint32_t gpio_add = Set_GPIO_Clock(port_index); - - // Configure GPIO - pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; - obj->event = EDGE_NONE; - obj->pin = pin; - - gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; - gpio_channel->pin_mask |= (1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = id; - gpio_channel->channel_gpio[gpio_idx] = gpio_add; - gpio_channel->channel_pin[gpio_idx] = pin_index; - - irq_handler = handler; - - return 0; -} - -void gpio_irq_free(gpio_irq_t *obj) -{ - gpio_channel_t *gpio_channel = &channels[obj->irq_index]; - uint32_t pin_index = STM_PIN(obj->pin); - uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; - - HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx); - gpio_channel->channel_ids[gpio_idx] = 0; - gpio_channel->channel_gpio[gpio_idx] = 0; - gpio_channel->channel_pin[gpio_idx] = 0; - - // Disable EXTI line, but don't change pull-up config - pin_function_gpiomode(obj->pin, STM_MODE_INPUT); - obj->event = EDGE_NONE; -} - -void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) -{ - uint32_t mode = STM_MODE_IT_EVT_RESET; - - if (enable) { - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or RISE - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING_FALLING; - obj->event = EDGE_BOTH; - } else { // NONE or FALL - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } - } - } else { // Disable - if (event == IRQ_RISE) { - if ((obj->event == EDGE_FALL) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_FALLING; - obj->event = EDGE_FALL; - } else { // NONE or RISE - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - if (event == IRQ_FALL) { - if ((obj->event == EDGE_RISE) || (obj->event == EDGE_BOTH)) { - mode = STM_MODE_IT_RISING; - obj->event = EDGE_RISE; - } else { // NONE or FALL - mode = STM_MODE_INPUT; - obj->event = EDGE_NONE; - } - } - } - - pin_function_gpiomode(obj->pin, mode); -} - -void gpio_irq_enable(gpio_irq_t *obj) -{ - NVIC_EnableIRQ(obj->irq_n); -} - -void gpio_irq_disable(gpio_irq_t *obj) -{ - NVIC_DisableIRQ(obj->irq_n); - obj->event = EDGE_NONE; -} diff --git a/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h new file mode 100644 index 0000000000..740b0f6653 --- /dev/null +++ b/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.h @@ -0,0 +1,82 @@ +/* mbed Microcontroller Library + ******************************************************************************* + * Copyright (c) 2016, STMicroelectronics + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ******************************************************************************* + */ +#ifndef MBED_GPIO_IRQ_DEVICE_H +#define MBED_GPIO_IRQ_DEVICE_H + +// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) +#define CHANNEL_NUM (7) + +#define EXTI_IRQ0_NUM_LINES 1 +#define EXTI_IRQ1_NUM_LINES 1 +#define EXTI_IRQ2_NUM_LINES 1 +#define EXTI_IRQ3_NUM_LINES 1 +#define EXTI_IRQ4_NUM_LINES 1 +#define EXTI_IRQ5_NUM_LINES 5 +#define EXTI_IRQ6_NUM_LINES 6 + +// Max pins for one line (max with EXTI10_15) +#define MAX_PIN_LINE (EXTI_IRQ6_NUM_LINES) + +/* Structure to describe how the HW EXTI lines are defined in this HW */ +typedef struct exti_lines { + uint32_t gpio_idx; // an index entry for each EXIT line + uint32_t irq_index; // the IRQ index + IRQn_Type irq_n; // the corresponding EXTI IRQn +} exti_lines_t; + +// Used to return the index for channels array. +static exti_lines_t pin_lines_desc[16] = +{ + // EXTI0 + {.gpio_idx = 0, .irq_index = 0, .irq_n = EXTI0_IRQn}, // pin 0 + // EXTI1 + {.gpio_idx = 0, .irq_index = 1, .irq_n = EXTI1_IRQn}, // pin 1 + // EXTI2 + {.gpio_idx = 0, .irq_index = 2, .irq_n = EXTI2_IRQn}, // pin 2 + // EXTI3 + {.gpio_idx = 0, .irq_index = 3, .irq_n = EXTI3_IRQn}, // pin 3 + // EXTI4 + {.gpio_idx = 0, .irq_index = 4, .irq_n = EXTI4_IRQn}, // pin 4 + // EXTI5_9 + {.gpio_idx = 0, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 5 + {.gpio_idx = 1, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 6 + {.gpio_idx = 2, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 7 + {.gpio_idx = 3, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 8 + {.gpio_idx = 4, .irq_index = 5, .irq_n = EXTI9_5_IRQn},// pin 9 + // EXTI10_15 + {.gpio_idx = 0, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 10 + {.gpio_idx = 1, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 11 + {.gpio_idx = 2, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 12 + {.gpio_idx = 3, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 13 + {.gpio_idx = 4, .irq_index = 6, .irq_n = EXTI15_10_IRQn},// pin 14 + {.gpio_idx = 5, .irq_index = 6, .irq_n = EXTI15_10_IRQn}// pin 15 +}; + +#endif diff --git a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c b/targets/TARGET_STM/gpio_irq_api.c similarity index 80% rename from targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c rename to targets/TARGET_STM/gpio_irq_api.c index f8e4f7a5bc..97e11f652f 100644 --- a/targets/TARGET_STM/TARGET_STM32F1/gpio_irq_api.c +++ b/targets/TARGET_STM/gpio_irq_api.c @@ -32,17 +32,13 @@ #include "gpio_irq_api.h" #include "pinmap.h" #include "mbed_error.h" +#include "gpio_irq_device.h" #define EDGE_NONE (0) #define EDGE_RISE (1) #define EDGE_FALL (2) #define EDGE_BOTH (3) -// Number of EXTI irq vectors (EXTI0, EXTI1, EXTI2, EXTI3, EXTI4, EXTI5_9, EXTI10_15) -#define CHANNEL_NUM (7) - -// Max pins for one line (max with EXTI10_15) -#define MAX_PIN_LINE (6) typedef struct gpio_channel { uint32_t pin_mask; // bitmask representing which pins are configured for receiving interrupts @@ -51,45 +47,32 @@ typedef struct gpio_channel { uint32_t channel_pin[MAX_PIN_LINE]; // pin number in port group } gpio_channel_t; -static gpio_channel_t channels[CHANNEL_NUM] = { - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0}, - {.pin_mask = 0} -}; - -// Used to return the index for channels array. -static uint32_t pin_base_nr[16] = { - // EXTI0 - 0, // pin 0 - // EXTI1 - 0, // pin 1 - // EXTI2 - 0, // pin 2 - // EXTI3 - 0, // pin 3 - // EXTI4 - 0, // pin 4 - // EXTI5_9 - 0, // pin 5 - 1, // pin 6 - 2, // pin 7 - 3, // pin 8 - 4, // pin 9 - // EXTI10_15 - 0, // pin 10 - 1, // pin 11 - 2, // pin 12 - 3, // pin 13 - 4, // pin 14 - 5 // pin 15 -}; - static gpio_irq_handler irq_handler; +static gpio_channel_t channels[CHANNEL_NUM] = { +#ifdef EXTI_IRQ0_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ1_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ2_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ3_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ4_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ5_NUM_LINES + {.pin_mask = 0}, +#endif +#ifdef EXTI_IRQ6_NUM_LINES + {.pin_mask = 0} +#endif +}; + static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) { gpio_channel_t *gpio_channel = &channels[irq_index]; @@ -104,15 +87,20 @@ static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) uint32_t pin = (uint32_t)(1 << (gpio_channel->channel_pin[gpio_idx])); // Clear interrupt flag - if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) { + if (__HAL_GPIO_EXTI_GET_FLAG(pin) != RESET) + { __HAL_GPIO_EXTI_CLEAR_FLAG(pin); - if (gpio_channel->channel_ids[gpio_idx] == 0) continue; + if (gpio_channel->channel_ids[gpio_idx] == 0) + continue; // Check which edge has generated the irq - if ((gpio->IDR & pin) == 0) { + if ((gpio->IDR & pin) == 0) + { irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL); - } else { + } + else + { irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE); } } @@ -120,54 +108,62 @@ static void handle_interrupt_in(uint32_t irq_index, uint32_t max_num_pin_line) } } + +#ifdef EXTI_IRQ0_NUM_LINES // EXTI line 0 static void gpio_irq0(void) { - handle_interrupt_in(0, 1); + handle_interrupt_in(0, EXTI_IRQ0_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ1_NUM_LINES // EXTI line 1 static void gpio_irq1(void) { - handle_interrupt_in(1, 1); + handle_interrupt_in(1, EXTI_IRQ1_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ2_NUM_LINES // EXTI line 2 static void gpio_irq2(void) { - handle_interrupt_in(2, 1); + handle_interrupt_in(2, EXTI_IRQ2_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ3_NUM_LINES // EXTI line 3 static void gpio_irq3(void) { - handle_interrupt_in(3, 1); + handle_interrupt_in(3, EXTI_IRQ3_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ4_NUM_LINES // EXTI line 4 static void gpio_irq4(void) { - handle_interrupt_in(4, 1); + handle_interrupt_in(4, EXTI_IRQ4_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ5_NUM_LINES // EXTI lines 5 to 9 static void gpio_irq5(void) { - handle_interrupt_in(5, 5); + handle_interrupt_in(5, EXTI_IRQ5_NUM_LINES); } - +#endif +#ifdef EXTI_IRQ6_NUM_LINES // EXTI lines 10 to 15 static void gpio_irq6(void) { - handle_interrupt_in(6, 6); + handle_interrupt_in(6, EXTI_IRQ6_NUM_LINES); } +#endif extern uint32_t Set_GPIO_Clock(uint32_t port_idx); extern void pin_function_gpiomode(PinName pin, uint32_t gpiomode); int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; uint32_t irq_index; gpio_channel_t *gpio_channel; @@ -177,53 +173,45 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 uint32_t port_index = STM_PORT(pin); uint32_t pin_index = STM_PIN(pin); + irq_index = pin_lines_desc[pin_index].irq_index; - // Select irq number and interrupt routine - switch (pin_index) { + switch (irq_index) + { +#ifdef EXTI_IRQ0_NUM_LINES case 0: - irq_n = EXTI0_IRQn; vector = (uint32_t)&gpio_irq0; - irq_index = 0; break; +#endif +#ifdef EXTI_IRQ1_NUM_LINES case 1: - irq_n = EXTI1_IRQn; vector = (uint32_t)&gpio_irq1; - irq_index = 1; break; +#endif +#ifdef EXTI_IRQ2_NUM_LINES case 2: - irq_n = EXTI2_IRQn; vector = (uint32_t)&gpio_irq2; - irq_index = 2; break; +#endif +#ifdef EXTI_IRQ3_NUM_LINES case 3: - irq_n = EXTI3_IRQn; vector = (uint32_t)&gpio_irq3; - irq_index = 3; break; +#endif +#ifdef EXTI_IRQ4_NUM_LINES case 4: - irq_n = EXTI4_IRQn; vector = (uint32_t)&gpio_irq4; - irq_index = 4; break; +#endif +#ifdef EXTI_IRQ5_NUM_LINES case 5: - case 6: - case 7: - case 8: - case 9: - irq_n = EXTI9_5_IRQn; vector = (uint32_t)&gpio_irq5; - irq_index = 5; break; - case 10: - case 11: - case 12: - case 13: - case 14: - case 15: - irq_n = EXTI15_10_IRQn; +#endif +#ifdef EXTI_IRQ6_NUM_LINES + case 6: vector = (uint32_t)&gpio_irq6; - irq_index = 6; break; +#endif default: error("InterruptIn error: pin not supported.\n"); return -1; @@ -235,18 +223,14 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 // Configure GPIO pin_function(pin, STM_PIN_DATA(STM_MODE_IT_FALLING, GPIO_NOPULL, 0)); - // Enable EXTI interrupt - NVIC_SetVector(irq_n, vector); - NVIC_EnableIRQ(irq_n); - // Save informations for future use - obj->irq_n = irq_n; - obj->irq_index = irq_index; + obj->irq_n = pin_lines_desc[pin_index].irq_n; + obj->irq_index = pin_lines_desc[pin_index].irq_index; obj->event = EDGE_NONE; obj->pin = pin; gpio_channel = &channels[irq_index]; - gpio_idx = pin_base_nr[pin_index]; + gpio_idx = pin_lines_desc[pin_index].gpio_idx; gpio_channel->pin_mask |= (1 << gpio_idx); gpio_channel->channel_ids[gpio_idx] = id; gpio_channel->channel_gpio[gpio_idx] = gpio_add; @@ -254,6 +238,10 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 irq_handler = handler; + // Enable EXTI interrupt + NVIC_SetVector(obj->irq_n, vector); + NVIC_EnableIRQ(obj->irq_n); + return 0; } @@ -262,7 +250,7 @@ void gpio_irq_free(gpio_irq_t *obj) gpio_channel_t *gpio_channel = &channels[obj->irq_index]; uint32_t pin_index = STM_PIN(obj->pin); uint32_t gpio_addr = GPIOA_BASE + (GPIOB_BASE-GPIOA_BASE) * STM_PORT(obj->pin); - uint32_t gpio_idx = pin_base_nr[pin_index]; + uint32_t gpio_idx = pin_lines_desc[STM_PIN(obj->pin)].gpio_idx; HAL_GPIO_DeInit((GPIO_TypeDef *)gpio_addr, (1<pin_mask &= ~(1 << gpio_idx);