1136 lines
26 KiB
C
1136 lines
26 KiB
C
/*
|
|
Copyright (C) 2014..2017 Marco Veeneman
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @file GPIO/hal_pal_lld.c
|
|
* @brief TM4C123x/TM4C129x PAL subsystem low level driver.
|
|
*
|
|
* @addtogroup PAL
|
|
* @{
|
|
*/
|
|
|
|
#include "hal.h"
|
|
|
|
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local definitions. */
|
|
/*===========================================================================*/
|
|
|
|
#if TIVA_HAS_GPIOA || defined(__DOXYGEN__)
|
|
#define GPIOA_BIT (1 << 0)
|
|
#else
|
|
#define GPIOA_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOB || defined(__DOXYGEN__)
|
|
#define GPIOB_BIT (1 << 1)
|
|
#else
|
|
#define GPIOB_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOC || defined(__DOXYGEN__)
|
|
#define GPIOC_BIT (1 << 2)
|
|
#else
|
|
#define GPIOC_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOD || defined(__DOXYGEN__)
|
|
#define GPIOD_BIT (1 << 3)
|
|
#else
|
|
#define GPIOD_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOE || defined(__DOXYGEN__)
|
|
#define GPIOE_BIT (1 << 4)
|
|
#else
|
|
#define GPIOE_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOF || defined(__DOXYGEN__)
|
|
#define GPIOF_BIT (1 << 5)
|
|
#else
|
|
#define GPIOF_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOG || defined(__DOXYGEN__)
|
|
#define GPIOG_BIT (1 << 6)
|
|
#else
|
|
#define GPIOG_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOH || defined(__DOXYGEN__)
|
|
#define GPIOH_BIT (1 << 7)
|
|
#else
|
|
#define GPIOH_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOJ || defined(__DOXYGEN__)
|
|
#define GPIOJ_BIT (1 << 8)
|
|
#else
|
|
#define GPIOJ_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOK || defined(__DOXYGEN__)
|
|
#define GPIOK_BIT (1 << 9)
|
|
#else
|
|
#define GPIOK_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOL || defined(__DOXYGEN__)
|
|
#define GPIOL_BIT (1 << 10)
|
|
#else
|
|
#define GPIOL_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOM || defined(__DOXYGEN__)
|
|
#define GPIOM_BIT (1 << 11)
|
|
#else
|
|
#define GPIOM_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPION || defined(__DOXYGEN__)
|
|
#define GPION_BIT (1 << 12)
|
|
#else
|
|
#define GPION_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOP || defined(__DOXYGEN__)
|
|
#define GPIOP_BIT (1 << 13)
|
|
#else
|
|
#define GPIOP_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOQ || defined(__DOXYGEN__)
|
|
#define GPIOQ_BIT (1 << 14)
|
|
#else
|
|
#define GPIOQ_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOR || defined(__DOXYGEN__)
|
|
#define GPIOR_BIT (1 << 15)
|
|
#else
|
|
#define GPIOR_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOS || defined(__DOXYGEN__)
|
|
#define GPIOS_BIT (1 << 16)
|
|
#else
|
|
#define GPIOS_BIT 0
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOT || defined(__DOXYGEN__)
|
|
#define GPIOT_BIT (1 << 17)
|
|
#else
|
|
#define GPIOT_BIT 0
|
|
#endif
|
|
|
|
#define RCGCGPIO_MASK (GPIOA_BIT | GPIOB_BIT | GPIOC_BIT | GPIOD_BIT | \
|
|
GPIOE_BIT | GPIOF_BIT | GPIOG_BIT | GPIOH_BIT | \
|
|
GPIOJ_BIT | GPIOK_BIT | GPIOL_BIT | GPIOM_BIT | \
|
|
GPION_BIT | GPIOP_BIT | GPIOQ_BIT | GPIOR_BIT | \
|
|
GPIOS_BIT | GPIOT_BIT)
|
|
|
|
#define GPIOHBCTL_MASK (GPIOA_BIT | GPIOB_BIT | GPIOC_BIT | GPIOD_BIT | \
|
|
GPIOE_BIT | GPIOF_BIT | GPIOG_BIT | GPIOH_BIT | \
|
|
GPIOJ_BIT)
|
|
|
|
#define GPIOC_JTAG_MASK (0x0F)
|
|
#define GPIOD_NMI_MASK (0x80)
|
|
#define GPIOF_NMI_MASK (0x01)
|
|
|
|
/*===========================================================================*/
|
|
/* Driver exported variables. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @brief Event records for all GPIO channels.
|
|
*/
|
|
palevent_t _pal_events[TIVA_GPIO_PINS];
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local variables and types. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local functions. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @brief Initializes the port with the port configuration.
|
|
*
|
|
* @param[in] port the port identifier
|
|
* @param[in] config the port configuration
|
|
*/
|
|
static void gpio_init(ioportid_t port, const tiva_gpio_setup_t *config)
|
|
{
|
|
HWREG(port + GPIO_O_DATA) = config->data;
|
|
HWREG(port + GPIO_O_DIR) = config->dir;
|
|
HWREG(port + GPIO_O_AFSEL) = config->afsel;
|
|
HWREG(port + GPIO_O_DR2R) = config->dr2r;
|
|
HWREG(port + GPIO_O_DR4R) = config->dr4r;
|
|
HWREG(port + GPIO_O_DR8R) = config->dr8r;
|
|
HWREG(port + GPIO_O_ODR) = config->odr;
|
|
HWREG(port + GPIO_O_PUR) = config->pur;
|
|
HWREG(port + GPIO_O_PDR) = config->pdr;
|
|
HWREG(port + GPIO_O_SLR) = config->slr;
|
|
HWREG(port + GPIO_O_DEN) = config->den;
|
|
HWREG(port + GPIO_O_AMSEL) = config->amsel;
|
|
HWREG(port + GPIO_O_PCTL) = config->pctl;
|
|
}
|
|
|
|
/**
|
|
* @brief Unlocks the masked pins of the GPIO peripheral.
|
|
* @note This function is only useful for PORTC0-3, PORTD7 and PORTF0.
|
|
*
|
|
* @param[in] port the port identifier
|
|
* @param[in] mask the pin mask
|
|
*/
|
|
static void gpio_unlock(ioportid_t port, ioportmask_t mask)
|
|
{
|
|
|
|
HWREG(port + GPIO_O_LOCK) = GPIO_LOCK_KEY;
|
|
HWREG(port + GPIO_O_CR) = mask;
|
|
}
|
|
|
|
#if PAL_USE_CALLBACKS || PAL_USE_WAIT
|
|
/**
|
|
* @brief Enables GPIO IRQ sources.
|
|
*/
|
|
static void gpio_irq_enable(void)
|
|
{
|
|
#if TIVA_HAS_GPIOA
|
|
nvicEnableVector(TIVA_GPIOA_NUMBER, TIVA_PAL_GPIOA_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOB
|
|
nvicEnableVector(TIVA_GPIOB_NUMBER, TIVA_PAL_GPIOB_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOC
|
|
nvicEnableVector(TIVA_GPIOC_NUMBER, TIVA_PAL_GPIOC_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOD
|
|
nvicEnableVector(TIVA_GPIOD_NUMBER, TIVA_PAL_GPIOD_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOE
|
|
nvicEnableVector(TIVA_GPIOE_NUMBER, TIVA_PAL_GPIOE_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOF
|
|
nvicEnableVector(TIVA_GPIOF_NUMBER, TIVA_PAL_GPIOF_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOG
|
|
nvicEnableVector(TIVA_GPIOG_NUMBER, TIVA_PAL_GPIOG_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOH
|
|
nvicEnableVector(TIVA_GPIOH_NUMBER, TIVA_PAL_GPIOH_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOJ
|
|
nvicEnableVector(TIVA_GPIOJ_NUMBER, TIVA_PAL_GPIOJ_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOK
|
|
nvicEnableVector(TIVA_GPIOK_NUMBER, TIVA_PAL_GPIOK_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOL
|
|
nvicEnableVector(TIVA_GPIOL_NUMBER, TIVA_PAL_GPIOL_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOM
|
|
nvicEnableVector(TIVA_GPIOM_NUMBER, TIVA_PAL_GPIOM_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPION
|
|
nvicEnableVector(TIVA_GPION_NUMBER, TIVA_PAL_GPION_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOP
|
|
nvicEnableVector(TIVA_GPIOP0_NUMBER, TIVA_PAL_GPIOP0_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP1_NUMBER, TIVA_PAL_GPIOP1_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP2_NUMBER, TIVA_PAL_GPIOP2_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP3_NUMBER, TIVA_PAL_GPIOP3_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP4_NUMBER, TIVA_PAL_GPIOP4_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP5_NUMBER, TIVA_PAL_GPIOP5_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP6_NUMBER, TIVA_PAL_GPIOP6_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOP7_NUMBER, TIVA_PAL_GPIOP7_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOQ
|
|
nvicEnableVector(TIVA_GPIOQ0_NUMBER, TIVA_PAL_GPIOQ0_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ1_NUMBER, TIVA_PAL_GPIOQ1_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ2_NUMBER, TIVA_PAL_GPIOQ2_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ3_NUMBER, TIVA_PAL_GPIOQ3_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ4_NUMBER, TIVA_PAL_GPIOQ4_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ5_NUMBER, TIVA_PAL_GPIOQ5_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ6_NUMBER, TIVA_PAL_GPIOQ6_IRQ_PRIORITY);
|
|
nvicEnableVector(TIVA_GPIOQ7_NUMBER, TIVA_PAL_GPIOQ7_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOR
|
|
nvicEnableVector(TIVA_GPIOR_NUMBER, TIVA_PAL_GPIOR_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOS
|
|
nvicEnableVector(TIVA_GPIOS_NUMBER, TIVA_PAL_GPIOS_IRQ_PRIORITY);
|
|
#endif
|
|
#if TIVA_HAS_GPIOT
|
|
nvicEnableVector(TIVA_GPIOT_NUMBER, TIVA_PAL_GPIOT_IRQ_PRIORITY);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#define gpio_serve_irq(mask, pin, channel) { \
|
|
\
|
|
if ((mask) & (1U << (pin))) { \
|
|
_pal_isr_code(channel); \
|
|
} \
|
|
}
|
|
|
|
/**
|
|
* @brief Generic interrupt serving code for multiple pins per interrupt
|
|
* handler.
|
|
*/
|
|
#define ext_lld_serve_port_interrupt(gpio, start) \
|
|
do { \
|
|
uint32_t mis = HWREG(gpio + GPIO_O_MIS); \
|
|
\
|
|
HWREG(gpio + GPIO_O_ICR) = mis; \
|
|
\
|
|
gpio_serve_irq(mis, 0, start + 0); \
|
|
gpio_serve_irq(mis, 1, start + 1); \
|
|
gpio_serve_irq(mis, 2, start + 2); \
|
|
gpio_serve_irq(mis, 3, start + 3); \
|
|
gpio_serve_irq(mis, 4, start + 4); \
|
|
gpio_serve_irq(mis, 5, start + 5); \
|
|
gpio_serve_irq(mis, 6, start + 6); \
|
|
gpio_serve_irq(mis, 7, start + 7); \
|
|
} while (0);
|
|
|
|
/**
|
|
* @brief Generic interrupt serving code for single pin per interrupt
|
|
* handler.
|
|
*/
|
|
#define ext_lld_serve_pin_interrupt(gpio, start, pin) \
|
|
do { \
|
|
HWREG(gpio + GPIO_O_ICR) = (1 << pin); \
|
|
gpio_serve_irq((1 << pin), pin, start) \
|
|
} while (0);
|
|
|
|
/*===========================================================================*/
|
|
/* Driver interrupt handlers. */
|
|
/*===========================================================================*/
|
|
|
|
#if TIVA_HAS_GPIOA || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOA interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOA_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOA, 0);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOB || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOB interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOB_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOB, 8);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOC || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOC interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOC_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOC, 16);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOD || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOD interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOD_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOD, 24);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOE || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOE interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOE_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOE, 32);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOF || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOF interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOF_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOF, 40);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOG || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOG interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOG_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOG, 48);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOH || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOH interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOH_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOH, 56);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOJ || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOJ interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOJ_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOJ, 64);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOK || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOK interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOK_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOK, 72);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOL || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOL interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOL_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOL, 80);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOM || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOM interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOM_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOM, 88);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPION || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPION interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPION_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPION, 96);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOP || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOP0 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP0_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 104, 0);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP1 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP1_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 105, 1);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP2 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP2_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 106, 2);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP3 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP3_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 107, 3);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP4 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP4_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 108, 4);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP5 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP5_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 109, 5);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP6 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP6_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 110, 6);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOP7 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOP7_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOP, 111, 7);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOQ || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOQ0 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ0_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 112, 0);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ1 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ1_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 113, 1);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ2 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ2_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 114, 2);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ3 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ3_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 115, 3);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ4 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ4_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 116, 4);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ5 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ5_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 117, 5);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ6 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ6_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 118, 6);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
|
|
/**
|
|
* @brief GPIOQ7 interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOQ7_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_pin_interrupt(GPIOQ, 119, 7);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOR || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOR interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOR_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOR, 120);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOS || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOS interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOS_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOS, 128);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
#if TIVA_HAS_GPIOT || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief GPIOT interrupt handler.
|
|
*
|
|
* @isr
|
|
*/
|
|
OSAL_IRQ_HANDLER(TIVA_GPIOT_HANDLER)
|
|
{
|
|
OSAL_IRQ_PROLOGUE();
|
|
|
|
ext_lld_serve_port_interrupt(GPIOT, 132);
|
|
|
|
OSAL_IRQ_EPILOGUE();
|
|
}
|
|
#endif
|
|
|
|
/*===========================================================================*/
|
|
/* Driver exported functions. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @brief Tiva I/O ports configuration.
|
|
* @details Ports A-F (G, H, J, K, L, M, N, P, Q, R, S, T) clocks enabled.
|
|
*
|
|
* @param[in] config the Tiva ports configuration
|
|
*
|
|
* @notapi
|
|
*/
|
|
void _pal_lld_init(const PALConfig *config)
|
|
{
|
|
#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
|
|
unsigned i;
|
|
|
|
for (i = 0; i < TIVA_GPIO_PINS; i++) {
|
|
_pal_init_event(i);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Enables all GPIO clocks.
|
|
*/
|
|
HWREG(SYSCTL_RCGCGPIO) = RCGCGPIO_MASK;
|
|
#if defined(TM4C123x)
|
|
HWREG(SYSCTL_GPIOHBCTL) = GPIOHBCTL_MASK;
|
|
#endif
|
|
|
|
/* Wait until all GPIO modules are ready */
|
|
while (!((HWREG(SYSCTL_PRGPIO) & RCGCGPIO_MASK) == RCGCGPIO_MASK))
|
|
;
|
|
|
|
#if TIVA_HAS_GPIOA
|
|
gpio_init(GPIOA, &config->PAData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOB
|
|
gpio_init(GPIOB, &config->PBData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOC
|
|
/* Unlock JTAG pins.*/
|
|
gpio_unlock(GPIOC, GPIOC_JTAG_MASK);
|
|
gpio_init(GPIOC, &config->PCData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOD
|
|
/* Unlock NMI pin.*/
|
|
gpio_unlock(GPIOD, GPIOD_NMI_MASK);
|
|
gpio_init(GPIOD, &config->PDData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOE
|
|
gpio_init(GPIOE, &config->PEData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOF
|
|
/* Unlock NMI pin.*/
|
|
gpio_unlock(GPIOF, GPIOF_NMI_MASK);
|
|
gpio_init(GPIOF, &config->PFData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOG || defined(__DOXYGEN__)
|
|
gpio_init(GPIOG, &config->PGData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOH || defined(__DOXYGEN__)
|
|
gpio_init(GPIOH, &config->PHData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOJ || defined(__DOXYGEN__)
|
|
gpio_init(GPIOJ, &config->PJData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOK || defined(__DOXYGEN__)
|
|
gpio_init(GPIOK, &config->PKData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOL || defined(__DOXYGEN__)
|
|
gpio_init(GPIOL, &config->PLData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOM || defined(__DOXYGEN__)
|
|
gpio_init(GPIOM, &config->PMData);
|
|
#endif
|
|
#if TIVA_HAS_GPION || defined(__DOXYGEN__)
|
|
gpio_init(GPION, &config->PNData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOP || defined(__DOXYGEN__)
|
|
gpio_init(GPIOP, &config->PPData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOQ || defined(__DOXYGEN__)
|
|
gpio_init(GPIOQ, &config->PQData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOR || defined(__DOXYGEN__)
|
|
gpio_init(GPIOR, &config->PRData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOS || defined(__DOXYGEN__)
|
|
gpio_init(GPIOS, &config->PSData);
|
|
#endif
|
|
#if TIVA_HAS_GPIOT || defined(__DOXYGEN__)
|
|
gpio_init(GPIOT, &config->PTData);
|
|
#endif
|
|
#if PAL_USE_CALLBACKS || PAL_USE_WAIT
|
|
gpio_irq_enable();
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Pads mode setup.
|
|
* @details This function programs a pads group belonging to the same port
|
|
* with the specified mode.
|
|
*
|
|
* @param[in] port the port identifier
|
|
* @param[in] mask the group mask
|
|
* @param[in] mode the mode
|
|
*
|
|
* @notapi
|
|
*/
|
|
void _pal_lld_setgroupmode(ioportid_t port, ioportmask_t mask, iomode_t mode)
|
|
{
|
|
uint32_t dir = (mode & PAL_TIVA_DIR_MASK) >> 0;
|
|
uint32_t afsel = (mode & PAL_TIVA_AFSEL_MASK) >> 1;
|
|
uint32_t dr2r = (mode & PAL_TIVA_DR2R_MASK) >> 2;
|
|
uint32_t dr4r = (mode & PAL_TIVA_DR4R_MASK) >> 3;
|
|
uint32_t dr8r = (mode & PAL_TIVA_DR8R_MASK) >> 4;
|
|
uint32_t odr = (mode & PAL_TIVA_ODR_MASK) >> 5;
|
|
uint32_t pur = (mode & PAL_TIVA_PUR_MASK) >> 6;
|
|
uint32_t pdr = (mode & PAL_TIVA_PDR_MASK) >> 7;
|
|
uint32_t slr = (mode & PAL_TIVA_SLR_MASK) >> 8;
|
|
uint32_t den = (mode & PAL_TIVA_DEN_MASK) >> 9;
|
|
uint32_t amsel = (mode & PAL_TIVA_AMSEL_MASK) >> 10;
|
|
uint32_t pctl = (mode & PAL_TIVA_PCTL_MASK) >> 11;
|
|
uint32_t bit = 0;
|
|
|
|
while(TRUE) {
|
|
uint32_t pctl_mask = (7 << (4 * bit));
|
|
uint32_t bit_mask = (1 << bit);
|
|
|
|
if ((mask & 1) != 0) {
|
|
HWREG(port + GPIO_O_DIR) = (HWREG(port + GPIO_O_DIR) & ~bit_mask) | dir;
|
|
HWREG(port + GPIO_O_AFSEL) = (HWREG(port + GPIO_O_AFSEL) & ~bit_mask) | afsel;
|
|
HWREG(port + GPIO_O_DR2R) = (HWREG(port + GPIO_O_DR2R) & ~bit_mask) | dr2r;
|
|
HWREG(port + GPIO_O_DR4R) = (HWREG(port + GPIO_O_DR4R) & ~bit_mask) | dr4r;
|
|
HWREG(port + GPIO_O_DR8R) = (HWREG(port + GPIO_O_DR8R) & ~bit_mask) | dr8r;
|
|
HWREG(port + GPIO_O_ODR) = (HWREG(port + GPIO_O_ODR) & ~bit_mask) | odr;
|
|
HWREG(port + GPIO_O_PUR) = (HWREG(port + GPIO_O_PUR) & ~bit_mask) | pur;
|
|
HWREG(port + GPIO_O_PDR) = (HWREG(port + GPIO_O_PDR) & ~bit_mask) | pdr;
|
|
HWREG(port + GPIO_O_SLR) = (HWREG(port + GPIO_O_SLR) & ~bit_mask) | slr;
|
|
HWREG(port + GPIO_O_DEN) = (HWREG(port + GPIO_O_DEN) & ~bit_mask) | den;
|
|
HWREG(port + GPIO_O_AMSEL) = (HWREG(port + GPIO_O_AMSEL) & ~bit_mask) | amsel;
|
|
HWREG(port + GPIO_O_PCTL) = (HWREG(port + GPIO_O_PCTL) & ~pctl_mask) | pctl;
|
|
}
|
|
|
|
mask >>= 1;
|
|
if (!mask) {
|
|
return;
|
|
}
|
|
|
|
dir <<= 1;
|
|
afsel <<= 1;
|
|
dr2r <<= 1;
|
|
dr4r <<= 1;
|
|
dr8r <<= 1;
|
|
odr <<= 1;
|
|
pur <<= 1;
|
|
pdr <<= 1;
|
|
slr <<= 1;
|
|
den <<= 1;
|
|
amsel <<= 1;
|
|
pctl <<= 4;
|
|
|
|
bit++;
|
|
}
|
|
}
|
|
|
|
#if PAL_USE_CALLBACKS || PAL_USE_WAIT || defined(__DOXYGEN__)
|
|
/**
|
|
* @brief Pad event enable.
|
|
* @note Programming an unknown or unsupported mode is silently ignored.
|
|
*
|
|
* @param[in] port port identifier
|
|
* @param[in] pad pad number within the port
|
|
* @param[in] mode pad event mode
|
|
*
|
|
* @notapi
|
|
*/
|
|
void _pal_lld_enablepadevent(ioportid_t port,
|
|
iopadid_t pad,
|
|
ioeventmode_t mode)
|
|
{
|
|
//uint8_t portidx;
|
|
uint32_t padmask;
|
|
|
|
//portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 12) & 0x1FU;
|
|
padmask = (1 << pad);
|
|
|
|
/* Disable interrupt before changing edge configuration.*/
|
|
HWREG(port + GPIO_O_IM) &= ~padmask;
|
|
|
|
/* Configure pin to be edge-sensitive.*/
|
|
HWREG(port + GPIO_O_IS) &= ~(1 << pad);
|
|
|
|
/* Configure edges */
|
|
switch(mode & PAL_EVENT_MODE_EDGES_MASK) {
|
|
case PAL_EVENT_MODE_BOTH_EDGES:
|
|
HWREG(port + GPIO_O_IBE) |= padmask;
|
|
break;
|
|
case PAL_EVENT_MODE_RISING_EDGE:
|
|
HWREG(port + GPIO_O_IBE) &= ~padmask;
|
|
HWREG(port + GPIO_O_IEV) &= ~padmask;
|
|
break;
|
|
case PAL_EVENT_MODE_FALLING_EDGE:
|
|
HWREG(port + GPIO_O_IBE) &= ~padmask;
|
|
HWREG(port + GPIO_O_IEV) |= padmask;
|
|
break;
|
|
default:
|
|
/* Interrupt is already disabled */
|
|
break;
|
|
}
|
|
|
|
if (mode & PAL_EVENT_MODE_EDGES_MASK) {
|
|
/* Enable interrupt for this pad */
|
|
HWREG(port + GPIO_O_IM) |= padmask;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Pad event disable.
|
|
* @details This function disables previously programmed event callbacks.
|
|
*
|
|
* @param[in] port port identifier
|
|
* @param[in] pad pad number within the port
|
|
*
|
|
* @notapi
|
|
*/
|
|
void _pal_lld_disablepadevent(ioportid_t port, iopadid_t pad)
|
|
{
|
|
uint8_t portidx;
|
|
uint8_t eventidx;
|
|
|
|
portidx = (((uint32_t)port - (uint32_t)GPIOA) >> 12) & 0x1FU;
|
|
|
|
eventidx = portidx * 8 + pad;
|
|
|
|
HWREG(port + GPIO_O_IM) &= ~(1 << pad);
|
|
|
|
#if PAL_USE_CALLBACKS || PAL_USE_WAIT
|
|
/* Callback cleared and/or thread reset.*/
|
|
_pal_clear_event(eventidx);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Disables GPIO IRQ sources.
|
|
*/
|
|
void pal_lld_disable_irqs(void)
|
|
{
|
|
#if TIVA_HAS_GPIOA
|
|
nvicDisableVector(TIVA_GPIOA_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOB
|
|
nvicDisableVector(TIVA_GPIOB_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOC
|
|
nvicDisableVector(TIVA_GPIOC_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOD
|
|
nvicDisableVector(TIVA_GPIOD_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOE
|
|
nvicDisableVector(TIVA_GPIOE_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOF
|
|
nvicDisableVector(TIVA_GPIOF_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOG
|
|
nvicDisableVector(TIVA_GPIOG_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOH
|
|
nvicDisableVector(TIVA_GPIOH_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOJ
|
|
nvicDisableVector(TIVA_GPIOJ_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOK
|
|
nvicDisableVector(TIVA_GPIOK_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOL
|
|
nvicDisableVector(TIVA_GPIOL_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOM
|
|
nvicDisableVector(TIVA_GPIOM_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPION
|
|
nvicDisableVector(TIVA_GPION_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOP
|
|
nvicDisableVector(TIVA_GPIOP0_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP1_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP2_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP3_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP4_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP5_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP6_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOP7_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOQ
|
|
nvicDisableVector(TIVA_GPIOQ0_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ1_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ2_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ3_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ4_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ5_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ6_NUMBER);
|
|
nvicDisableVector(TIVA_GPIOQ7_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOR
|
|
nvicDisableVector(TIVA_GPIOR_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOS
|
|
nvicDisableVector(TIVA_GPIOS_NUMBER);
|
|
#endif
|
|
#if TIVA_HAS_GPIOT
|
|
nvicDisableVector(TIVA_GPIOT_NUMBER);
|
|
#endif
|
|
}
|
|
#endif /* PAL_USE_CALLBACKS || PAL_USE_WAIT */
|
|
|
|
#endif /* HAL_USE_PAL */
|
|
|
|
/**
|
|
* @}
|
|
*/
|