From 78e93f99de4a504b7b8cfc528b641470aa147e9e Mon Sep 17 00:00:00 2001 From: Theodore Ateba Date: Mon, 31 Jul 2017 18:55:55 +0000 Subject: Remove the PCINT support from EXT driver because of a lot of conflicts. The PCINT will be reimplement. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10346 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.c | 669 +++++++++++------------------- os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.h | 450 +------------------- 2 files changed, 264 insertions(+), 855 deletions(-) (limited to 'os/hal') diff --git a/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.c b/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.c index c7875e690..72a236ced 100644 --- a/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.c +++ b/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.c @@ -1,7 +1,5 @@ /* - EXT Low Level Driver for ChibiOS - Copyright (C) 2015 Igor Stoppa - Copyright (C) 2016 Theodore Ateba + ChibiOS - Copyright (C) 2016 Theodore Ateba Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,7 +15,7 @@ */ /** - * @file hal_ext_lld.c + * @file AVR/hal_ext_lld.c * @brief AVR EXT subsystem low level driver source. * * @addtogroup EXT @@ -32,69 +30,12 @@ /* Driver local definitions. */ /*===========================================================================*/ -#define EXT_EICRA_LOW_LEVEL 0 -#define EXT_EICRA_BOTH_EDGES 1 -#define EXT_EICRA_FALLING_EDGE 2 -#define EXT_EICRA_RISING_EDGE 3 - -/** - * @brief Declares the isr for the ext channel specified - * - * @param[in] channel number of the channel - * - * @notapi - */ -#define declare_extint_isr(channel) \ -OSAL_IRQ_HANDLER(INT##channel##_vect) \ -{ \ - OSAL_IRQ_PROLOGUE(); \ - EXTD1.config->channels[EXT_INT##channel##_CHANNEL]. \ - cb(&EXTD1, EXT_INT##channel##_CHANNEL); \ - OSAL_IRQ_EPILOGUE(); \ -} - -/** - * @brief Declares the isr for the pc channel specified - * - * @param[in] port number of the port - * - * @notapi - */ -#define declare_pcint_isr(index) \ -OSAL_IRQ_HANDLER(PCINT##index##_vect) { \ - uint8_t changed_pins; \ - uint8_t i; \ - \ - OSAL_IRQ_PROLOGUE(); \ - EXTD1.pc_current_values[index] = (*(PINS[index])) & (*(PCMSK[index])); \ - \ - /* XOR to find the changed pin(s) */ \ - changed_pins = EXTD1.pc_current_values[index] ^ EXTD1.pc_old_values[index];\ - \ - for (i = 0; i < 8; i++) { \ - if (changed_pins & (1 << i)) { \ - const EXTChannelConfig *chn = \ - &EXTD1.config->channels[EXT_PCINT##index##_INDEX + i]; \ - \ - if (((chn->mode & EXT_CH_MODE_RISING_EDGE) && \ - ((EXTD1.pc_current_values[index] & (1 << i)) > 0)) || \ - ((chn->mode & EXT_CH_MODE_FALLING_EDGE) && \ - ((EXTD1.pc_current_values[index] & (1 << i)) == 0))) { \ - chn->cb(&EXTD1, EXT_PCINT##index##_INDEX + i - EXT_PCINT_MIN_INDEX); \ - } \ - } \ - } \ - \ - EXTD1.pc_old_values[index] = EXTD1.pc_current_values[index]; \ - OSAL_IRQ_EPILOGUE(); \ -} - /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ /** - * @brief EXT1 driver identifier. + * @brief EXTD1 driver identifier. */ EXTDriver EXTD1; @@ -102,313 +43,286 @@ EXTDriver EXTD1; /* Driver local variables and types. */ /*===========================================================================*/ -#if EXT_PC_NUM_PORTS > 0 -/** - * @brief Vector with addresses of Ports available. - */ -volatile uint8_t * const PINS[EXT_PC_NUM_PORTS] = { -#if AVR_EXT_USE_PCINT0 - (volatile uint8_t *const)&PCINT0_PIN, -#endif -#if AVR_EXT_USE_PCINT1 - (volatile uint8_t *const)&PCINT1_PIN, -#endif -#if AVR_EXT_USE_PCINT2 -(volatile uint8_t *const)&PCINT2_PIN, -#endif -#if AVR_EXT_USE_PCINT3 -(volatile uint8_t *const)&PCINT3_PIN, -#endif -#if AVR_EXT_USE_PCINT4 -(volatile uint8_t *const)&PCINT4_PIN, -#endif -#if AVR_EXT_USE_PCINT5 -(volatile uint8_t *const)&PCINT5_PIN, -#endif -#if AVR_EXT_USE_PCINT6 -(volatile uint8_t *const)&PCINT6_PIN, -#endif -#if AVR_EXT_USE_PCINT7 -(volatile uint8_t *const)&PCINT7_PIN, -#endif -#if AVR_EXT_USE_PCINT8 -(volatile uint8_t *const)&PCINT8_PIN, -#endif -#if AVR_EXT_USE_PCINT9 -(volatile uint8_t *const)&PCINT9_PIN, -#endif -#if AVR_EXT_USE_PCINT10 -(volatile uint8_t *const)&PCINT10_PIN, -#endif -}; +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ /** - * @brief Vector with addresses of Port Masks available. + * @brief Set the INTx interrupt trigger front or state. + * + * @param[in] channel the channel to configure + * @param[in] edge the front or state to configure */ -volatile uint8_t * const PCMSK[EXT_PC_NUM_PORTS] = { -#if AVR_EXT_USE_PCINT0 - (volatile uint8_t *const)&PCMSK0, -#endif -#if AVR_EXT_USE_PCINT1 - (volatile uint8_t *const)&PCMSK1, -#endif -#if AVR_EXT_USE_PCINT2 - (volatile uint8_t *const)&PCMSK2, -#endif -#if AVR_EXT_USE_PCINT3 - (volatile uint8_t *const)&PCMSK3, -#endif -#if AVR_EXT_USE_PCINT4 - (volatile uint8_t *const)&PCMSK4, -#endif -#if AVR_EXT_USE_PCINT5 - (volatile uint8_t *const)&PCMSK5, -#endif -#if AVR_EXT_USE_PCINT6 - (volatile uint8_t *const)&PCMSK6, +void ext_lld_set_intx_edges(expchannel_t channel, uint8_t edge) { + +#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__) + if (channel == INT0) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRA |= (1 << 0); + EICRA |= (1 << 1); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRA &= ~(1 << 0); + EICRA |= (1 << 1); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRA |= (1 << 0); + EICRA &= ~(1 << 1); + } else { + EICRA &= ~(1 << 0); + EICRA &= ~(1 << 1); + } + } #endif -#if AVR_EXT_USE_PCINT7 - (volatile uint8_t *const)&PCMSK7, +#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__) + if (channel == INT1) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRA |= (1 << 2); + EICRA |= (1 << 3); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRA &= ~(1 << 2); + EICRA |= (1 << 3); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRA |= (1 << 2); + EICRA &= ~(1 << 3); + } else { + EICRA &= ~(1 << 2); + EICRA &= ~(1 << 3); + } + } #endif -#if AVR_EXT_USE_PCINT8 - (volatile uint8_t *const)&PCMSK8, +#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__) + if (channel == INT2) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRA |= (1 << 4); + EICRA |= (1 << 5); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRA &= ~(1 << 4); + EICRA |= (1 << 5); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRA |= (1 << 4); + EICRA &= ~(1 << 5); + } else { + EICRA &= ~(1 << 4); + EICRA &= ~(1 << 5); + } + } #endif -#if AVR_EXT_USE_PCINT9 - (volatile uint8_t *const)&PCMSK9, +#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__) + if (channel == INT3) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRA |= (1 << 6); + EICRA |= (1 << 7); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRA &= ~(1 << 6); + EICRA |= (1 << 7); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRA |= (1 << 6); + EICRA &= ~(1 << 7); + } else { + EICRA &= ~(1 << 6); + EICRA &= ~(1 << 7); + } + } #endif -#if AVR_EXT_USE_PCINT10 - (volatile uint8_t *const)&PCMSK10, +#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__) + if (channel == INT4) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRB |= (1 << 0); + EICRB |= (1 << 1); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRB &= ~(1 << 0); + EICRB |= (1 << 1); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRB |= (1 << 0); + EICRB &= ~(1 << 1); + } else { + EICRB &= ~(1 << 0); + EICRB &= ~(1 << 1); + } + } #endif -}; +#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__) + if (channel == INT5) { + if (edge == EXT_CH_MODE_RISING_EDGE) { + EICRB |= (1 << 2); + EICRB |= (1 << 3); + } else if (edge == EXT_CH_MODE_FALLING_EDGE) { + EICRB &= ~(1 << 2); + EICRB |= (1 << 3); + } else if (edge == EXT_CH_MODE_BOTH_EDGES) { + EICRB |= (1 << 2); + EICRB &= ~(1 << 3); + } else { + EICRB &= ~(1 << 2); + EICRB &= ~(1 << 3); + } + } #endif +} /*===========================================================================*/ -/* Driver local functions. */ +/* Driver interrupt handlers. */ /*===========================================================================*/ -#if EXT_PC_NUM_PORTS > 0 +#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__) /** - * @brief Configures and activates the Pin Change inputs. + * @brief EXTI[INT0] interrupt handler. * - * @param[in] extp pointer to the @p EXTDriver object - * - * @notapi + * @isr */ -static void start_pc(EXTDriver *extp) { - uint8_t icr = 0; - uint8_t i; - - /* For every pin */ - for (i = 0; i < EXT_PC_NUM_CHANNELS; i++) { - uint8_t mode = extp->config->channels[i + EXT_PC_MIN_CHANNEL].mode; - - /* Only start if autostart and not disabled */ - if ((mode & EXT_CH_MODE_AUTOSTART) && ((mode & EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED)) { - (*(PCMSK[i/8])) |= _BV(i & 0x07); - } - } - - /* For every port */ - for (i = 0; i < EXT_PC_NUM_PORTS; i++) { - /* Only enable interrupt if at least 1 bit in the mask is set */ - if ((*(PCMSK[i])) != 0) { - /* Enable interrupt */ - icr |= (_BV(i)); - } - } - - /* Enables/disables the peripheral, as requested. */ -#if defined(__AVR_ATmega162__) - GICR &= ~(0x03 << 3); - GICR |= (icr << 3); -#else - PCICR = icr; -#endif +OSAL_IRQ_HANDLER(INT0_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT0].cb(&EXTD1, INT0); + OSAL_IRQ_EPILOGUE(); } - +#endif +#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__) /** - * @brief Deactivates the PC interrupts. - * - * @param[in] extp pointer to the @p EXTDriver object + * @brief EXTI[INT1] interrupt handler. + * + * @isr */ -static void stop_pc(EXTDriver *extp) { - uint8_t i; - (void)extp; - - /* Disable pin change interrupts */ -#if defined(__AVR_ATmega162__) - GICR &= ~(0x03 << 3); -#else - PCICR = 0; -#endif - - /* Clear masks */ - for (i = 0; i < EXT_PC_NUM_PORTS; i++) { - (*(PCMSK[i])) = 0; - } +OSAL_IRQ_HANDLER(INT1_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT1].cb(&EXTD1, INT1); + OSAL_IRQ_EPILOGUE(); } #endif - -#if EXT_INT_NUM_CHANNELS > 0 +#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__) /** - * @brief Configures and activates the INT inputs. + * @brief EXTI[INT2] interrupt handler. * - * @param[in] extp pointer to the @p EXTDriver object - * - * @notapi + * @isr */ -static void start_ext(EXTDriver *extp) { -#if EXT_INT_NUM_CHANNELS < 4 - uint8_t icr = 0; -#else - uint16_t icr = 0; -#endif - uint8_t msk = 0; - for (expchannel_t channel = EXT_INT_MIN_CHANNEL; - channel <= EXT_INT_MAX_CHANNEL; channel++) { - /* Determines the triggering condition for each channel. */ - switch(extp->config->channels[channel].mode & - ~(EXT_CH_MODE_AUTOSTART | EXT_CH_MODE_INTERNAL_PULLUP)) { - case EXT_CH_MODE_LOW_LEVEL: - icr |= (EXT_EICRA_LOW_LEVEL << (2 * (channel - EXT_INT_MIN_CHANNEL))); - break; - case EXT_CH_MODE_BOTH_EDGES: - icr |= (EXT_EICRA_BOTH_EDGES << (2 * (channel - EXT_INT_MIN_CHANNEL))); - break; - case EXT_CH_MODE_RISING_EDGE: - icr |= (EXT_EICRA_RISING_EDGE << (2 * (channel - EXT_INT_MIN_CHANNEL))); - break; - case EXT_CH_MODE_FALLING_EDGE: - icr |= (EXT_EICRA_FALLING_EDGE << (2 * (channel - EXT_INT_MIN_CHANNEL))); - break; - default: osalDbgAssert(FALSE, "unsupported mode"); - } - - /* Determines which channel must be started right away. */ - if (extp->config->channels[channel].mode & EXT_CH_MODE_AUTOSTART) { - msk |= (1 << (channel - EXT_INT_MIN_CHANNEL)); - } - } - /* Configures the peripheral. */ -#if defined(__AVR_ATmega162__) - MCUCR |= (icr & 0x0f); - - icr >>= 4; - osalDbgAssert(((icr & 0x02) == EXT_EICRA_RISING_EDGE) || ((icr & 0x02) == EXT_EICRA_FALLING_EDGE), "INT2 only supports rising or falling edge, not both."); - EMCUCR |= icr & 0x01; - - GICR |= ((msk & 0x03) << 6); - if (icr & 0x01) { - /* Enable INT2 */ - GICR |= (1 << 5); - } -#else - EICRA = icr & 0xff; -#if EXT_INT_NUM_CHANNELS > 4 - EICRB = icr >> 8; -#endif - /* Enables/disables the peripheral, as requested. */ - EIMSK = msk; -#endif +OSAL_IRQ_HANDLER(INT2_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT2].cb(&EXTD1, INT2); + OSAL_IRQ_EPILOGUE(); } - +#endif +#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__) /** - * @brief Deactivates the INT interrupts. - * - * @param[in] extp pointer to the @p EXTDriver object + * @brief EXTI[INT3] interrupt handler. + * + * @isr */ -static void stop_ext(EXTDriver *extp) { - (void)extp; -#if defined(__AVR_ATmega162__) - MCUCR &= ~(0x0f); - EMCUCR &= ~(0x01); - GICR |= ~(0x07 << 5); -#else - EICRA = 0; -#if EXT_INT_NUM_CHANNELS > 4 - EICRB = 0; +OSAL_IRQ_HANDLER(INT3_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT3].cb(&EXTD1, INT3); + OSAL_IRQ_EPILOGUE(); +} #endif - /* Enables/disables the peripheral, as requested. */ - EIMSK = 0; +#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__) +/** + * @brief EXTI[INT4] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(INT4_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT4].cb(&EXTD1, INT4); + OSAL_IRQ_EPILOGUE(); +} #endif +#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__) +/** + * @brief EXTI[INT5] interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(INT5_vect) { + OSAL_IRQ_PROLOGUE(); + EXTD1.config->channels[INT5].cb(&EXTD1, INT5); + OSAL_IRQ_EPILOGUE(); } #endif /*===========================================================================*/ -/* Driver interrupt handlers. */ +/* Driver functions. */ /*===========================================================================*/ -/* - * Interrupt handlers for PC-type interrupts. +/** + * @brief Enables an EXT channel. + * + * @param[in] extp pointer to the @p EXTDriver object + * @param[in] channel channel to be enabled + * + * @notapi */ -#define EXT_PCINT_MIN_INDEX EXT_PC_MIN_PORT +void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { -#if 0 < EXT_PC_NUM_PORTS -#define EXT_PCINT0_INDEX EXT_PCINT_MIN_INDEX -declare_pcint_isr(0); -#endif -#if 1 < EXT_PC_NUM_PORTS -#define EXT_PCINT1_INDEX (EXT_PCINT0_INDEX + 1) -declare_pcint_isr(1); -#endif -#if 2 < EXT_PC_NUM_PORTS -#define EXT_PCINT2_INDEX (EXT_PCINT1_INDEX + 1) -declare_pcint_isr(2); -#endif -#if 3 < EXT_PC_NUM_PORTS -#define EXT_PCINT3_INDEX (EXT_PCINT2_INDEX + 1) -declare_pcint_isr(3); -#endif -#if 4 < EXT_PC_NUM_PORTS -#define EXT_PCINT4_INDEX (EXT_PCINT3_INDEX + 1) -declare_pcint_isr(4); +#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__) + if (channel == INT0) { + EIMSK |= 1 << INT0; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif -#if 5 < EXT_PC_NUM_PORTS -#define EXT_PCINT5_INDEX (EXT_PCINT4_INDEX + 1) -declare_pcint_isr(5); +#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__) + if (channel == INT1) { + EIMSK |= 1 << INT1; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif -#if 6 < EXT_PC_NUM_PORTS -#define EXT_PCINT6_INDEX (EXT_PCINT5_INDEX + 1) -declare_pcint_isr(6); +#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__) + if (channel == INT2) { + EIMSK |= 1 << INT2; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif -#if 7 < EXT_PC_NUM_PORTS -#define EXT_PCINT7_INDEX (EXT_PCINT6_INDEX + 1) -declare_pcint_isr(7); +#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__) + if (channel == INT3) { + EIMSK |= 1 << INT3; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif -#if 8 < EXT_PC_NUM_PORTS -#define EXT_PCINT8_INDEX (EXT_PCINT7_INDEX + 1) -declare_pcint_isr(8); +#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__) + if (channel == INT4) { + EIMSK |= 1 << INT4; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif -#if 9 < EXT_PC_NUM_PORTS -#define EXT_PCINT9_INDEX (EXT_PCINT8_INDEX + 1) -declare_pcint_isr(9); +#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__) + if (channel == INT5) { + EIMSK |= 1 << INT5; + ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode); + } #endif +} -/* - * Interrupt handlers for INT-type interrupts. +/** + * @brief Disables an EXT channel. + * + * @param[in] extp pinter to the @p EXTDriver object + * @param[in] channel channel to be disabled + * + * @notapi */ -#if 0 < EXT_INT_NUM_CHANNELS -declare_extint_isr(0); +void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { + +#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__) + if (channel == INT0) + EIMSK &= ~(1 << INT0); #endif -#if 1 < EXT_INT_NUM_CHANNELS -declare_extint_isr(1); +#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__) + if (channel == INT1) + EIMSK &= ~(1 << INT1); #endif -#if 2 < EXT_INT_NUM_CHANNELS -declare_extint_isr(2); +#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__) + if (channel == INT2) + EIMSK &= ~(1 << INT2); #endif -#if 3 < EXT_INT_NUM_CHANNELS -declare_extint_isr(3); +#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__) + if (channel == INT3) + EIMSK &= ~(1 << INT3); #endif -#if 4 < EXT_INT_NUM_CHANNELS -declare_extint_isr(4); +#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__) + if (channel == INT4) + EIMSK &= ~(1 << INT4); #endif -#if 5 < EXT_INT_NUM_CHANNELS -declare_extint_isr(5); +#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__) + if (channel == INT5) + EIMSK &= ~(1 << INT5); #endif - -/*===========================================================================*/ -/* Driver functions. */ -/*===========================================================================*/ +} /** * @brief Low level EXT driver initialization. @@ -416,133 +330,48 @@ declare_extint_isr(5); * @notapi */ void ext_lld_init(void) { + /* Driver initialization.*/ extObjectInit(&EXTD1); -#if EXT_PC_NUM_PORTS > 0 - for (int i = 0; i < EXT_PC_NUM_PORTS; i++) { - EXTD1.pc_old_values[i] = 0; - } -#endif } /** * @brief Configures and activates the EXT peripheral. * - * @param[in] extp pointer to the @p EXTDriver object + * @param[in] extp pointer to the @p EXTDriver object * * @notapi */ void ext_lld_start(EXTDriver *extp) { -#if EXT_INT_NUM_CHANNELS > 0 - start_ext(extp); -#endif -#if EXT_PC_NUM_PORTS > 0 - start_pc(extp); -#endif -} - -/** - * @brief Deactivates the EXT peripheral. - * - * @param[in] extp pointer to the @p EXTDriver object - * - * @notapi - */ -void ext_lld_stop(EXTDriver *extp) { - if (extp->state == EXT_ACTIVE) { - /* Disables the peripheral.*/ -#if EXT_INT_NUM_CHANNELS > 0 - stop_ext(extp); -#endif -#if EXT_PC_NUM_PORTS > 0 - stop_pc(extp); -#endif - } -} - -/** - * @brief Enables an EXT channel. - * - * @param[in] extp pointer to the @p EXTDriver object - * @param[in] channel channel to be enabled - * - * @notapi - */ -void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) { - (void)extp; -#if EXT_PC_NUM_CHANNELS > 0 - if (EXT_PC_MIN_CHANNEL <= channel && channel <= EXT_PC_MAX_CHANNEL) { - uint8_t port = (channel - EXT_PC_MIN_CHANNEL) / 8; + expchannel_t line; - /* Enable bit in mask */ - (*(PCMSK[port])) |= _BV((channel - EXT_PC_MIN_CHANNEL) % 8); + if (extp->state == EXT_STOP) + osalSysUnlock(); - /* Always enable interrupt */ -#if defined(__AVR_ATmega162__) - GICR |= (_BV(port) << 3); -#else - PCICR |= _BV(port); -#endif - } -#endif -#if EXT_PC_NUM_CHANNELS > 0 && EXT_INT_NUM_CHANNELS > 0 - else -#endif -#if EXT_INT_NUM_CHANNELS > 0 - if (channel <= EXT_INT_MAX_CHANNEL) { -#if defined(__AVR_ATmega162__) - GICR |= ((1 << channel) << 5); -#else - /* Enables/disables the peripheral, as requested. */ - EIMSK |= (1 << channel); -#endif + /* Configuration of automatic channels. */ + 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, line); } -#endif } /** - * @brief Disables an EXT channel. + * @brief Deactivates the EXT peripheral. * - * @param[in] extp pointer to the @p EXTDriver object - * @param[in] channel channel to be disabled + * @param[in] extp pointer to the @p EXTDriver object * * @notapi */ -void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) { - (void)extp; -#if EXT_PC_NUM_CHANNELS > 0 - if (EXT_PC_MIN_CHANNEL <= channel && channel <= EXT_PC_MAX_CHANNEL) { - uint8_t port = (channel - EXT_PC_MIN_CHANNEL) / 8; - - /* Clear bit in mask */ - (*(PCMSK[port])) &= ~(_BV((channel - EXT_PC_MIN_CHANNEL) % 8)); +void ext_lld_stop(EXTDriver *extp) { - /* Disable interrupt if no bits are set */ - if ((*(PCMSK[port])) == 0) { -#if defined(__AVR_ATmega162__) - GICR &= ~(_BV(port) << 3); -#else - PCICR |= ~(_BV(port)); -#endif - } - } -#endif -#if EXT_PC_NUM_CHANNELS > 0 && EXT_INT_NUM_CHANNELS > 0 - else -#endif -#if EXT_INT_NUM_CHANNELS > 0 - if (channel <= EXT_INT_MAX_CHANNEL) { -#if defined(__AVR_ATmega162__) - GICR &= ~((1 << channel) << 5); -#else - /* Enables/disables the peripheral, as requested. */ - EIMSK &= ~(1 << channel); -#endif - } -#endif + if (extp->state == EXT_ACTIVE) + osalSysLock(); } #endif /* HAL_USE_EXT */ /** @} */ + diff --git a/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.h b/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.h index 4dc125d27..6707f9cda 100644 --- a/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.h +++ b/os/hal/ports/AVR/MEGA/EXTv1/hal_ext_lld.h @@ -1,7 +1,5 @@ /* - EXT Low Level Driver for ChibiOS - Copyright (C) 2015 Igor Stoppa - Copyright (C) 2016 Theodore Ateba + ChibiOS - Copyright (C) 2016 Theodore Ateba Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,14 +16,14 @@ /** * @file AVR/hal_ext_lld.h - * @brief EXT Driver subsystem low level driver header. + * @brief EXT Driver subsystem low level driver source. * * @addtogroup EXT * @{ */ -#ifndef HAL_EXT_LLD_H -#define HAL_EXT_LLD_H +#ifndef _HAL_EXT_LLD_H_ +#define _HAL_EXT_LLD_H_ #if HAL_USE_EXT || defined(__DOXYGEN__) @@ -34,425 +32,23 @@ /*===========================================================================*/ /** - * @brief Level-driven irq generation. + * @brief Maximum number of EXT channels. */ -#define EXT_CH_MODE_LEVELS_MASK 8U /**< @brief Mask of levels field. */ -#undef EXT_CH_MODE_LOW_LEVEL -#define EXT_CH_MODE_LOW_LEVEL 8U /**< @brief Trigger on Low level. */ -#define EXT_CH_MODE_INTERNAL_PULLUP 16U /**< @brief Use internal pullup. */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name AVR configuration options - * @{ - */ -/** - * @brief INT0 support enable switch. - * @details If set to @p TRUE the support for INT0 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_INT0) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT0 FALSE -#endif - -/** - * @brief INT1 support enable switch. - * @details If set to @p TRUE the support for INT1 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_INT1) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT1 FALSE -#endif - -/** - * @brief INT2 support enable switch. - * @details If set to @p TRUE the support for INT2 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_INT2) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT2 FALSE -#endif - -/** - * @brief INT3 support enable switch. - * @details If set to @p TRUE the support for INT3 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_INT3) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT3 FALSE -#endif - -/** - * @brief INT4 support enable switch. - * @details If set to @p TRUE the support for INT4 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_INT4) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT4 FALSE -#endif +#define AVR_INT_NUM_LINES 6 /**< INT0 to INT5 */ /** - * @brief INT5 support enable switch. - * @details If set to @p TRUE the support for INT5 is included. - * @note The default is @p FALSE. + * @brief Available number of EXT channels. */ -#if !defined(AVR_EXT_USE_INT5) || defined(__DOXYGEN__) -#define AVR_EXT_USE_INT5 FALSE -#endif - -/** - * @brief PCINT0 support enable switch. - * @details If set to @p TRUE the support for PCINT0 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT0) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT0 FALSE -#endif +#define EXT_MAX_CHANNELS AVR_INT_NUM_LINES -/** - * @brief PCINT1 support enable switch. - * @details If set to @p TRUE the support for PCINT1 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT1) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT1 FALSE -#endif - -/** - * @brief PCINT2 support enable switch. - * @details If set to @p TRUE the support for PCINT2 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT2) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT2 FALSE -#endif - -/** - * @brief PCINT3 support enable switch. - * @details If set to @p TRUE the support for PCINT3 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT3) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT3 FALSE -#endif - -/** - * @brief PCINT4 support enable switch. - * @details If set to @p TRUE the support for PCINT4 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT4) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT4 FALSE -#endif - -/** - * @brief PCINT5 support enable switch. - * @details If set to @p TRUE the support for PCINT5 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT5) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT5 FALSE -#endif - -/** - * @brief PCINT6 support enable switch. - * @details If set to @p TRUE the support for PCINT6 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT6) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT6 FALSE -#endif - -/** - * @brief PCINT7 support enable switch. - * @details If set to @p TRUE the support for PCINT7 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT7) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT7 FALSE -#endif - -/** - * @brief PCINT8 support enable switch. - * @details If set to @p TRUE the support for PCINT8 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT8) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT8 FALSE -#endif - -/** - * @brief PCINT9 support enable switch. - * @details If set to @p TRUE the support for PCINT9 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT9) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT9 FALSE -#endif - -/** - * @brief PCINT10 support enable switch. - * @details If set to @p TRUE the support for PCINT10 is included. - * @note The default is @p FALSE. - */ -#if !defined(AVR_EXT_USE_PCINT10) || defined(__DOXYGEN__) -#define AVR_EXT_USE_PCINT10 FALSE -#endif -/** @} */ +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -#if !defined(INT0_vect) && AVR_EXT_USE_INT0 -#error "INT0 is not present in the selected device" -#endif - -#if !defined(INT1_vect) && AVR_EXT_USE_INT1 -#error "INT1 is not present in the selected device" -#endif - -#if !defined(INT2_vect) && AVR_EXT_USE_INT2 -#error "INT2 is not present in the selected device" -#endif - -#if !defined(INT3_vect) && AVR_EXT_USE_INT3 -#error "INT3 is not present in the selected device" -#endif - -#if !defined(INT4_vect) && AVR_EXT_USE_INT4 -#error "INT4 is not present in the selected device" -#endif - -#if !defined(INT5_vect) && AVR_EXT_USE_INT5 -#error "INT5 is not present in the selected device" -#endif - -#if !defined(PCINT0_PIN) && AVR_EXT_USE_PCINT0 -#error "PCINT0 is not present in the selected device" -#endif - -#if !defined(PCINT1_PIN) && AVR_EXT_USE_PCINT1 -#error "PCINT1 is not present in the selected device" -#endif - -#if !defined(PCINT2_PIN) && AVR_EXT_USE_PCINT2 -#error "PCINT2 is not present in the selected device" -#endif - -#if !defined(PCINT3_PIN) && AVR_EXT_USE_PCINT3 -#error "PCINT3 is not present in the selected device" -#endif - -#if !defined(PCINT4_PIN) && AVR_EXT_USE_PCINT4 -#error "PCINT4 is not present in the selected device" -#endif - -#if !defined(PCINT5_PIN) && AVR_EXT_USE_PCINT5 -#error "PCINT5 is not present in the selected device" -#endif - -#if !defined(PCINT6_PIN) && AVR_EXT_USE_PCINT6 -#error "PCINT6 is not present in the selected device" -#endif - -#if !defined(PCINT7_PIN) && AVR_EXT_USE_PCINT7 -#error "PCINT7 is not present in the selected device" -#endif - -#if !defined(PCINT8_PIN) && AVR_EXT_USE_PCINT8 -#error "PCINT8 is not present in the selected device" -#endif - -#if !defined(PCINT9_PIN) && AVR_EXT_USE_PCINT9 -#error "PCINT9 is not present in the selected device" -#endif - -#if !defined(PCINT10_PIN) && AVR_EXT_USE_PCINT10 -#error "PCINT10 is not present in the selected device" -#endif - -/** - * @brief Indexes of INT channels. - */ -#define EXT_INT_MIN_CHANNEL 0 - -#if AVR_EXT_USE_INT0 -#define EXT_INT0_PRESENT 1 -#define EXT_INT0_CHANNEL EXT_INT_MIN_CHANNEL -#else -#define EXT_INT0_PRESENT 0 -#define EXT_INT0_CHANNEL (EXT_INT_MIN_CHANNEL - 1) -#endif - -#if AVR_EXT_USE_INT1 -#define EXT_INT1_PRESENT 1 -#define EXT_INT1_CHANNEL (EXT_INT0_CHANNEL + 1) -#else -#define EXT_INT1_PRESENT 0 -#define EXT_INT1_CHANNEL EXT_INT0_CHANNEL -#endif - -#if AVR_EXT_USE_INT2 -#define EXT_INT2_PRESENT 1 -#define EXT_INT2_CHANNEL (EXT_INT1_CHANNEL + 1) -#else -#define EXT_INT2_PRESENT 0 -#define EXT_INT2_CHANNEL EXT_INT1_CHANNEL -#endif - -#if AVR_EXT_USE_INT3 -#define EXT_INT3_PRESENT 1 -#define EXT_INT3_CHANNEL (EXT_INT2_CHANNEL + 1) -#else -#define EXT_INT3_PRESENT 0 -#define EXT_INT3_CHANNEL EXT_INT2_CHANNEL -#endif - -#if AVR_EXT_USE_INT4 -#define EXT_INT4_PRESENT 1 -#define EXT_INT4_CHANNEL (EXT_INT3_CHANNEL + 1) -#else -#define EXT_INT4_PRESENT 0 -#define EXT_INT4_CHANNEL EXT_INT3_CHANNEL -#endif - -#if AVR_EXT_USE_INT5 -#define EXT_INT5_PRESENT 1 -#define EXT_INT5_CHANNEL (EXT_INT4_CHANNEL + 1) -#else -#define EXT_INT5_PRESENT 0 -#define EXT_INT5_CHANNEL EXT_INT4_CHANNEL -#endif - -#define EXT_INT_NUM_CHANNELS \ - (EXT_INT0_PRESENT + EXT_INT1_PRESENT + EXT_INT2_PRESENT + \ - EXT_INT3_PRESENT + EXT_INT4_PRESENT + EXT_INT5_PRESENT) - -#if EXT_INT_NUM_CHANNELS > 0 -#define EXT_INT_MAX_CHANNEL (EXT_INT_MIN_CHANNEL + EXT_INT_NUM_CHANNELS - 1) -#else -#define EXT_INT_MAX_CHANNEL 0 -#endif - -/** - * @brief Indexes of PC channels. - */ -#define EXT_PC_MIN_PORT EXT_INT_NUM_CHANNELS - -#if AVR_EXT_USE_PCINT0 -#define PORTA_PRESENT 1 -#define PORTA_INDEX EXT_PC_MIN_PORT -#else -#define PORTA_PRESENT 0 -#define PORTA_INDEX (EXT_PC_MIN_PORT - 1) -#endif - -#if AVR_EXT_USE_PCINT1 -#define PORTB_PRESENT 1 -#define PORTB_INDEX (PORTA_INDEX + 1) -#else -#define PORTB_PRESENT 0 -#define PORTB_INDEX PORTA_INDEX -#endif - -#if AVR_EXT_USE_PCINT2 -#define PORTC_PRESENT 1 -#define PORTC_INDEX (PORTB_INDEX + 1) -#else -#define PORTC_PRESENT 0 -#define PORTC_INDEX PORTB_INDEX -#endif - -#if AVR_EXT_USE_PCINT3 -#define PORTD_PRESENT 1 -#define PORTD_INDEX (PORTC_INDEX + 1) -#else -#define PORTD_PRESENT 0 -#define PORTD_INDEX PORTC_INDEX -#endif - -#if AVR_EXT_USE_PCINT4 -#define PORTE_PRESENT 1 -#define PORTE_INDEX (PORTD_INDEX + 1) -#else -#define PORTE_PRESENT 0 -#define PORTE_INDEX PORTD_INDEX -#endif - -#if AVR_EXT_USE_PCINT5 -#define PORTF_PRESENT 1 -#define PORTF_INDEX (PORTE_INDEX + 1) -#else -#define PORTF_PRESENT 0 -#define PORTF_INDEX PORTE_INDEX -#endif - -#if AVR_EXT_USE_PCINT6 -#define PORTG_PRESENT 1 -#define PORTG_INDEX (PORTF_INDEX + 1) -#else -#define PORTG_PRESENT 0 -#define PORTG_INDEX PORTF_INDEX -#endif - -#if AVR_EXT_USE_PCINT7 -#define PORTH_PRESENT 1 -#define PORTH_INDEX (PORTG_INDEX + 1) -#else -#define PORTH_PRESENT 0 -#define PORTH_INDEX PORTG_INDEX -#endif - -#if AVR_EXT_USE_PCINT8 -#define PORTI_PRESENT 1 -#define PORTI_INDEX (PORTH_INDEX + 1) -#else -#define PORTI_PRESENT 0 -#define PORTI_INDEX PORTH_INDEX -#endif - -#if AVR_EXT_USE_PCINT9 -#define PORTJ_PRESENT 1 -#define PORTJ_INDEX (PORTI_INDEX + 1) -#else -#define PORTJ_PRESENT 0 -#define PORTJ_INDEX PORTI_INDEX -#endif - -#if AVR_EXT_USE_PCINT10 -#define PORTK_PRESENT 1 -#define PORTK_INDEX (PORTJ_INDEX + 1) -#else -#define PORTK_PRESENT 0 -#define PORTK_INDEX PORTJ_INDEX -#endif - -/** - * @brief Available number of PC ports. - */ - -#define EXT_PC_NUM_PORTS \ - (PORTA_PRESENT + PORTB_PRESENT + PORTC_PRESENT + PORTD_PRESENT + \ - PORTE_PRESENT + PORTF_PRESENT + PORTG_PRESENT + PORTH_PRESENT + \ - PORTI_PRESENT + PORTJ_PRESENT + PORTK_PRESENT) - -#if EXT_PC_NUM_PORTS > 0 -#define EXT_PC_MAX_PORT (EXT_PC_MIN_PORT + EXT_PC_NUM_PORTS - 1) -#else -#define EXT_PC_MAX_PORT 0 -#endif - -#define EXT_PC_NUM_CHANNELS (EXT_PC_NUM_PORTS * 8) - -#define EXT_TOTAL_CHANNELS (EXT_INT_NUM_CHANNELS + EXT_PC_NUM_CHANNELS) -#define EXT_MAX_CHANNELS EXT_TOTAL_CHANNELS -#define EXT_PC_MIN_CHANNEL EXT_INT_NUM_CHANNELS -#define EXT_PC_MAX_CHANNEL (EXT_PC_MIN_CHANNEL + EXT_PC_NUM_CHANNELS - 1) - /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -467,7 +63,6 @@ typedef uint16_t expchannel_t; * * @param[in] extp pointer to the @p EXPDriver object triggering the * callback - * @param[in] channel channel being triggered. */ typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel); @@ -476,9 +71,9 @@ typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel); */ typedef struct { /** - * @brief Channel mode from HAL. + * @brief Channel mode. */ - uint8_t mode; + uint32_t mode; /** * @brief Channel callback. */ @@ -493,7 +88,7 @@ typedef struct { /** * @brief Channel configurations. */ - EXTChannelConfig channels[EXT_TOTAL_CHANNELS]; + EXTChannelConfig channels[EXT_MAX_CHANNELS]; /* End of the mandatory fields.*/ } EXTConfig; @@ -511,29 +106,15 @@ struct EXTDriver { */ const EXTConfig *config; /* End of the mandatory fields.*/ -#if EXT_PC_NUM_PORTS > 0 - /** - * @brief Current pin values. Only valid for PCINT. - */ - uint8_t pc_current_values[EXT_PC_NUM_PORTS]; - /** - * @brief Previous pin states. Only valid for PCINT. - */ - uint8_t pc_old_values[EXT_PC_NUM_PORTS]; -#endif }; /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ -#define ext_port_to_channel(port, bit) \ - ((PORT##port##_INDEX - EXT_PC_MIN_PORT) * 8 + bit) - /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ - extern EXTDriver EXTD1; #ifdef __cplusplus @@ -550,6 +131,5 @@ extern "C" { #endif /* HAL_USE_EXT */ -#endif /* HAL_EXT_LLD_H */ +#endif /* _HAL_EXT_LLD_H_ */ -/** @} */ -- cgit v1.2.3