diff options
Diffstat (limited to 'FreeRTOS/Demo/Safer_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c')
-rw-r--r-- | FreeRTOS/Demo/Safer_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c | 412 |
1 files changed, 412 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/Safer_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c b/FreeRTOS/Demo/Safer_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c new file mode 100644 index 000000000..7a21a1ce0 --- /dev/null +++ b/FreeRTOS/Demo/Safer_Interrupts_M33F_NXP_LPC55S69_MCUXpresso/NXP_Code/drivers/fsl_flexcomm.c @@ -0,0 +1,412 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2019 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include "fsl_common.h" +#include "fsl_flexcomm.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Component ID definition, used by tools. */ +#ifndef FSL_COMPONENT_ID +#define FSL_COMPONENT_ID "platform.drivers.flexcomm" +#endif + +/*! + * @brief Used for conversion between `void*` and `uint32_t`. + */ +typedef union pvoid_to_u32 +{ + void *pvoid; + uint32_t u32; +} pvoid_to_u32_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! @brief Set the FLEXCOMM mode . */ +static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock); + +/*! @brief check whether flexcomm supports peripheral type */ +static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map FLEXCOMM instance number to base address. */ +static const uint32_t s_flexcommBaseAddrs[] = FLEXCOMM_BASE_ADDRS; + +/*! @brief Pointers to real IRQ handlers installed by drivers for each instance. */ +static flexcomm_irq_handler_t s_flexcommIrqHandler[ARRAY_SIZE(s_flexcommBaseAddrs)]; + +/*! @brief Pointers to handles for each instance to provide context to interrupt routines */ +static void *s_flexcommHandle[ARRAY_SIZE(s_flexcommBaseAddrs)]; + +/*! @brief Array to map FLEXCOMM instance number to IRQ number. */ +IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief IDs of clock for each FLEXCOMM module */ +static const clock_ip_name_t s_flexcommClocks[] = FLEXCOMM_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) +/*! @brief Pointers to FLEXCOMM resets for each instance. */ +static const reset_ip_name_t s_flexcommResets[] = FLEXCOMM_RSTS; +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* check whether flexcomm supports peripheral type */ +static bool FLEXCOMM_PeripheralIsPresent(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph) +{ + if (periph == FLEXCOMM_PERIPH_NONE) + { + return true; + } + else if (periph <= FLEXCOMM_PERIPH_I2S_TX) + { + return (base->PSELID & (1UL << ((uint32_t)periph + 3U))) > 0UL ? true : false; + } + else if (periph == FLEXCOMM_PERIPH_I2S_RX) + { + return (base->PSELID & (1U << 7U)) > (uint32_t)0U ? true : false; + } + else + { + return false; + } +} + +/* Get the index corresponding to the FLEXCOMM */ +/*! brief Returns instance number for FLEXCOMM module with given base address. */ +uint32_t FLEXCOMM_GetInstance(void *base) +{ + uint32_t i; + pvoid_to_u32_t BaseAddr; + BaseAddr.pvoid = base; + + for (i = 0U; i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT; i++) + { + if (BaseAddr.u32 == s_flexcommBaseAddrs[i]) + { + break; + } + } + + assert(i < (uint32_t)FSL_FEATURE_SOC_FLEXCOMM_COUNT); + return i; +} + +/* Changes FLEXCOMM mode */ +static status_t FLEXCOMM_SetPeriph(FLEXCOMM_Type *base, FLEXCOMM_PERIPH_T periph, int lock) +{ + /* Check whether peripheral type is present */ + if (!FLEXCOMM_PeripheralIsPresent(base, periph)) + { + return kStatus_OutOfRange; + } + + /* Flexcomm is locked to different peripheral type than expected */ + if (((base->PSELID & FLEXCOMM_PSELID_LOCK_MASK) != 0U) && + ((base->PSELID & FLEXCOMM_PSELID_PERSEL_MASK) != (uint32_t)periph)) + { + return kStatus_Fail; + } + + /* Check if we are asked to lock */ + if (lock != 0) + { + base->PSELID = (uint32_t)periph | FLEXCOMM_PSELID_LOCK_MASK; + } + else + { + base->PSELID = (uint32_t)periph; + } + + return kStatus_Success; +} + +/*! brief Initializes FLEXCOMM and selects peripheral mode according to the second parameter. */ +status_t FLEXCOMM_Init(void *base, FLEXCOMM_PERIPH_T periph) +{ + uint32_t idx = FLEXCOMM_GetInstance(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the peripheral clock */ + CLOCK_EnableClock(s_flexcommClocks[idx]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +#if !(defined(FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) && FSL_FEATURE_FLEXCOMM_HAS_NO_RESET) + /* Reset the FLEXCOMM module */ + RESET_PeripheralReset(s_flexcommResets[idx]); +#endif + + /* Set the FLEXCOMM to given peripheral */ + return FLEXCOMM_SetPeriph((FLEXCOMM_Type *)base, periph, 0); +} + +/*! brief Sets IRQ handler for given FLEXCOMM module. It is used by drivers register IRQ handler according to FLEXCOMM + * mode */ +void FLEXCOMM_SetIRQHandler(void *base, flexcomm_irq_handler_t handler, void *flexcommHandle) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(base); + + /* Clear handler first to avoid execution of the handler with wrong handle */ + s_flexcommIrqHandler[instance] = NULL; + s_flexcommHandle[instance] = flexcommHandle; + s_flexcommIrqHandler[instance] = handler; + SDK_ISR_EXIT_BARRIER; +} + +/* IRQ handler functions overloading weak symbols in the startup */ +#if defined(FLEXCOMM0) +void FLEXCOMM0_DriverIRQHandler(void); +void FLEXCOMM0_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM0); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM1) +void FLEXCOMM1_DriverIRQHandler(void); +void FLEXCOMM1_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM1); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM2) +void FLEXCOMM2_DriverIRQHandler(void); +void FLEXCOMM2_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM2); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM3) +void FLEXCOMM3_DriverIRQHandler(void); +void FLEXCOMM3_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM3); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM4) +void FLEXCOMM4_DriverIRQHandler(void); +void FLEXCOMM4_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM4); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} + +#endif + +#if defined(FLEXCOMM5) +void FLEXCOMM5_DriverIRQHandler(void); +void FLEXCOMM5_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM5); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM6) +void FLEXCOMM6_DriverIRQHandler(void); +void FLEXCOMM6_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM6); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM7) +void FLEXCOMM7_DriverIRQHandler(void); +void FLEXCOMM7_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM7); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM8) +void FLEXCOMM8_DriverIRQHandler(void); +void FLEXCOMM8_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM8); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM9) +void FLEXCOMM9_DriverIRQHandler(void); +void FLEXCOMM9_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM9); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM10) +void FLEXCOMM10_DriverIRQHandler(void); +void FLEXCOMM10_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM10); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM11) +void FLEXCOMM11_DriverIRQHandler(void); +void FLEXCOMM11_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM11); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM12) +void FLEXCOMM12_DriverIRQHandler(void); +void FLEXCOMM12_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM12); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM13) +void FLEXCOMM13_DriverIRQHandler(void); +void FLEXCOMM13_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM13); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM14) +void FLEXCOMM14_DriverIRQHandler(void); +void FLEXCOMM14_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM14); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM15) +void FLEXCOMM15_DriverIRQHandler(void); +void FLEXCOMM15_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM15); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif + +#if defined(FLEXCOMM16) +void FLEXCOMM16_DriverIRQHandler(void); +void FLEXCOMM16_DriverIRQHandler(void) +{ + uint32_t instance; + + /* Look up instance number */ + instance = FLEXCOMM_GetInstance(FLEXCOMM16); + assert(s_flexcommIrqHandler[instance] != NULL); + s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]); + SDK_ISR_EXIT_BARRIER; +} +#endif |