keyboard/qmk/lib/chibios-contrib/os/hal/ports/TIVA/LLD/GPIO/hal_pal_lld.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 */
/**
* @}
*/