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
This commit is contained in:
parent
0e4213f267
commit
78e93f99de
|
@ -1,7 +1,5 @@
|
||||||
/*
|
/*
|
||||||
EXT Low Level Driver for ChibiOS
|
ChibiOS - Copyright (C) 2016 Theodore Ateba
|
||||||
Copyright (C) 2015 Igor Stoppa <igor.stoppa@gmail.com>
|
|
||||||
Copyright (C) 2016 Theodore Ateba
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with 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.
|
* @brief AVR EXT subsystem low level driver source.
|
||||||
*
|
*
|
||||||
* @addtogroup EXT
|
* @addtogroup EXT
|
||||||
|
@ -32,69 +30,12 @@
|
||||||
/* Driver local definitions. */
|
/* 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. */
|
/* Driver exported variables. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief EXT1 driver identifier.
|
* @brief EXTD1 driver identifier.
|
||||||
*/
|
*/
|
||||||
EXTDriver EXTD1;
|
EXTDriver EXTD1;
|
||||||
|
|
||||||
|
@ -102,365 +43,203 @@ EXTDriver EXTD1;
|
||||||
/* Driver local variables and types. */
|
/* 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
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Vector with addresses of Port Masks available.
|
|
||||||
*/
|
|
||||||
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,
|
|
||||||
#endif
|
|
||||||
#if AVR_EXT_USE_PCINT7
|
|
||||||
(volatile uint8_t *const)&PCMSK7,
|
|
||||||
#endif
|
|
||||||
#if AVR_EXT_USE_PCINT8
|
|
||||||
(volatile uint8_t *const)&PCMSK8,
|
|
||||||
#endif
|
|
||||||
#if AVR_EXT_USE_PCINT9
|
|
||||||
(volatile uint8_t *const)&PCMSK9,
|
|
||||||
#endif
|
|
||||||
#if AVR_EXT_USE_PCINT10
|
|
||||||
(volatile uint8_t *const)&PCMSK10,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#if EXT_PC_NUM_PORTS > 0
|
|
||||||
/**
|
/**
|
||||||
* @brief Configures and activates the Pin Change inputs.
|
* @brief Set the INTx interrupt trigger front or state.
|
||||||
*
|
*
|
||||||
* @param[in] extp pointer to the @p EXTDriver object
|
* @param[in] channel the channel to configure
|
||||||
*
|
* @param[in] edge the front or state to configure
|
||||||
* @notapi
|
|
||||||
*/
|
*/
|
||||||
static void start_pc(EXTDriver *extp) {
|
void ext_lld_set_intx_edges(expchannel_t channel, uint8_t edge) {
|
||||||
uint8_t icr = 0;
|
|
||||||
uint8_t i;
|
|
||||||
|
|
||||||
/* For every pin */
|
#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__)
|
||||||
for (i = 0; i < EXT_PC_NUM_CHANNELS; i++) {
|
if (channel == INT0) {
|
||||||
uint8_t mode = extp->config->channels[i + EXT_PC_MIN_CHANNEL].mode;
|
if (edge == EXT_CH_MODE_RISING_EDGE) {
|
||||||
|
EICRA |= (1 << 0);
|
||||||
/* Only start if autostart and not disabled */
|
EICRA |= (1 << 1);
|
||||||
if ((mode & EXT_CH_MODE_AUTOSTART) && ((mode & EXT_CH_MODE_EDGES_MASK) != EXT_CH_MODE_DISABLED)) {
|
} else if (edge == EXT_CH_MODE_FALLING_EDGE) {
|
||||||
(*(PCMSK[i/8])) |= _BV(i & 0x07);
|
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
|
||||||
/* For every port */
|
#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__)
|
||||||
for (i = 0; i < EXT_PC_NUM_PORTS; i++) {
|
if (channel == INT1) {
|
||||||
/* Only enable interrupt if at least 1 bit in the mask is set */
|
if (edge == EXT_CH_MODE_RISING_EDGE) {
|
||||||
if ((*(PCMSK[i])) != 0) {
|
EICRA |= (1 << 2);
|
||||||
/* Enable interrupt */
|
EICRA |= (1 << 3);
|
||||||
icr |= (_BV(i));
|
} 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enables/disables the peripheral, as requested. */
|
|
||||||
#if defined(__AVR_ATmega162__)
|
|
||||||
GICR &= ~(0x03 << 3);
|
|
||||||
GICR |= (icr << 3);
|
|
||||||
#else
|
|
||||||
PCICR = icr;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT2) {
|
||||||
/**
|
if (edge == EXT_CH_MODE_RISING_EDGE) {
|
||||||
* @brief Deactivates the PC interrupts.
|
EICRA |= (1 << 4);
|
||||||
*
|
EICRA |= (1 << 5);
|
||||||
* @param[in] extp pointer to the @p EXTDriver object
|
} else if (edge == EXT_CH_MODE_FALLING_EDGE) {
|
||||||
*/
|
EICRA &= ~(1 << 4);
|
||||||
static void stop_pc(EXTDriver *extp) {
|
EICRA |= (1 << 5);
|
||||||
uint8_t i;
|
} else if (edge == EXT_CH_MODE_BOTH_EDGES) {
|
||||||
(void)extp;
|
EICRA |= (1 << 4);
|
||||||
|
EICRA &= ~(1 << 5);
|
||||||
/* Disable pin change interrupts */
|
} else {
|
||||||
#if defined(__AVR_ATmega162__)
|
EICRA &= ~(1 << 4);
|
||||||
GICR &= ~(0x03 << 3);
|
EICRA &= ~(1 << 5);
|
||||||
#else
|
|
||||||
PCICR = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Clear masks */
|
|
||||||
for (i = 0; i < EXT_PC_NUM_PORTS; i++) {
|
|
||||||
(*(PCMSK[i])) = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if EXT_INT_NUM_CHANNELS > 0
|
|
||||||
/**
|
|
||||||
* @brief Configures and activates the INT inputs.
|
|
||||||
*
|
|
||||||
* @param[in] extp pointer to the @p EXTDriver object
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
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. */
|
#endif
|
||||||
#if defined(__AVR_ATmega162__)
|
#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__)
|
||||||
MCUCR |= (icr & 0x0f);
|
if (channel == INT3) {
|
||||||
|
if (edge == EXT_CH_MODE_RISING_EDGE) {
|
||||||
icr >>= 4;
|
EICRA |= (1 << 6);
|
||||||
osalDbgAssert(((icr & 0x02) == EXT_EICRA_RISING_EDGE) || ((icr & 0x02) == EXT_EICRA_FALLING_EDGE), "INT2 only supports rising or falling edge, not both.");
|
EICRA |= (1 << 7);
|
||||||
EMCUCR |= icr & 0x01;
|
} else if (edge == EXT_CH_MODE_FALLING_EDGE) {
|
||||||
|
EICRA &= ~(1 << 6);
|
||||||
GICR |= ((msk & 0x03) << 6);
|
EICRA |= (1 << 7);
|
||||||
if (icr & 0x01) {
|
} else if (edge == EXT_CH_MODE_BOTH_EDGES) {
|
||||||
/* Enable INT2 */
|
EICRA |= (1 << 6);
|
||||||
GICR |= (1 << 5);
|
EICRA &= ~(1 << 7);
|
||||||
|
} else {
|
||||||
|
EICRA &= ~(1 << 6);
|
||||||
|
EICRA &= ~(1 << 7);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
EICRA = icr & 0xff;
|
|
||||||
#if EXT_INT_NUM_CHANNELS > 4
|
|
||||||
EICRB = icr >> 8;
|
|
||||||
#endif
|
#endif
|
||||||
/* Enables/disables the peripheral, as requested. */
|
#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__)
|
||||||
EIMSK = msk;
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Deactivates the INT interrupts.
|
|
||||||
*
|
|
||||||
* @param[in] extp pointer to the @p EXTDriver object
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
#endif
|
|
||||||
/* Enables/disables the peripheral, as requested. */
|
|
||||||
EIMSK = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver interrupt handlers. */
|
/* Driver interrupt handlers. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/*
|
#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__)
|
||||||
* Interrupt handlers for PC-type interrupts.
|
/**
|
||||||
|
* @brief EXTI[INT0] interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
*/
|
*/
|
||||||
#define EXT_PCINT_MIN_INDEX EXT_PC_MIN_PORT
|
OSAL_IRQ_HANDLER(INT0_vect) {
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
#if 0 < EXT_PC_NUM_PORTS
|
EXTD1.config->channels[INT0].cb(&EXTD1, INT0);
|
||||||
#define EXT_PCINT0_INDEX EXT_PCINT_MIN_INDEX
|
OSAL_IRQ_EPILOGUE();
|
||||||
declare_pcint_isr(0);
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1 < EXT_PC_NUM_PORTS
|
#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__)
|
||||||
#define EXT_PCINT1_INDEX (EXT_PCINT0_INDEX + 1)
|
/**
|
||||||
declare_pcint_isr(1);
|
* @brief EXTI[INT1] interrupt handler.
|
||||||
#endif
|
*
|
||||||
#if 2 < EXT_PC_NUM_PORTS
|
* @isr
|
||||||
#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);
|
|
||||||
#endif
|
|
||||||
#if 5 < EXT_PC_NUM_PORTS
|
|
||||||
#define EXT_PCINT5_INDEX (EXT_PCINT4_INDEX + 1)
|
|
||||||
declare_pcint_isr(5);
|
|
||||||
#endif
|
|
||||||
#if 6 < EXT_PC_NUM_PORTS
|
|
||||||
#define EXT_PCINT6_INDEX (EXT_PCINT5_INDEX + 1)
|
|
||||||
declare_pcint_isr(6);
|
|
||||||
#endif
|
|
||||||
#if 7 < EXT_PC_NUM_PORTS
|
|
||||||
#define EXT_PCINT7_INDEX (EXT_PCINT6_INDEX + 1)
|
|
||||||
declare_pcint_isr(7);
|
|
||||||
#endif
|
|
||||||
#if 8 < EXT_PC_NUM_PORTS
|
|
||||||
#define EXT_PCINT8_INDEX (EXT_PCINT7_INDEX + 1)
|
|
||||||
declare_pcint_isr(8);
|
|
||||||
#endif
|
|
||||||
#if 9 < EXT_PC_NUM_PORTS
|
|
||||||
#define EXT_PCINT9_INDEX (EXT_PCINT8_INDEX + 1)
|
|
||||||
declare_pcint_isr(9);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Interrupt handlers for INT-type interrupts.
|
|
||||||
*/
|
*/
|
||||||
#if 0 < EXT_INT_NUM_CHANNELS
|
OSAL_IRQ_HANDLER(INT1_vect) {
|
||||||
declare_extint_isr(0);
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
EXTD1.config->channels[INT1].cb(&EXTD1, INT1);
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1 < EXT_INT_NUM_CHANNELS
|
#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__)
|
||||||
declare_extint_isr(1);
|
/**
|
||||||
|
* @brief EXTI[INT2] interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(INT2_vect) {
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
EXTD1.config->channels[INT2].cb(&EXTD1, INT2);
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 2 < EXT_INT_NUM_CHANNELS
|
#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__)
|
||||||
declare_extint_isr(2);
|
/**
|
||||||
|
* @brief EXTI[INT3] interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(INT3_vect) {
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
EXTD1.config->channels[INT3].cb(&EXTD1, INT3);
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 3 < EXT_INT_NUM_CHANNELS
|
#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__)
|
||||||
declare_extint_isr(3);
|
/**
|
||||||
|
* @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
|
#endif
|
||||||
#if 4 < EXT_INT_NUM_CHANNELS
|
#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__)
|
||||||
declare_extint_isr(4);
|
/**
|
||||||
#endif
|
* @brief EXTI[INT5] interrupt handler.
|
||||||
#if 5 < EXT_INT_NUM_CHANNELS
|
*
|
||||||
declare_extint_isr(5);
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(INT5_vect) {
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
EXTD1.config->channels[INT5].cb(&EXTD1, INT5);
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver functions. */
|
/* Driver functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Low level EXT driver initialization.
|
|
||||||
*
|
|
||||||
* @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
|
|
||||||
*
|
|
||||||
* @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.
|
* @brief Enables an EXT channel.
|
||||||
*
|
*
|
||||||
|
@ -470,33 +249,41 @@ void ext_lld_stop(EXTDriver *extp) {
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
|
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;
|
|
||||||
|
|
||||||
/* Enable bit in mask */
|
#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__)
|
||||||
(*(PCMSK[port])) |= _BV((channel - EXT_PC_MIN_CHANNEL) % 8);
|
if (channel == INT0) {
|
||||||
|
EIMSK |= 1 << INT0;
|
||||||
/* Always enable interrupt */
|
ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode);
|
||||||
#if defined(__AVR_ATmega162__)
|
|
||||||
GICR |= (_BV(port) << 3);
|
|
||||||
#else
|
|
||||||
PCICR |= _BV(port);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EXT_PC_NUM_CHANNELS > 0 && EXT_INT_NUM_CHANNELS > 0
|
#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__)
|
||||||
else
|
if (channel == INT1) {
|
||||||
|
EIMSK |= 1 << INT1;
|
||||||
|
ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#if EXT_INT_NUM_CHANNELS > 0
|
#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__)
|
||||||
if (channel <= EXT_INT_MAX_CHANNEL) {
|
if (channel == INT2) {
|
||||||
#if defined(__AVR_ATmega162__)
|
EIMSK |= 1 << INT2;
|
||||||
GICR |= ((1 << channel) << 5);
|
ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode);
|
||||||
#else
|
}
|
||||||
/* Enables/disables the peripheral, as requested. */
|
|
||||||
EIMSK |= (1 << channel);
|
|
||||||
#endif
|
#endif
|
||||||
|
#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 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 AVR_EXT_USE_INT5 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT5) {
|
||||||
|
EIMSK |= 1 << INT5;
|
||||||
|
ext_lld_set_intx_edges(channel, extp->config->channels[channel].mode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -504,45 +291,87 @@ void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
|
||||||
/**
|
/**
|
||||||
* @brief Disables an EXT channel.
|
* @brief Disables an EXT channel.
|
||||||
*
|
*
|
||||||
* @param[in] extp pointer to the @p EXTDriver object
|
* @param[in] extp pinter to the @p EXTDriver object
|
||||||
* @param[in] channel channel to be disabled
|
* @param[in] channel channel to be disabled
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
|
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 */
|
#if AVR_EXT_USE_INT0 || defined(__DOXYGEN__)
|
||||||
(*(PCMSK[port])) &= ~(_BV((channel - EXT_PC_MIN_CHANNEL) % 8));
|
if (channel == INT0)
|
||||||
|
EIMSK &= ~(1 << INT0);
|
||||||
|
#endif
|
||||||
|
#if AVR_EXT_USE_INT1 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT1)
|
||||||
|
EIMSK &= ~(1 << INT1);
|
||||||
|
#endif
|
||||||
|
#if AVR_EXT_USE_INT2 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT2)
|
||||||
|
EIMSK &= ~(1 << INT2);
|
||||||
|
#endif
|
||||||
|
#if AVR_EXT_USE_INT3 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT3)
|
||||||
|
EIMSK &= ~(1 << INT3);
|
||||||
|
#endif
|
||||||
|
#if AVR_EXT_USE_INT4 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT4)
|
||||||
|
EIMSK &= ~(1 << INT4);
|
||||||
|
#endif
|
||||||
|
#if AVR_EXT_USE_INT5 || defined(__DOXYGEN__)
|
||||||
|
if (channel == INT5)
|
||||||
|
EIMSK &= ~(1 << INT5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Disable interrupt if no bits are set */
|
/**
|
||||||
if ((*(PCMSK[port])) == 0) {
|
* @brief Low level EXT driver initialization.
|
||||||
#if defined(__AVR_ATmega162__)
|
*
|
||||||
GICR &= ~(_BV(port) << 3);
|
* @notapi
|
||||||
#else
|
*/
|
||||||
PCICR |= ~(_BV(port));
|
void ext_lld_init(void) {
|
||||||
#endif
|
|
||||||
}
|
/* Driver initialization.*/
|
||||||
|
extObjectInit(&EXTD1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configures and activates the EXT peripheral.
|
||||||
|
*
|
||||||
|
* @param[in] extp pointer to the @p EXTDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void ext_lld_start(EXTDriver *extp) {
|
||||||
|
|
||||||
|
expchannel_t line;
|
||||||
|
|
||||||
|
if (extp->state == EXT_STOP)
|
||||||
|
osalSysUnlock();
|
||||||
|
|
||||||
|
/* 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
|
}
|
||||||
#if EXT_PC_NUM_CHANNELS > 0 && EXT_INT_NUM_CHANNELS > 0
|
|
||||||
else
|
/**
|
||||||
#endif
|
* @brief Deactivates the EXT peripheral.
|
||||||
#if EXT_INT_NUM_CHANNELS > 0
|
*
|
||||||
if (channel <= EXT_INT_MAX_CHANNEL) {
|
* @param[in] extp pointer to the @p EXTDriver object
|
||||||
#if defined(__AVR_ATmega162__)
|
*
|
||||||
GICR &= ~((1 << channel) << 5);
|
* @notapi
|
||||||
#else
|
*/
|
||||||
/* Enables/disables the peripheral, as requested. */
|
void ext_lld_stop(EXTDriver *extp) {
|
||||||
EIMSK &= ~(1 << channel);
|
|
||||||
#endif
|
if (extp->state == EXT_ACTIVE)
|
||||||
}
|
osalSysLock();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_EXT */
|
#endif /* HAL_USE_EXT */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
/*
|
/*
|
||||||
EXT Low Level Driver for ChibiOS
|
ChibiOS - Copyright (C) 2016 Theodore Ateba
|
||||||
Copyright (C) 2015 Igor Stoppa <igor.stoppa@gmail.com>
|
|
||||||
Copyright (C) 2016 Theodore Ateba
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -18,14 +16,14 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file AVR/hal_ext_lld.h
|
* @file AVR/hal_ext_lld.h
|
||||||
* @brief EXT Driver subsystem low level driver header.
|
* @brief EXT Driver subsystem low level driver source.
|
||||||
*
|
*
|
||||||
* @addtogroup EXT
|
* @addtogroup EXT
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef HAL_EXT_LLD_H
|
#ifndef _HAL_EXT_LLD_H_
|
||||||
#define HAL_EXT_LLD_H
|
#define _HAL_EXT_LLD_H_
|
||||||
|
|
||||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
#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. */
|
#define AVR_INT_NUM_LINES 6 /**< INT0 to INT5 */
|
||||||
#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. */
|
* @brief Available number of EXT channels.
|
||||||
|
*/
|
||||||
|
#define EXT_MAX_CHANNELS AVR_INT_NUM_LINES
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver pre-compile time settings. */
|
/* 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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief INT5 support enable switch.
|
|
||||||
* @details If set to @p TRUE the support for INT5 is included.
|
|
||||||
* @note The default is @p FALSE.
|
|
||||||
*/
|
|
||||||
#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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Derived constants and error checks. */
|
/* 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. */
|
/* 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
|
* @param[in] extp pointer to the @p EXPDriver object triggering the
|
||||||
* callback
|
* callback
|
||||||
* @param[in] channel channel being triggered.
|
|
||||||
*/
|
*/
|
||||||
typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
|
typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
|
||||||
|
|
||||||
|
@ -476,9 +71,9 @@ typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Channel mode from HAL.
|
* @brief Channel mode.
|
||||||
*/
|
*/
|
||||||
uint8_t mode;
|
uint32_t mode;
|
||||||
/**
|
/**
|
||||||
* @brief Channel callback.
|
* @brief Channel callback.
|
||||||
*/
|
*/
|
||||||
|
@ -493,7 +88,7 @@ typedef struct {
|
||||||
/**
|
/**
|
||||||
* @brief Channel configurations.
|
* @brief Channel configurations.
|
||||||
*/
|
*/
|
||||||
EXTChannelConfig channels[EXT_TOTAL_CHANNELS];
|
EXTChannelConfig channels[EXT_MAX_CHANNELS];
|
||||||
/* End of the mandatory fields.*/
|
/* End of the mandatory fields.*/
|
||||||
} EXTConfig;
|
} EXTConfig;
|
||||||
|
|
||||||
|
@ -511,29 +106,15 @@ struct EXTDriver {
|
||||||
*/
|
*/
|
||||||
const EXTConfig *config;
|
const EXTConfig *config;
|
||||||
/* End of the mandatory fields.*/
|
/* 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. */
|
/* Driver macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define ext_port_to_channel(port, bit) \
|
|
||||||
((PORT##port##_INDEX - EXT_PC_MIN_PORT) * 8 + bit)
|
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
extern EXTDriver EXTD1;
|
extern EXTDriver EXTD1;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -550,6 +131,5 @@ extern "C" {
|
||||||
|
|
||||||
#endif /* HAL_USE_EXT */
|
#endif /* HAL_USE_EXT */
|
||||||
|
|
||||||
#endif /* HAL_EXT_LLD_H */
|
#endif /* _HAL_EXT_LLD_H_ */
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
|
@ -44,7 +44,12 @@ static void extcb(EXTDriver *extp, expchannel_t channel) {
|
||||||
*/
|
*/
|
||||||
static const EXTConfig extcfg = {
|
static const EXTConfig extcfg = {
|
||||||
{
|
{
|
||||||
|
{EXT_CH_MODE_DISABLED , NULL}, /* INT0 Config. */
|
||||||
|
{EXT_CH_MODE_DISABLED , NULL}, /* INT1 Config. */
|
||||||
|
{EXT_CH_MODE_DISABLED , NULL}, /* INT2 Config. */
|
||||||
|
{EXT_CH_MODE_DISABLED , NULL}, /* INT3 Config. */
|
||||||
{EXT_CH_MODE_RISING_EDGE , extcb}, /* INT4 Config. */
|
{EXT_CH_MODE_RISING_EDGE , extcb}, /* INT4 Config. */
|
||||||
|
{EXT_CH_MODE_DISABLED , NULL}, /* INT5 Config. */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,7 +70,7 @@ int main(void) {
|
||||||
/*
|
/*
|
||||||
* External interrupt on the Pin D2 of the Arduino Mega2560.
|
* External interrupt on the Pin D2 of the Arduino Mega2560.
|
||||||
*/
|
*/
|
||||||
palSetPadMode(IOPORT5, PE4, PAL_MODE_INPUT);
|
palSetPadMode(IOPORT5, PE4, PAL_MODE_INPUT); /* INT4 pin. */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start the serial driver.
|
* Start the serial driver.
|
||||||
|
|
Loading…
Reference in New Issue