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