From 5b7d62c5490a3f4662c1ba77ab3f78a80ad6869d Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 28 Jul 2015 14:22:57 +0000 Subject: Updated EXT driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8121 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c | 83 +++++++++++++++++++-------------- os/hal/ports/STM32/LLD/EXTIv1/notes.txt | 23 +++++++++ 2 files changed, 71 insertions(+), 35 deletions(-) create mode 100644 os/hal/ports/STM32/LLD/EXTIv1/notes.txt (limited to 'os/hal/ports/STM32/LLD/EXTIv1') diff --git a/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c index 314ca2899..4b649dbf2 100644 --- a/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c +++ b/os/hal/ports/STM32/LLD/EXTIv1/ext_lld.c @@ -74,17 +74,17 @@ void ext_lld_init(void) { * @notapi */ void ext_lld_start(EXTDriver *extp) { - unsigned i; + expchannel_t line; if (extp->state == EXT_STOP) ext_lld_exti_irq_enable(); /* Configuration of automatic channels.*/ - for (i = 0; i < EXT_MAX_CHANNELS; i++) - if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART) - ext_lld_channel_enable(extp, i); + for (line = 0; line < EXT_MAX_CHANNELS; line++) + if (extp->config->channels[line].mode & EXT_CH_MODE_AUTOSTART) + ext_lld_channel_enable(extp, line); else - ext_lld_channel_disable(extp, i); + ext_lld_channel_disable(extp, line); } /** @@ -99,11 +99,12 @@ void ext_lld_stop(EXTDriver *extp) { if (extp->state == EXT_ACTIVE) ext_lld_exti_irq_disable(); - EXTI->EMR = 0; - EXTI->IMR = 0; - EXTI->PR = 0xFFFFFFFF; + EXTI->EMR = 0; + EXTI->IMR = STM32_EXTI_IMR_MASK; + EXTI->PR = ~STM32_EXTI_IMR_MASK; #if STM32_EXTI_NUM_LINES > 32 - EXTI->PR2 = 0xFFFFFFFF; + EXTI->IMR2 = STM32_EXTI_IMR2_MASK; + EXTI->PR2 = ~STM32_EXTI_IMR2_MASK; #endif } @@ -116,6 +117,7 @@ void ext_lld_stop(EXTDriver *extp) { * @notapi */ void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { + uint32_t cmask = (1 << (channel & 0x1F)); /* Setting the associated GPIO for external channels.*/ if (channel < 16) { @@ -135,46 +137,56 @@ void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { #if STM32_EXTI_NUM_LINES > 32 if (channel < 32) { #endif + /* Masked out lines must not be touched by this driver.*/ + if ((cmask & STM32_EXTI_IMR_MASK) != 0U) { + return; + } + /* Programming edge registers.*/ if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE) - EXTI->RTSR |= (1 << channel); + EXTI->RTSR |= cmask; else - EXTI->RTSR &= ~(1 << channel); + EXTI->RTSR &= ~cmask; if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE) - EXTI->FTSR |= (1 << channel); + EXTI->FTSR |= cmask; else - EXTI->FTSR &= ~(1 << channel); + EXTI->FTSR &= ~cmask; /* Programming interrupt and event registers.*/ if (extp->config->channels[channel].cb != NULL) { - EXTI->IMR |= (1 << channel); - EXTI->EMR &= ~(1 << channel); + EXTI->IMR |= cmask; + EXTI->EMR &= ~cmask; } else { - EXTI->EMR |= (1 << channel); - EXTI->IMR &= ~(1 << channel); + EXTI->EMR |= cmask; + EXTI->IMR &= ~cmask; } #if STM32_EXTI_NUM_LINES > 32 } else { + /* Masked out lines must not be touched by this driver.*/ + if ((cmask & STM32_EXTI_IMR2_MASK) != 0U) { + return; + } + /* Programming edge registers.*/ if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE) - EXTI->RTSR2 |= (1 << (32 - channel)); + EXTI->RTSR2 |= cmask; else - EXTI->RTSR2 &= ~(1 << (32 - channel)); + EXTI->RTSR2 &= ~cmask; if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE) - EXTI->FTSR2 |= (1 << (32 - channel)); + EXTI->FTSR2 |= cmask; else - EXTI->FTSR2 &= ~(1 << (32 - channel)); + EXTI->FTSR2 &= ~cmask; /* Programming interrupt and event registers.*/ if (extp->config->channels[channel].cb != NULL) { - EXTI->IMR2 |= (1 << (32 - channel)); - EXTI->EMR2 &= ~(1 << (32 - channel)); + EXTI->IMR2 |= cmask; + EXTI->EMR2 &= ~cmask; } else { - EXTI->EMR2 |= (1 << (32 - channel)); - EXTI->IMR2 &= ~(1 << (32 - channel)); + EXTI->EMR2 |= cmask; + EXTI->IMR2 &= ~cmask; } } #endif @@ -189,25 +201,26 @@ void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { * @notapi */ void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { + uint32_t cmask = (1 << (channel & 0x1F)); (void)extp; #if STM32_EXTI_NUM_LINES > 32 if (channel < 32) { #endif - EXTI->IMR &= ~(1 << channel); - EXTI->EMR &= ~(1 << channel); - EXTI->RTSR &= ~(1 << channel); - EXTI->FTSR &= ~(1 << channel); - EXTI->PR = (1 << channel); + EXTI->IMR &= ~cmask; + EXTI->EMR &= ~cmask; + EXTI->RTSR &= ~cmask; + EXTI->FTSR &= ~cmask; + EXTI->PR = cmask; #if STM32_EXTI_NUM_LINES > 32 } else { - EXTI->IMR2 &= ~(1 << (32 - channel)); - EXTI->EMR2 &= ~(1 << (32 - channel)); - EXTI->RTSR2 &= ~(1 << (32 - channel)); - EXTI->FTSR2 &= ~(1 << (32 - channel)); - EXTI->PR2 = (1 << (32 - channel)); + EXTI->IMR2 &= ~cmask; + EXTI->EMR2 &= ~cmask; + EXTI->RTSR2 &= ~cmask; + EXTI->FTSR2 &= ~cmask; + EXTI->PR2 = cmask; } #endif } diff --git a/os/hal/ports/STM32/LLD/EXTIv1/notes.txt b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt new file mode 100644 index 000000000..10eda50d4 --- /dev/null +++ b/os/hal/ports/STM32/LLD/EXTIv1/notes.txt @@ -0,0 +1,23 @@ +STM32 EXT driver implementation through EXTI unit. + +There are several kind of EXTI lines: + +1) GPIO lines. Always in range 0..15, always handled by the EXT driver. +2) Configurable peripheral events not shared, always handled by the EXT driver. +3) Configurable peripheral events shared with other, non EXTI, interrupts. + The EXTI driver declares the ISR and has to call the IRQ handler of the + other driver. +4) Direct lines (1 in IMR register after reset). The EXTI driver never touches + the default configuration for direct lines and does not declare ISRs. +5) Unused lines. The EXTI driver does not declare ISRs. + +The file registry must export: +STM32_EXTI_NUM_LINES - Range of configurable lines, it can have holes of + unused or direct lines. Configurable line numbers go + from 0 to STM32_EXTI_NUM_LINES-1. +STM32_EXTI_IMR_MASK - Direct lines and unused lines marked as 1 in this + mask, configurable lines marked as 0. +STM32_EXTI_IMR2_MASK - Optional, for lines 32...63. + +ISRs are not declared inside the driver, each sub-family must have its own +ext_lld_isr.h and ext_lld_isr.c files. -- cgit v1.2.3