initial check in based on SVN revision 575
This commit is contained in:
356
drivers/fsl_flexcomm.c
Normal file
356
drivers/fsl_flexcomm.c
Normal file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* 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 Pointers to real IRQ handlers installed by drivers for each instance. */
|
||||
static flexcomm_irq_handler_t s_flexcommIrqHandler[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
|
||||
|
||||
/*! @brief Pointers to handles for each instance to provide context to interrupt routines */
|
||||
static void *s_flexcommHandle[FSL_FEATURE_SOC_FLEXCOMM_COUNT];
|
||||
|
||||
/*! @brief Array to map FLEXCOMM instance number to IRQ number. */
|
||||
IRQn_Type const kFlexcommIrqs[] = FLEXCOMM_IRQS;
|
||||
|
||||
/*! @brief Array to map FLEXCOMM instance number to base address. */
|
||||
static const uint32_t s_flexcommBaseAddrs[FSL_FEATURE_SOC_FLEXCOMM_COUNT] = FLEXCOMM_BASE_ADDRS;
|
||||
|
||||
#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)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[0]);
|
||||
s_flexcommIrqHandler[0]((uint32_t *)s_flexcommBaseAddrs[0], s_flexcommHandle[0]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM1)
|
||||
void FLEXCOMM1_DriverIRQHandler(void);
|
||||
void FLEXCOMM1_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[1]);
|
||||
s_flexcommIrqHandler[1]((uint32_t *)s_flexcommBaseAddrs[1], s_flexcommHandle[1]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM2)
|
||||
void FLEXCOMM2_DriverIRQHandler(void);
|
||||
void FLEXCOMM2_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[2]);
|
||||
s_flexcommIrqHandler[2]((uint32_t *)s_flexcommBaseAddrs[2], s_flexcommHandle[2]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM3)
|
||||
void FLEXCOMM3_DriverIRQHandler(void);
|
||||
void FLEXCOMM3_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[3]);
|
||||
s_flexcommIrqHandler[3]((uint32_t *)s_flexcommBaseAddrs[3], s_flexcommHandle[3]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM4)
|
||||
void FLEXCOMM4_DriverIRQHandler(void);
|
||||
void FLEXCOMM4_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[4]);
|
||||
s_flexcommIrqHandler[4]((uint32_t *)s_flexcommBaseAddrs[4], s_flexcommHandle[4]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM5)
|
||||
void FLEXCOMM5_DriverIRQHandler(void);
|
||||
void FLEXCOMM5_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[5]);
|
||||
s_flexcommIrqHandler[5]((uint32_t *)s_flexcommBaseAddrs[5], s_flexcommHandle[5]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM6)
|
||||
void FLEXCOMM6_DriverIRQHandler(void);
|
||||
void FLEXCOMM6_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[6]);
|
||||
s_flexcommIrqHandler[6]((uint32_t *)s_flexcommBaseAddrs[6], s_flexcommHandle[6]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM7)
|
||||
void FLEXCOMM7_DriverIRQHandler(void);
|
||||
void FLEXCOMM7_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[7]);
|
||||
s_flexcommIrqHandler[7]((uint32_t *)s_flexcommBaseAddrs[7], s_flexcommHandle[7]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM8)
|
||||
void FLEXCOMM8_DriverIRQHandler(void);
|
||||
void FLEXCOMM8_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[8]);
|
||||
s_flexcommIrqHandler[8]((uint32_t *)s_flexcommBaseAddrs[8], s_flexcommHandle[8]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM9)
|
||||
void FLEXCOMM9_DriverIRQHandler(void);
|
||||
void FLEXCOMM9_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[9]);
|
||||
s_flexcommIrqHandler[9]((uint32_t *)s_flexcommBaseAddrs[9], s_flexcommHandle[9]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM10)
|
||||
void FLEXCOMM10_DriverIRQHandler(void);
|
||||
void FLEXCOMM10_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[10]);
|
||||
s_flexcommIrqHandler[10]((uint32_t *)s_flexcommBaseAddrs[10], s_flexcommHandle[10]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM11)
|
||||
void FLEXCOMM11_DriverIRQHandler(void);
|
||||
void FLEXCOMM11_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[11]);
|
||||
s_flexcommIrqHandler[11]((uint32_t *)s_flexcommBaseAddrs[11], s_flexcommHandle[11]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM12)
|
||||
void FLEXCOMM12_DriverIRQHandler(void);
|
||||
void FLEXCOMM12_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[12]);
|
||||
s_flexcommIrqHandler[12]((uint32_t *)s_flexcommBaseAddrs[12], s_flexcommHandle[12]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FLEXCOMM13)
|
||||
void FLEXCOMM13_DriverIRQHandler(void);
|
||||
void FLEXCOMM13_DriverIRQHandler(void)
|
||||
{
|
||||
assert(s_flexcommIrqHandler[13]);
|
||||
s_flexcommIrqHandler[13]((uint32_t *)s_flexcommBaseAddrs[13], s_flexcommHandle[13]);
|
||||
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]);
|
||||
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]);
|
||||
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]);
|
||||
s_flexcommIrqHandler[instance]((uint32_t *)s_flexcommBaseAddrs[instance], s_flexcommHandle[instance]);
|
||||
SDK_ISR_EXIT_BARRIER;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user