From ce8f47e7df8e0bc8abaaec79058cc08bc297f0c9 Mon Sep 17 00:00:00 2001 From: Karl Palsson Date: Mon, 22 Oct 2012 23:32:42 +0000 Subject: Enable nvic and exti support for L1 And include an example that uses it. --- lib/stm32/exti2.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 lib/stm32/exti2.c (limited to 'lib/stm32/exti2.c') diff --git a/lib/stm32/exti2.c b/lib/stm32/exti2.c new file mode 100644 index 0000000..bea2f4d --- /dev/null +++ b/lib/stm32/exti2.c @@ -0,0 +1,170 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Mark Butler + * Copyright (C) 2012 Karl Palsson + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + * + * This provides the code for the "next gen" EXTI block provided in F2/F4/L1 + * devices. (differences only in the source selection) + */ + +#include +#include +#if defined(STM32F2) +#include +#elif defined(STM32F4) +#include +#elif defined(STM32L1) +#include +#else +#error "invalid/unknown stm32 family for this code" +#endif + +void exti_set_trigger(u32 extis, exti_trigger_type trig) +{ + switch (trig) { + case EXTI_TRIGGER_RISING: + EXTI_RTSR |= extis; + EXTI_FTSR &= ~extis; + break; + case EXTI_TRIGGER_FALLING: + EXTI_RTSR &= ~extis; + EXTI_FTSR |= extis; + break; + case EXTI_TRIGGER_BOTH: + EXTI_RTSR |= extis; + EXTI_FTSR |= extis; + break; + } +} + +void exti_enable_request(u32 extis) +{ + /* Enable interrupts. */ + EXTI_IMR |= extis; + + /* Enable events. */ + EXTI_EMR |= extis; +} + +void exti_disable_request(u32 extis) +{ + /* Disable interrupts. */ + EXTI_IMR &= ~extis; + + /* Disable events. */ + EXTI_EMR &= ~extis; +} + +/* + * Reset the interrupt request by writing a 1 to the corresponding + * pending bit register. + */ +void exti_reset_request(u32 extis) +{ + EXTI_PR = extis; +} + +/* + * Remap an external interrupt line to the corresponding pin on the + * specified GPIO port. + * + * TODO: This could be rewritten in fewer lines of code. + */ +void exti_select_source(u32 exti, u32 gpioport) +{ + u8 shift, bits; + + shift = bits = 0; + + switch (exti) { + case EXTI0: + case EXTI4: + case EXTI8: + case EXTI12: + shift = 0; + break; + case EXTI1: + case EXTI5: + case EXTI9: + case EXTI13: + shift = 4; + break; + case EXTI2: + case EXTI6: + case EXTI10: + case EXTI14: + shift = 8; + break; + case EXTI3: + case EXTI7: + case EXTI11: + case EXTI15: + shift = 12; + break; + } + + switch (gpioport) { + case GPIOA: + bits = 0xf; + break; + case GPIOB: + bits = 0xe; + break; + case GPIOC: + bits = 0xd; + break; + case GPIOD: + bits = 0xc; + break; + case GPIOE: + bits = 0xb; + break; +#if defined(STM32L1) +#else + case GPIOF: + bits = 0xa; + break; + case GPIOG: + bits = 0x9; + break; +#endif + case GPIOH: + bits = 0x8; + break; +#if defined(STM32L1) +#else + case GPIOI: + bits = 0x7; + break; +#endif + } + + /* Ensure that only valid EXTI lines are used. */ + if (exti < EXTI4) { + SYSCFG_EXTICR1 &= ~(0x000F << shift); + SYSCFG_EXTICR1 |= (~bits << shift); + } else if (exti < EXTI8) { + SYSCFG_EXTICR2 &= ~(0x000F << shift); + SYSCFG_EXTICR2 |= (~bits << shift); + } else if (exti < EXTI12) { + SYSCFG_EXTICR3 &= ~(0x000F << shift); + SYSCFG_EXTICR3 |= (~bits << shift); + } else if (exti < EXTI16) { + SYSCFG_EXTICR4 &= ~(0x000F << shift); + SYSCFG_EXTICR4 |= (~bits << shift); + } +} -- cgit v1.2.3