From 1d3861ef93f8423176c6010ab606abdab00a7cbd Mon Sep 17 00:00:00 2001 From: bnewbold Date: Wed, 31 Mar 2010 08:52:45 +0800 Subject: Major hierarchy reorganization; see README. copy-to-ide and Makefile updated to conform; .gitignore added; LICENSE added --- src/lib/exti.c | 279 --------------------------------------------------------- 1 file changed, 279 deletions(-) delete mode 100644 src/lib/exti.c (limited to 'src/lib/exti.c') diff --git a/src/lib/exti.c b/src/lib/exti.c deleted file mode 100644 index bdaa204..0000000 --- a/src/lib/exti.c +++ /dev/null @@ -1,279 +0,0 @@ -/* ***************************************************************************** - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * Created: 12/18/09 02:35:22 - * Copyright (c) 2009 Perry L. Hung. All rights reserved. - * - * ****************************************************************************/ - -/** - * @file exti.c - * - * @brief External interrupt control routines - */ - -#include "libmaple.h" -#include "exti.h" -#include "nvic.h" - -volatile static voidFuncPtr exti_handlers[NR_EXTI_CHANNELS]; - -static inline void clear_pending(int bit) { - REG_SET(EXTI_PR, BIT(bit)); - /* If the pending bit is cleared as the last instruction in an ISR, - * it won't actually be cleared in time and the ISR will fire again. - * Insert a 2-cycle buffer to allow it to take effect. */ - asm volatile("nop"); - asm volatile("nop"); -} - -/* For EXTI0 through EXTI4, only one handler - * is associated with each channel, so we - * don't have to keep track of which channel - * we came from */ -void EXTI0_IRQHandler(void) { - ASSERT(exti_handlers[EXTI0]); - if (exti_handlers[EXTI0]) { - exti_handlers[EXTI0](); - } - - /* Clear pending bit*/ - clear_pending(EXTI0); -} - -void EXTI1_IRQHandler(void) { - ASSERT(exti_handlers[EXTI1]); - /* Call registered handler */ - if (exti_handlers[EXTI1]) { - exti_handlers[EXTI1](); - } - - /* Clear pending bit*/ - clear_pending(EXTI1); -} - -void EXTI2_IRQHandler(void) { - ASSERT(exti_handlers[EXTI2]); - /* Call registered handler */ - if (exti_handlers[EXTI2]) { - exti_handlers[EXTI2](); - } - - /* Clear pending bit*/ - clear_pending(EXTI2); -} - -void EXTI3_IRQHandler(void) { - ASSERT(exti_handlers[EXTI3]); - /* Call registered handler */ - if (exti_handlers[EXTI3]) { - exti_handlers[EXTI3](); - } - - /* Clear pending bit*/ - clear_pending(EXTI3); -} - -void EXTI4_IRQHandler(void) { - ASSERT(exti_handlers[EXTI4]); - /* Call registered handler */ - if (exti_handlers[EXTI4]) { - exti_handlers[EXTI4](); - } - - /* Clear pending bit*/ - clear_pending(EXTI4); -} - -void EXTI9_5_IRQHandler(void) { - /* Figure out which channel it came from */ - uint32_t pending; - uint32_t i; - pending = REG_GET(EXTI_PR); - pending = GET_BITS(pending, 5, 9); - - /* Dispatch every handler if the pending bit is set */ - for (i = 0; i < 5; i++) { - if (pending & 0x1) { - ASSERT(exti_handlers[EXTI5 + i]); - exti_handlers[EXTI5 + i](); - clear_pending(EXTI5 + i); - } - pending >>= 1; - } -} - -void EXTI15_10_IRQHandler(void) { - /* Figure out which channel it came from */ - uint32_t pending; - uint32_t i; - pending = REG_GET(EXTI_PR); - pending = GET_BITS(pending, 10, 15); - - /* Dispatch every handler if the pending bit is set */ - for (i = 0; i < 6; i++) { - if (pending & 0x1) { - ASSERT(exti_handlers[EXTI10 + i]); - exti_handlers[EXTI10 + i](); - clear_pending(EXTI10 + i); - } - pending >>= 1; - } -} - - -void exti_attach_interrupt(uint8_t channel, uint8_t port, voidFuncPtr handler, uint8_t mode) { - ASSERT(channel < NR_EXTI_CHANNELS); - ASSERT(port < NR_EXTI_PORTS); - ASSERT(mode < NR_EXTI_MODES); - ASSERT(EXTI0 == 0); - ASSERT(handler); - - /* Note: All of the following code assumes that EXTI0 = 0 */ - - /* Map port to the correct EXTI channel */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - REG_SET_MASK(AFIO_EXTICR1, BIT_MASK_SHIFT(port, channel*4)); - break; - - case EXTI4: - case EXTI5: - case EXTI6: - case EXTI7: - REG_SET_MASK(AFIO_EXTICR2, BIT_MASK_SHIFT(port, (channel-4)*4)); - break; - - case EXTI8: - case EXTI9: - case EXTI10: - case EXTI11: - REG_SET_MASK(AFIO_EXTICR3, BIT_MASK_SHIFT(port, (channel-8)*4)); - break; - - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - REG_SET_MASK(AFIO_EXTICR4, BIT_MASK_SHIFT(port, (channel-12)*4)); - break; - } - - /* Unmask appropriate interrupt line */ - REG_SET_BIT(EXTI_IMR, channel); - - /* Set trigger mode */ - switch (mode) { - case EXTI_RISING: - REG_SET_BIT(EXTI_RTSR, channel); - break; - - case EXTI_FALLING: - REG_SET_BIT(EXTI_FTSR, channel); - break; - - case EXTI_RISING_FALLING: - REG_SET_BIT(EXTI_RTSR, channel); - REG_SET_BIT(EXTI_FTSR, channel); - break; - } - - /* Configure the enable interrupt bits for the NVIC */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - case EXTI4: - REG_SET(NVIC_ISER0, BIT(channel + 6)); - break; - - /* EXTI5-9 map to the same isr */ - case EXTI5: - case EXTI6: - case EXTI7: - case EXTI8: - case EXTI9: - REG_SET(NVIC_ISER0, BIT(23)); - break; - - /* EXTI10-15 map to the same isr */ - case EXTI10: - case EXTI11: - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - REG_SET(NVIC_ISER1, BIT(8)); - break; - } - - /* Register the handler */ - exti_handlers[channel] = handler; -} - - -void exti_detach_interrupt(uint8_t channel) { - ASSERT(channel < NR_EXTI_CHANNELS); - ASSERT(EXTI0 == 0); - /* Is this interrupt actually on? */ - ASSERT((REG_GET(EXTI_IMR) >> channel) & 0x01); - - /* Clear EXTI_IMR line */ - REG_CLEAR_BIT(EXTI_IMR, channel); - - /* Clear triggers */ - REG_CLEAR_BIT(EXTI_FTSR, channel); - REG_CLEAR_BIT(EXTI_RTSR, channel); - - /* Turn off the associated interrupt */ - switch (channel) { - case EXTI0: - case EXTI1: - case EXTI2: - case EXTI3: - case EXTI4: - REG_SET(NVIC_ICER0, BIT(channel + 6)); - break; - case EXTI5: - case EXTI6: - case EXTI7: - case EXTI8: - case EXTI9: - /* Are there any other channels enabled? - * If so, don't disable the interrupt handler */ - if (GET_BITS(REG_GET(EXTI_IMR), 5, 9) == 0) { - REG_SET(NVIC_ICER0, BIT(23)); - } - break; - case EXTI10: - case EXTI11: - case EXTI12: - case EXTI13: - case EXTI14: - case EXTI15: - /* Are there any other channels enabled? - * If so, don't disable the interrupt handler */ - if (GET_BITS(REG_GET(EXTI_IMR), 10, 15) == 0) { - REG_SET(NVIC_ICER1, BIT(8)); - } - break; - } - - /* Clear handler function pointer */ - exti_handlers[channel] = 0; -} -- cgit v1.2.3