igor wrote:Where does the "1" in PLATFORM_EXT_USE_EXT1 come from?
Btw, that would become, according to Giovanni's post AVR_EXT_USE_EXT1, right?
Is that number used to identify similar but independent HW blocks?
The ATMega328p has INT0 and INT1 as direct external sources of events, but they are both handled in the same registers and I would handle them through #define EXT_MAX_CHANNELS 2
rather than having AVR_EXT_USE_EXT2
Answering to myself, after further reading.
So yes, what i wrote seems to be the case.
But I have one new doubt now:
the ext.h file states:
Code: Select all
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @name EXT channel modes
* @{
*/
#define EXT_CH_MODE_EDGES_MASK 3U /**< @brief Mask of edges field. */
#define EXT_CH_MODE_DISABLED 0U /**< @brief Channel disabled. */
#define EXT_CH_MODE_RISING_EDGE 1U /**< @brief Rising edge callback. */
#define EXT_CH_MODE_FALLING_EDGE 2U /**< @brief Falling edge callback. */
#define EXT_CH_MODE_BOTH_EDGES 3U /**< @brief Both edges callback. */
#define EXT_CH_MODE_AUTOSTART 4U /**< @brief Channel started
automatically on driver start. */
/** @} */
However the AVR has slightly different modes:
0: _low level_ triggers an interrupt -> ????
1: any change triggers and interrupt -> EXT_CH_MODE_BOTH_EDGES
2: falling edge triggers an interrupt -> EXT_CH_MODE_RISING_EDGE
3: rising edge triggers and interrupt -> EXT_CH_MODE_FALLING_EDGE
Quoting the TRM
http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf@ 13.2.1 EICRA – External Interrupt Control Register A
• Bit 3, 2 – ISC11, ISC10: Interrupt Sense Control 1 Bit 1 and Bit 0 :
If edge or toggle interrupt is selected, pulses that
last longer than one clock period will generate an interrupt. Shorter pulses are not guaranteed to generate an
interrupt. If low level interrupt is selected, the low level must be held until the completion of the currently
executing instruction to generate an interrupt.
So the current driver doesn't seem to support level-driven IRQs.
If my analysis is correct, I would propose to extend it in a generic way (the translation to real register values can still happen in the ext_lld.c file).
The current solution uses only bits [2..0] of the mode field.
So I would propose to turn the modes section into the following (should be 100% compatible with the current version):
Code: Select all
/**
* @name EXT channel modes
* @{
*/
#define EXT_CH_MODE_DISABLED 0U /**< @brief Channel disabled. */
#define EXT_CH_MODE_EDGES_MASK 3U /**< @brief Mask of edges field. */
#define EXT_CH_MODE_LEVELS_MASK 24U /**< @brief Mask of levels field. */
#define EXT_CH_MODE_AUTOSTART 4U /**< @brief Channel started
automatically on driver start. */
#define EXT_CH_MODE_RISING_EDGE 1U /**< @brief Rising edge callback. */
#define EXT_CH_MODE_FALLING_EDGE 2U /**< @brief Falling edge callback. */
#define EXT_CH_MODE_BOTH_EDGES 3U /**< @brief Both edges callback. */
#define EXT_CH_MODE_HIGH_LEVEL 8U /**< @brief High Level callback. */
#define EXT_CH_MODE_LOW_LEVEL 16U /**< @brief Low Level callback. */
#define EXT_CH_MODE_BOTH_LEVELS 24U /**< @brief Both Levels callback. */
/** @} */
I can create a separate patch for this.
Comments?
thanks, igor