ext/hal/nxp/imx: Import the nxp imx7 freertos bsp

This code component is used to add Zephyr support on iMX7 processors,
exclusively on Cortex M4 core, and to speed up the development process
it was decided to have it based on NXP FreeRTOS BSP implementation.

The source code was imported from the following folders:
    FreeRTOS_BSP_1.0.1_iMX7D/platform/drivers
    FreeRTOS_BSP_1.0.1_iMX7D/platform/devices

This source code depends on headers and sources from zephyr:
    ext/hal/cmsis

Origin: iMX7D NXP FreeRTOS BSP Peripheral Driver
License: BSD 3-Clause
URL: https://www.nxp.com/webapp/Download?colCode=FreeRTOS_iMX7D_1.0.1_LINUX&appType=license
commit: no commit hash
Purpose: The peripheral driver wraps the H/W for i.MX7 M4 core
Maintained-by: External

Signed-off-by: Diego Sueiro <diego.sueiro@gmail.com>
This commit is contained in:
Diego Sueiro 2018-03-14 18:34:52 +00:00 committed by Maureen Helm
commit 3afc2b6c61
42 changed files with 56020 additions and 0 deletions

View file

@ -20,6 +20,8 @@ source "ext/hal/nordic/Kconfig"
source "ext/hal/nxp/mcux/Kconfig"
source "ext/hal/nxp/imx/Kconfig"
source "ext/hal/qmsi/Kconfig"
source "ext/hal/silabs/gecko/Kconfig"

View file

@ -2,3 +2,8 @@ add_subdirectory_ifdef(
CONFIG_HAS_MCUX
mcux
)
add_subdirectory_ifdef(
CONFIG_HAS_IMX_HAL
imx
)

View file

@ -0,0 +1,9 @@
# Translate the SoC name and part number into the imx device and cpu
# name respectively.
string(TOUPPER ${CONFIG_SOC} IMX_DEVICE)
zephyr_include_directories(devices/${IMX_DEVICE})
# Build imx drivers and utilities that can be used for multiple SoC's.
add_subdirectory(drivers)
add_subdirectory(devices/${IMX_DEVICE})

28
ext/hal/nxp/imx/Kconfig Normal file
View file

@ -0,0 +1,28 @@
# Kconfig - IMX M4 Core SDK
#
# Copyright (c) 2018, NXP
#
# SPDX-License-Identifier: Apache-2.0
#
config HAS_IMX_HAL
bool
select HAS_CMSIS
depends on SOC_FAMILY_IMX
if HAS_IMX_HAL
config HAS_IMX_RDC
bool
default n
help
Set if the RDC module is present in the SoC.
config HAS_IMX_CCM
bool
default n
help
Set if the CCM module is present in the SoC.
endif # HAS_IMX_HAL

41
ext/hal/nxp/imx/README Normal file
View file

@ -0,0 +1,41 @@
iMX7D Port
#####################
Origin:
iMX7D NXP FreeRTOS BSP Peripheral Driver
https://www.nxp.com/webapp/Download?colCode=FreeRTOS_iMX7D_1.0.1_LINUX&appType=license
Status:
FreeRTOS_iMX7D_1.0.1
Purpose:
The peripheral driver wrap the H/W
Description:
This code component is used to add Zephyr support on iMX7 processors,
exclusively on Cortex M4 core, and to speed up the development process
it was decided to have it based on NXP FreeRTOS BSP implementation.
The source code was imported from the following folders:
FreeRTOS_BSP_1.0.1_iMX7D/platform/drivers
FreeRTOS_BSP_1.0.1_iMX7D/platform/devices
Dependencies:
This source code depends on headers and sources from zephyr:
ext/hal/cmsis
URL:
https://www.nxp.com/products/processors-and-microcontrollers/applications-processors/i.mx-applications-processors/i.mx-7-processors/i.mx-7dual-processors-heterogeneous-processing-with-dual-arm-cortex-a7-cores-and-cortex-m4-core:i.MX7D?tab=Design_Tools_Tab
commit:
No commit hash
Maintained-by:
External
License:
BSD-3-Clause
License Link:
https://www.nxp.com/webapp/sps/download/license.jsp?colCode=FreeRTOS_iMX7D_1.0.1_LINUX&appType=file1&DOWNLOAD_ID=null

View file

@ -0,0 +1,2 @@
zephyr_include_directories(.)
zephyr_sources(clock_freq.c)

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,243 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "clock_freq.h"
#include "ccm_imx7d.h"
#include "ccm_analog_imx7d.h"
/*FUNCTION**********************************************************************
*
* Function Name : get_gpt_clock_freq
* Description : Get clock frequency applies to the GPT module
*
*END**************************************************************************/
uint32_t get_gpt_clock_freq(GPT_Type *base)
{
uint32_t root;
uint32_t hz;
uint32_t pre, post;
switch ((uint32_t)base) {
case GPT3_BASE:
root = CCM_GetRootMux(CCM, ccmRootGpt3);
CCM_GetRootDivider(CCM, ccmRootGpt3, &pre, &post);
break;
case GPT4_BASE:
root = CCM_GetRootMux(CCM, ccmRootGpt4);
CCM_GetRootDivider(CCM, ccmRootGpt4, &pre, &post);
break;
default:
return 0;
}
switch (root) {
case ccmRootmuxGptOsc24m:
hz = 24000000;
break;
case ccmRootmuxGptSysPllPfd0:
hz = CCM_ANALOG_GetPfdFreq(CCM_ANALOG, ccmAnalogPfd0Frac);
break;
default:
return 0;
}
return hz / (pre + 1) / (post + 1);
}
/*FUNCTION**********************************************************************
*
* Function Name : get_ecspi_clock_freq
* Description : Get clock frequency applys to the ECSPI module
*
*END**************************************************************************/
uint32_t get_ecspi_clock_freq(ECSPI_Type *base)
{
uint32_t root;
uint32_t hz;
uint32_t pre, post;
switch ((uint32_t)base) {
case ECSPI1_BASE:
root = CCM_GetRootMux(CCM, ccmRootEcspi1);
CCM_GetRootDivider(CCM, ccmRootEcspi1, &pre, &post);
break;
case ECSPI2_BASE:
root = CCM_GetRootMux(CCM, ccmRootEcspi2);
CCM_GetRootDivider(CCM, ccmRootEcspi2, &pre, &post);
break;
default:
return 0;
}
switch (root) {
case ccmRootmuxEcspiOsc24m:
hz = 24000000;
break;
case ccmRootmuxEcspiSysPllPfd4:
hz = CCM_ANALOG_GetPfdFreq(CCM_ANALOG, ccmAnalogPfd4Frac);
break;
default:
return 0;
}
return hz / (pre + 1) / (post + 1);
}
/*FUNCTION**********************************************************************
*
* Function Name : get_flexcan_clock_freq
* Description : Get clock frequency applys to the FLEXCAN module
*
*END**************************************************************************/
uint32_t get_flexcan_clock_freq(CAN_Type *base)
{
uint32_t root;
uint32_t hz;
uint32_t pre, post;
switch ((uint32_t)base) {
case CAN1_BASE:
root = CCM_GetRootMux(CCM, ccmRootCan1);
CCM_GetRootDivider(CCM, ccmRootCan1, &pre, &post);
break;
case CAN2_BASE:
root = CCM_GetRootMux(CCM, ccmRootCan2);
CCM_GetRootDivider(CCM, ccmRootCan2, &pre, &post);
break;
default:
return 0;
}
switch (root) {
case ccmRootmuxCanOsc24m:
hz = 24000000;
break;
case ccmRootmuxCanSysPllDiv4:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG) >> 2;
break;
case ccmRootmuxCanSysPllDiv1:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG);
break;
default:
return 0;
}
return hz / (pre + 1) / (post + 1);
}
/*FUNCTION**********************************************************************
*
* Function Name : get_I2C_clock_freq
* Description : Get clock frequency applys to the I2C module
*
*END**************************************************************************/
uint32_t get_i2c_clock_freq(I2C_Type *base)
{
uint32_t root;
uint32_t hz;
uint32_t pre, post;
switch ((uint32_t)base) {
case I2C1_BASE:
root = CCM_GetRootMux(CCM, ccmRootI2c1);
CCM_GetRootDivider(CCM, ccmRootI2c1, &pre, &post);
break;
case I2C2_BASE:
root = CCM_GetRootMux(CCM, ccmRootI2c2);
CCM_GetRootDivider(CCM, ccmRootI2c2, &pre, &post);
break;
case I2C3_BASE:
root = CCM_GetRootMux(CCM, ccmRootI2c3);
CCM_GetRootDivider(CCM, ccmRootI2c3, &pre, &post);
break;
case I2C4_BASE:
root = CCM_GetRootMux(CCM, ccmRootI2c4);
CCM_GetRootDivider(CCM, ccmRootI2c4, &pre, &post);
break;
default:
return 0;
}
switch (root) {
case ccmRootmuxI2cOsc24m:
hz = 24000000;
break;
case ccmRootmuxI2cSysPllDiv4:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG) >> 2;
break;
default:
return 0;
}
return hz / (pre + 1) / (post + 1);
}
/*FUNCTION**********************************************************************
*
* Function Name : get_uart_clock_freq
* Description : Get clock frequency applys to the UART module
*
*END**************************************************************************/
uint32_t get_uart_clock_freq(UART_Type *base)
{
uint32_t root;
uint32_t hz;
uint32_t pre, post;
switch ((uint32_t)base) {
case UART2_BASE:
root = CCM_GetRootMux(CCM, ccmRootUart2);
CCM_GetRootDivider(CCM, ccmRootUart2, &pre, &post);
break;
default:
return 0;
}
switch (root) {
case ccmRootmuxUartOsc24m:
hz = 24000000;
break;
case ccmRootmuxUartSysPllDiv2:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG) >> 1;
break;
case ccmRootmuxUartSysPllDiv1:
hz = CCM_ANALOG_GetSysPllFreq(CCM_ANALOG);
break;
default:
return 0;
}
return hz / (pre + 1) / (post + 1);
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CLOCK_FREQ_H__
#define __CLOCK_FREQ_H__
#include "device_imx.h"
/*!
* @addtogroup clock_freq_helper
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Get clock frequency applies to the GPT module
*
* @param base GPT base pointer.
* @return clock frequency (in HZ) applies to the GPT module
*/
uint32_t get_gpt_clock_freq(GPT_Type *base);
/*!
* @brief Get clock frequency applies to the ECSPI module
*
* @param base ECSPI base pointer.
* @return clock frequency (in HZ) applies to the ECSPI module
*/
uint32_t get_ecspi_clock_freq(ECSPI_Type *base);
/*!
* @brief Get clock frequency applies to the FLEXCAN module
*
* @param base CAN base pointer.
* @return clock frequency (in HZ) applies to the FLEXCAN module
*/
uint32_t get_flexcan_clock_freq(CAN_Type *base);
/*!
* @brief Get clock frequency applies to the I2C module
*
* @param base I2C base pointer.
* @return clock frequency (in HZ) applies to the I2C module
*/
uint32_t get_i2c_clock_freq(I2C_Type *base);
/*!
* @brief Get clock frequency applies to the UART module
*
* @param base UART base pointer.
* @return clock frequency (in HZ) applies to the UART module
*/
uint32_t get_uart_clock_freq(UART_Type *base);
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __CLOCK_FREQ_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
** ###################################################################
** Abstract:
** Common include file for CMSIS register access layer headers.
**
** http: www.freescale.com
** mail: support@freescale.com
**
** ###################################################################
*/
#ifndef __DEVICE_IMX_H__
#define __DEVICE_IMX_H__
/*
* Include the cpu specific register header files.
*
* The CPU macro should be declared in the project or makefile.
*/
#if defined(CONFIG_SOC_MCIMX6X_M4)
/* CMSIS-style register definitions */
#include "MCIMX6X/include/MCIMX6X_M4.h"
#define RDC_SEMAPHORE_MASTER_SELF (5)
#define SEMA4_PROCESSOR_SELF (1)
#elif defined(CONFIG_SOC_MCIMX7_M4)
/* CMSIS-style register definitions */
#include "MCIMX7D_M4.h"
#define RDC_SEMAPHORE_MASTER_SELF (6)
#define SEMA4_PROCESSOR_SELF (1)
#endif
#endif /* __DEVICE_IMX_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,6 @@
zephyr_include_directories(.)
if(CONFIG_SOC_MCIMX7_M4)
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_IMX_CCM ccm_imx7d.c)
zephyr_sources_ifdef(CONFIG_CLOCK_CONTROL_IMX_CCM ccm_analog_imx7d.c)
endif()

View file

@ -0,0 +1,803 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "adc_imx7d.h"
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* ADC Module Initialization and Configuration functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_Init
* Description : Initialize ADC to reset state and initialize with initialize
* structure.
*
*END**************************************************************************/
void ADC_Init(ADC_Type* base, const adc_init_config_t* initConfig)
{
assert(initConfig);
/* Reset ADC register to its default value. */
ADC_Deinit(base);
/* Set ADC Module Sample Rate */
ADC_SetSampleRate(base, initConfig->sampleRate);
/* Enable ADC Build-in voltage level shifter */
if (initConfig->levelShifterEnable)
ADC_LevelShifterEnable(base);
else
ADC_LevelShifterDisable(base);
/* Wait until ADC module power-up completely. */
while((ADC_ADC_CFG_REG(base) & ADC_ADC_CFG_ADC_PD_OK_MASK));
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_Deinit
* Description : This function reset ADC module register content to its
* default value.
*
*END**************************************************************************/
void ADC_Deinit(ADC_Type* base)
{
/* Stop all continues conversions */
ADC_SetConvertCmd(base, adcLogicChA, false);
ADC_SetConvertCmd(base, adcLogicChB, false);
ADC_SetConvertCmd(base, adcLogicChC, false);
ADC_SetConvertCmd(base, adcLogicChD, false);
/* Reset ADC Module Register content to default value */
ADC_CH_A_CFG1_REG(base) = 0x0;
ADC_CH_A_CFG2_REG(base) = ADC_CH_A_CFG2_CHA_AUTO_DIS_MASK;
ADC_CH_B_CFG1_REG(base) = 0x0;
ADC_CH_B_CFG2_REG(base) = ADC_CH_B_CFG2_CHB_AUTO_DIS_MASK;
ADC_CH_C_CFG1_REG(base) = 0x0;
ADC_CH_C_CFG2_REG(base) = ADC_CH_C_CFG2_CHC_AUTO_DIS_MASK;
ADC_CH_D_CFG1_REG(base) = 0x0;
ADC_CH_D_CFG2_REG(base) = ADC_CH_D_CFG2_CHD_AUTO_DIS_MASK;
ADC_CH_SW_CFG_REG(base) = 0x0;
ADC_TIMER_UNIT_REG(base) = 0x0;
ADC_DMA_FIFO_REG(base) = ADC_DMA_FIFO_DMA_WM_LVL(0xF);
ADC_INT_SIG_EN_REG(base) = 0x0;
ADC_INT_EN_REG(base) = 0x0;
ADC_INT_STATUS_REG(base) = 0x0;
ADC_ADC_CFG_REG(base) = ADC_ADC_CFG_ADC_EN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetSampleRate
* Description : This function is used to set ADC module sample rate.
*
*END**************************************************************************/
void ADC_SetSampleRate(ADC_Type* base, uint32_t sampleRate)
{
uint8_t preDiv;
uint8_t coreTimerUnit;
assert((sampleRate <= 1000000) && (sampleRate >= 1563));
for (preDiv = 0 ; preDiv < 6; preDiv++)
{
uint32_t divider = 24000000 >> (2 + preDiv);
divider /= sampleRate * 6;
if(divider <= 32)
{
coreTimerUnit = divider - 1;
break;
}
}
if (0x6 == preDiv)
{
preDiv = 0x5;
coreTimerUnit = 0x1F;
}
ADC_TIMER_UNIT_REG(base) = 0x0;
ADC_TIMER_UNIT_REG(base) = ADC_TIMER_UNIT_PRE_DIV(preDiv) | ADC_TIMER_UNIT_CORE_TIMER_UNIT(coreTimerUnit);
}
/*******************************************************************************
* ADC Low power control functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetClockDownCmd
* Description : This function is used to stop all digital part power.
*
*END**************************************************************************/
void ADC_SetClockDownCmd(ADC_Type* base, bool clockDown)
{
if (clockDown)
ADC_ADC_CFG_REG(base) |= ADC_ADC_CFG_ADC_CLK_DOWN_MASK;
else
ADC_ADC_CFG_REG(base) &= ~ADC_ADC_CFG_ADC_CLK_DOWN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetPowerDownCmd
* Description : This function is used to power down ADC analogue core.
* Before entering into stop-mode, power down ADC analogue
* core first.
*
*END**************************************************************************/
void ADC_SetPowerDownCmd(ADC_Type* base, bool powerDown)
{
if (powerDown)
{
ADC_ADC_CFG_REG(base) |= ADC_ADC_CFG_ADC_PD_MASK;
/* Wait until power down action finish. */
while((ADC_ADC_CFG_REG(base) & ADC_ADC_CFG_ADC_PD_OK_MASK));
}
else
{
ADC_ADC_CFG_REG(base) &= ~ADC_ADC_CFG_ADC_PD_MASK;
}
}
/*******************************************************************************
* ADC Convert Channel Initialization and Configuration functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_LogicChInit
* Description : Initialize ADC Logic channel with initialization structure.
*
*END**************************************************************************/
void ADC_LogicChInit(ADC_Type* base, uint8_t logicCh, const adc_logic_ch_init_config_t* chInitConfig)
{
assert(chInitConfig);
/* Select input channel */
ADC_SelectInputCh(base, logicCh, chInitConfig->inputChannel);
/* Set Continuous Convert Rate. */
if (chInitConfig->coutinuousEnable)
ADC_SetConvertRate(base, logicCh, chInitConfig->convertRate);
/* Set Hardware average Number. */
if (chInitConfig->averageEnable)
{
ADC_SetAverageNum(base, logicCh, chInitConfig->averageNumber);
ADC_SetAverageCmd(base, logicCh, true);
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_LogicChDeinit
* Description : Reset target ADC logic channel registers to default value.
*
*END**************************************************************************/
void ADC_LogicChDeinit(ADC_Type* base, uint8_t logicCh)
{
assert(logicCh <= adcLogicChSW);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) = 0x0;
ADC_CH_A_CFG2_REG(base) = 0x8000;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) = 0x0;
ADC_CH_B_CFG2_REG(base) = 0x8000;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) = 0x0;
ADC_CH_C_CFG2_REG(base) = 0x8000;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) = 0x0;
ADC_CH_D_CFG2_REG(base) = 0x8000;
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) = 0x0;
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SelectInputCh
* Description : Select input channel for target logic channel.
*
*END**************************************************************************/
void ADC_SelectInputCh(ADC_Type* base, uint8_t logicCh, uint8_t inputCh)
{
assert(logicCh <= adcLogicChSW);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) = (ADC_CH_A_CFG1_REG(base) & ~ADC_CH_A_CFG1_CHA_SEL_MASK) | \
ADC_CH_A_CFG1_CHA_SEL(inputCh);
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) = (ADC_CH_B_CFG1_REG(base) & ~ADC_CH_B_CFG1_CHB_SEL_MASK) | \
ADC_CH_B_CFG1_CHB_SEL(inputCh);
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) = (ADC_CH_C_CFG1_REG(base) & ~ADC_CH_C_CFG1_CHC_SEL_MASK) | \
ADC_CH_C_CFG1_CHC_SEL(inputCh);
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) = (ADC_CH_D_CFG1_REG(base) & ~ADC_CH_D_CFG1_CHD_SEL_MASK) | \
ADC_CH_D_CFG1_CHD_SEL(inputCh);
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) = (ADC_CH_SW_CFG_REG(base) & ~ADC_CH_SW_CFG_CH_SW_SEL_MASK) | \
ADC_CH_SW_CFG_CH_SW_SEL(inputCh);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertRate
* Description : Set ADC conversion rate of target logic channel.
*
*END**************************************************************************/
void ADC_SetConvertRate(ADC_Type* base, uint8_t logicCh, uint32_t convertRate)
{
assert(logicCh <= adcLogicChD);
/* Calculate ADC module's current sample rate */
uint32_t sampleRate = (4000000 >> (2 + (ADC_TIMER_UNIT_REG(base) >> ADC_TIMER_UNIT_PRE_DIV_SHIFT))) / \
((ADC_TIMER_UNIT_REG(base) & ADC_TIMER_UNIT_CORE_TIMER_UNIT_MASK) + 1);
uint32_t convertDiv = sampleRate / convertRate;
assert((sampleRate / convertRate) <= ADC_CH_A_CFG1_CHA_TIMER_MASK);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) = (ADC_CH_A_CFG1_REG(base) & ~ADC_CH_A_CFG1_CHA_TIMER_MASK) | \
ADC_CH_A_CFG1_CHA_TIMER(convertDiv);
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) = (ADC_CH_B_CFG1_REG(base) & ~ADC_CH_B_CFG1_CHB_TIMER_MASK) | \
ADC_CH_B_CFG1_CHB_TIMER(convertDiv);
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) = (ADC_CH_C_CFG1_REG(base) & ~ADC_CH_C_CFG1_CHC_TIMER_MASK) | \
ADC_CH_C_CFG1_CHC_TIMER(convertDiv);
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) = (ADC_CH_D_CFG1_REG(base) & ~ADC_CH_D_CFG1_CHD_TIMER_MASK) | \
ADC_CH_D_CFG1_CHD_TIMER(convertDiv);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetAverageCmd
* Description : Set work state of hardware average feature of target
* logic channel.
*
*END**************************************************************************/
void ADC_SetAverageCmd(ADC_Type* base, uint8_t logicCh, bool enable)
{
assert(logicCh <= adcLogicChSW);
if (enable)
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) |= ADC_CH_A_CFG1_CHA_AVG_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) |= ADC_CH_B_CFG1_CHB_AVG_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) |= ADC_CH_C_CFG1_CHC_AVG_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) |= ADC_CH_D_CFG1_CHD_AVG_EN_MASK;
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) |= ADC_CH_SW_CFG_CH_SW_AVG_EN_MASK;
break;
default:
break;
}
}
else
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) &= ~ADC_CH_A_CFG1_CHA_AVG_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) &= ~ADC_CH_B_CFG1_CHB_AVG_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) &= ~ADC_CH_C_CFG1_CHC_AVG_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) &= ~ADC_CH_D_CFG1_CHD_AVG_EN_MASK;
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) &= ~ADC_CH_SW_CFG_CH_SW_AVG_EN_MASK;
break;
default:
break;
}
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetAverageNum
* Description : Set hardware average number of target logic channel.
*
*END**************************************************************************/
void ADC_SetAverageNum(ADC_Type* base, uint8_t logicCh, uint8_t avgNum)
{
assert(logicCh <= adcLogicChSW);
assert(avgNum <= adcAvgNum32);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) = (ADC_CH_A_CFG2_REG(base) & ~ADC_CH_A_CFG2_CHA_AVG_NUMBER_MASK) | \
ADC_CH_A_CFG2_CHA_AVG_NUMBER(avgNum);
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) = (ADC_CH_B_CFG2_REG(base) & ~ADC_CH_B_CFG2_CHB_AVG_NUMBER_MASK) | \
ADC_CH_B_CFG2_CHB_AVG_NUMBER(avgNum);
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) = (ADC_CH_C_CFG2_REG(base) & ~ADC_CH_C_CFG2_CHC_AVG_NUMBER_MASK) | \
ADC_CH_C_CFG2_CHC_AVG_NUMBER(avgNum);
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) = (ADC_CH_D_CFG2_REG(base) & ~ADC_CH_D_CFG2_CHD_AVG_NUMBER_MASK) | \
ADC_CH_D_CFG2_CHD_AVG_NUMBER(avgNum);
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) = (ADC_CH_SW_CFG_REG(base) & ~ADC_CH_SW_CFG_CH_SW_AVG_NUMBER_MASK) | \
ADC_CH_SW_CFG_CH_SW_AVG_NUMBER(avgNum);
break;
default:
break;
}
}
/*******************************************************************************
* ADC Conversion Control functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetConvertCmd
* Description : Set continuous convert work mode of target logic channel.
*
*END**************************************************************************/
void ADC_SetConvertCmd(ADC_Type* base, uint8_t logicCh, bool enable)
{
assert(logicCh <= adcLogicChD);
if (enable)
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) = (ADC_CH_A_CFG1_REG(base) & ~ADC_CH_A_CFG1_CHA_SINGLE_MASK) |
ADC_CH_A_CFG1_CHA_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) = (ADC_CH_B_CFG1_REG(base) & ~ADC_CH_B_CFG1_CHB_SINGLE_MASK) |
ADC_CH_B_CFG1_CHB_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) = (ADC_CH_C_CFG1_REG(base) & ~ADC_CH_C_CFG1_CHC_SINGLE_MASK) |
ADC_CH_C_CFG1_CHC_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) = (ADC_CH_D_CFG1_REG(base) & ~ADC_CH_D_CFG1_CHD_SINGLE_MASK) |
ADC_CH_D_CFG1_CHD_EN_MASK;
break;
default:
break;
}
}
else
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) &= ~ADC_CH_A_CFG1_CHA_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) &= ~ADC_CH_B_CFG1_CHB_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) &= ~ADC_CH_C_CFG1_CHC_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) &= ~ADC_CH_D_CFG1_CHD_EN_MASK;
break;
default:
break;
}
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_TriggerSingleConvert
* Description : Trigger single time convert on the target logic channel.
*
*END**************************************************************************/
void ADC_TriggerSingleConvert(ADC_Type* base, uint8_t logicCh)
{
assert(logicCh <= adcLogicChSW);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) |= ADC_CH_A_CFG1_CHA_SINGLE_MASK | ADC_CH_A_CFG1_CHA_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) |= ADC_CH_B_CFG1_CHB_SINGLE_MASK | ADC_CH_B_CFG1_CHB_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) |= ADC_CH_C_CFG1_CHC_SINGLE_MASK | ADC_CH_C_CFG1_CHC_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) |= ADC_CH_D_CFG1_CHD_SINGLE_MASK | ADC_CH_D_CFG1_CHD_EN_MASK;
break;
case adcLogicChSW:
ADC_CH_SW_CFG_REG(base) |= ADC_CH_SW_CFG_START_CONV_MASK;
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_StopConvert
* Description : Stop current convert on the target logic channel.
*
*END**************************************************************************/
void ADC_StopConvert(ADC_Type* base, uint8_t logicCh)
{
assert(logicCh <= adcLogicChSW);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG1_REG(base) &= ~ADC_CH_A_CFG1_CHA_EN_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG1_REG(base) &= ~ADC_CH_B_CFG1_CHB_EN_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG1_REG(base) &= ~ADC_CH_C_CFG1_CHC_EN_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG1_REG(base) &= ~ADC_CH_D_CFG1_CHD_EN_MASK;
break;
case adcLogicChSW:
/* Wait until ADC conversion finish. */
while (ADC_CH_SW_CFG_REG(base) & ADC_CH_SW_CFG_START_CONV_MASK);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_GetConvertResult
* Description : Get 12-bit length right aligned convert result.
*
*END**************************************************************************/
uint16_t ADC_GetConvertResult(ADC_Type* base, uint8_t logicCh)
{
assert(logicCh <= adcLogicChSW);
switch (logicCh)
{
case adcLogicChA:
return ADC_CHA_B_CNV_RSLT_REG(base) & ADC_CHA_B_CNV_RSLT_CHA_CNV_RSLT_MASK;
case adcLogicChB:
return ADC_CHA_B_CNV_RSLT_REG(base) >> ADC_CHA_B_CNV_RSLT_CHB_CNV_RSLT_SHIFT;
case adcLogicChC:
return ADC_CHC_D_CNV_RSLT_REG(base) & ADC_CHC_D_CNV_RSLT_CHC_CNV_RSLT_MASK;
case adcLogicChD:
return ADC_CHC_D_CNV_RSLT_REG(base) >> ADC_CHC_D_CNV_RSLT_CHD_CNV_RSLT_SHIFT;
case adcLogicChSW:
return ADC_CH_SW_CNV_RSLT_REG(base) & ADC_CH_SW_CNV_RSLT_CH_SW_CNV_RSLT_MASK;
default:
return 0;
}
}
/*******************************************************************************
* ADC Comparer Control functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCmpMode
* Description : Set the work mode of ADC module build-in comparer on target
* logic channel.
*
*END**************************************************************************/
void ADC_SetCmpMode(ADC_Type* base, uint8_t logicCh, uint8_t cmpMode)
{
assert(logicCh <= adcLogicChD);
assert(cmpMode <= adcCmpModeOutOffInterval);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) = (ADC_CH_A_CFG2_REG(base) & ~ADC_CH_A_CFG2_CHA_CMP_MODE_MASK) | \
ADC_CH_A_CFG2_CHA_CMP_MODE(cmpMode);
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) = (ADC_CH_B_CFG2_REG(base) & ~ADC_CH_B_CFG2_CHB_CMP_MODE_MASK) | \
ADC_CH_B_CFG2_CHB_CMP_MODE(cmpMode);
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) = (ADC_CH_C_CFG2_REG(base) & ~ADC_CH_C_CFG2_CHC_CMP_MODE_MASK) | \
ADC_CH_C_CFG2_CHC_CMP_MODE(cmpMode);
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) = (ADC_CH_D_CFG2_REG(base) & ~ADC_CH_D_CFG2_CHD_CMP_MODE_MASK) | \
ADC_CH_D_CFG2_CHD_CMP_MODE(cmpMode);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCmpHighThres
* Description : Set ADC module build-in comparer high threshold on target
* logic channel.
*
*END**************************************************************************/
void ADC_SetCmpHighThres(ADC_Type* base, uint8_t logicCh, uint16_t threshold)
{
assert(logicCh <= adcLogicChD);
assert(threshold <= 0xFFF);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) = (ADC_CH_A_CFG2_REG(base) & ~ADC_CH_A_CFG2_CHA_HIGH_THRES_MASK) | \
ADC_CH_A_CFG2_CHA_HIGH_THRES(threshold);
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) = (ADC_CH_B_CFG2_REG(base) & ~ADC_CH_B_CFG2_CHB_HIGH_THRES_MASK) | \
ADC_CH_B_CFG2_CHB_HIGH_THRES(threshold);
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) = (ADC_CH_C_CFG2_REG(base) & ~ADC_CH_C_CFG2_CHC_HIGH_THRES_MASK) | \
ADC_CH_C_CFG2_CHC_HIGH_THRES(threshold);
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) = (ADC_CH_D_CFG2_REG(base) & ~ADC_CH_D_CFG2_CHD_HIGH_THRES_MASK) | \
ADC_CH_D_CFG2_CHD_HIGH_THRES(threshold);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetCmpLowThres
* Description : Set ADC module build-in comparer low threshold on target
* logic channel.
*
*END**************************************************************************/
void ADC_SetCmpLowThres(ADC_Type* base, uint8_t logicCh, uint16_t threshold)
{
assert(logicCh <= adcLogicChD);
assert(threshold <= 0xFFF);
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) = (ADC_CH_A_CFG2_REG(base) & ~ADC_CH_A_CFG2_CHA_LOW_THRES_MASK) | \
ADC_CH_A_CFG2_CHA_LOW_THRES(threshold);
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) = (ADC_CH_B_CFG2_REG(base) & ~ADC_CH_B_CFG2_CHB_LOW_THRES_MASK) | \
ADC_CH_B_CFG2_CHB_LOW_THRES(threshold);
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) = (ADC_CH_C_CFG2_REG(base) & ~ADC_CH_C_CFG2_CHC_LOW_THRES_MASK) | \
ADC_CH_B_CFG2_CHB_LOW_THRES(threshold);
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) = (ADC_CH_D_CFG2_REG(base) & ~ADC_CH_D_CFG2_CHD_LOW_THRES_MASK) | \
ADC_CH_D_CFG2_CHD_LOW_THRES(threshold);
break;
default:
break;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetAutoDisableCmd
* Description : Set the working mode of ADC module auto disable feature on
* target logic channel.
*
*END**************************************************************************/
void ADC_SetAutoDisableCmd(ADC_Type* base, uint8_t logicCh, bool enable)
{
assert(logicCh <= adcLogicChD);
if (enable)
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) |= ADC_CH_A_CFG2_CHA_AUTO_DIS_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) |= ADC_CH_B_CFG2_CHB_AUTO_DIS_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) |= ADC_CH_C_CFG2_CHC_AUTO_DIS_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) |= ADC_CH_D_CFG2_CHD_AUTO_DIS_MASK;
break;
default:
break;
}
}
else
{
switch (logicCh)
{
case adcLogicChA:
ADC_CH_A_CFG2_REG(base) &= ~ADC_CH_A_CFG2_CHA_AUTO_DIS_MASK;
break;
case adcLogicChB:
ADC_CH_B_CFG2_REG(base) &= ~ADC_CH_B_CFG2_CHB_AUTO_DIS_MASK;
break;
case adcLogicChC:
ADC_CH_C_CFG2_REG(base) &= ~ADC_CH_C_CFG2_CHC_AUTO_DIS_MASK;
break;
case adcLogicChD:
ADC_CH_D_CFG2_REG(base) &= ~ADC_CH_D_CFG2_CHD_AUTO_DIS_MASK;
break;
default:
break;
}
}
}
/*******************************************************************************
* Interrupt and Flag control functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetIntCmd
* Description : Enables or disables ADC interrupt requests.
*
*END**************************************************************************/
void ADC_SetIntCmd(ADC_Type* base, uint32_t intSource, bool enable)
{
if (enable)
ADC_INT_EN_REG(base) |= intSource;
else
ADC_INT_EN_REG(base) &= ~intSource;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetIntSigCmd
* Description : Enables or disables ADC interrupt flag when interrupt
* condition met.
*
*END**************************************************************************/
void ADC_SetIntSigCmd(ADC_Type* base, uint32_t intSignal, bool enable)
{
if (enable)
ADC_INT_SIG_EN_REG(base) |= intSignal;
else
ADC_INT_SIG_EN_REG(base) &= ~intSignal;
}
/*******************************************************************************
* DMA & FIFO control functions.
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetDmaReset
* Description : Set the reset state of ADC internal DMA part.
*
*END**************************************************************************/
void ADC_SetDmaReset(ADC_Type* base, bool active)
{
if (active)
ADC_DMA_FIFO_REG(base) |= ADC_DMA_FIFO_DMA_RST_MASK;
else
ADC_DMA_FIFO_REG(base) &= ~ADC_DMA_FIFO_DMA_RST_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetDmaCmd
* Description : Set the work mode of ADC DMA part.
*
*END**************************************************************************/
void ADC_SetDmaCmd(ADC_Type* base, bool enable)
{
if (enable)
ADC_DMA_FIFO_REG(base) |= ADC_DMA_FIFO_DMA_EN_MASK;
else
ADC_DMA_FIFO_REG(base) &= ~ADC_DMA_FIFO_DMA_EN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ADC_SetDmaFifoCmd
* Description : Set the work mode of ADC DMA FIFO part.
*
*END**************************************************************************/
void ADC_SetDmaFifoCmd(ADC_Type* base, bool enable)
{
if (enable)
ADC_DMA_FIFO_REG(base) |= ADC_DMA_FIFO_DMA_FIFO_EN_MASK;
else
ADC_DMA_FIFO_REG(base) &= ~ADC_DMA_FIFO_DMA_FIFO_EN_MASK;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,555 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ADC_IMX7D_H__
#define __ADC_IMX7D_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup adc_imx7d_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ADC module initialization structure. */
typedef struct _adc_init_config
{
uint32_t sampleRate; /*!< The desired ADC sample rate.*/
bool levelShifterEnable; /*!< The level shifter module configuration(Enable to power on ADC module).*/
} adc_init_config_t;
/*! @brief ADC logic channel initialization structure. */
typedef struct _adc_logic_ch_init_config
{
uint32_t convertRate; /*!< The continuous rate when continuous sample enabled.*/
uint8_t inputChannel; /*!< The logic channel to be set.*/
uint8_t averageNumber; /*!< The average number for hardware average function.*/
bool coutinuousEnable; /*!< Continuous sample mode enable configuration.*/
bool averageEnable; /*!< Hardware average enable configuration.*/
} adc_logic_ch_init_config_t;
/*! @brief ADC logic channel selection enumeration. */
enum _adc_logic_ch_selection
{
adcLogicChA = 0x0, /*!< ADC Logic Channel A.*/
adcLogicChB = 0x1, /*!< ADC Logic Channel B.*/
adcLogicChC = 0x2, /*!< ADC Logic Channel C.*/
adcLogicChD = 0x3, /*!< ADC Logic Channel D.*/
adcLogicChSW = 0x4, /*!< ADC Logic Channel Software.*/
};
/*! @brief ADC hardware average number enumeration. */
enum _adc_average_number
{
adcAvgNum4 = 0x0, /*!< ADC Hardware Average Number is set to 4.*/
adcAvgNum8 = 0x1, /*!< ADC Hardware Average Number is set to 8.*/
adcAvgNum16 = 0x2, /*!< ADC Hardware Average Number is set to 16.*/
adcAvgNum32 = 0x3, /*!< ADC Hardware Average Number is set to 32.*/
};
/*! @brief ADC build-in comparer work mode configuration enumeration. */
enum _adc_compare_mode
{
adcCmpModeDisable = 0x0, /*!< ADC build-in comparator is disabled.*/
adcCmpModeGreaterThanLow = 0x1, /*!< ADC build-in comparator is triggered when sample value greater than low threshold.*/
adcCmpModeLessThanLow = 0x2, /*!< ADC build-in comparator is triggered when sample value less than low threshold.*/
adcCmpModeInInterval = 0x3, /*!< ADC build-in comparator is triggered when sample value in interval between low and high threshold.*/
adcCmpModeGreaterThanHigh = 0x5, /*!< ADC build-in comparator is triggered when sample value greater than high threshold.*/
adcCmpModeLessThanHigh = 0x6, /*!< ADC build-in comparator is triggered when sample value less than high threshold.*/
adcCmpModeOutOffInterval = 0x7, /*!< ADC build-in comparator is triggered when sample value out of interval between low and high threshold.*/
};
/*! @brief This enumeration contains the settings for all of the ADC interrupt configurations. */
enum _adc_interrupt
{
adcIntLastFifoDataRead = ADC_INT_EN_LAST_FIFO_DATA_READ_EN_MASK, /*!< Last FIFO Data Read Interrupt Enable.*/
adcIntConvertTimeoutChSw = ADC_INT_EN_SW_CH_COV_TO_INT_EN_MASK, /*!< Software Channel Conversion Time Out Interrupt Enable.*/
adcIntConvertTimeoutChD = ADC_INT_EN_CHD_COV_TO_INT_EN_MASK, /*!< Channel D Conversion Time Out Interrupt Enable.*/
adcIntConvertTimeoutChC = ADC_INT_EN_CHC_COV_TO_INT_EN_MASK, /*!< Channel C Conversion Time Out Interrupt Enable.*/
adcIntConvertTimeoutChB = ADC_INT_EN_CHB_COV_TO_INT_EN_MASK, /*!< Channel B Conversion Time Out Interrupt Enable.*/
adcIntConvertTimeoutChA = ADC_INT_EN_CHA_COV_TO_INT_EN_MASK, /*!< Channel A Conversion Time Out Interrupt Enable.*/
adcIntConvertChSw = ADC_INT_EN_SW_CH_COV_INT_EN_MASK, /*!< Software Channel Conversion Interrupt Enable.*/
adcIntConvertChD = ADC_INT_EN_CHD_COV_INT_EN_MASK, /*!< Channel D Conversion Interrupt Enable.*/
adcIntConvertChC = ADC_INT_EN_CHC_COV_INT_EN_MASK, /*!< Channel C Conversion Interrupt Enable.*/
adcIntConvertChB = ADC_INT_EN_CHB_COV_INT_EN_MASK, /*!< Channel B Conversion Interrupt Enable.*/
adcIntConvertChA = ADC_INT_EN_CHA_COV_INT_EN_MASK, /*!< Channel A Conversion Interrupt Enable.*/
adcIntFifoOverrun = ADC_INT_EN_FIFO_OVERRUN_INT_EN_MASK, /*!< FIFO overrun Interrupt Enable.*/
adcIntFifoUnderrun = ADC_INT_EN_FIFO_UNDERRUN_INT_EN_MASK, /*!< FIFO underrun Interrupt Enable.*/
adcIntDmaReachWatermark = ADC_INT_EN_DMA_REACH_WM_INT_EN_MASK, /*!< DMA Reach Watermark Level Interrupt Enable.*/
adcIntCmpChD = ADC_INT_EN_CHD_CMP_INT_EN_MASK, /*!< Channel D Compare Interrupt Enable.*/
adcIntCmpChC = ADC_INT_EN_CHC_CMP_INT_EN_MASK, /*!< Channel C Compare Interrupt Enable.*/
adcIntCmpChB = ADC_INT_EN_CHB_CMP_INT_EN_MASK, /*!< Channel B Compare Interrupt Enable.*/
adcIntCmpChA = ADC_INT_EN_CHA_CMP_INT_EN_MASK, /*!< Channel A Compare Interrupt Enable.*/
};
/*! @brief Flag for ADC interrupt/DMA status check or polling status. */
enum _adc_status_flag
{
adcStatusLastFifoDataRead = ADC_INT_STATUS_LAST_FIFO_DATA_READ_MASK, /*!< Last FIFO Data Read status flag.*/
adcStatusConvertTimeoutChSw = ADC_INT_STATUS_SW_CH_COV_TO_MASK, /*!< Software Channel Conversion Time Out status flag.*/
adcStatusConvertTimeoutChD = ADC_INT_STATUS_CHD_COV_TO_MASK, /*!< Channel D Conversion Time Out status flag.*/
adcStatusConvertTimeoutChC = ADC_INT_STATUS_CHC_COV_TO_MASK, /*!< Channel C Conversion Time Out status flag.*/
adcStatusConvertTimeoutChB = ADC_INT_STATUS_CHB_COV_TO_MASK, /*!< Channel B Conversion Time Out status flag.*/
adcStatusConvertTimeoutChA = ADC_INT_STATUS_CHA_COV_TO_MASK, /*!< Channel A Conversion Time Out status flag.*/
adcStatusConvertChSw = ADC_INT_STATUS_SW_CH_COV_MASK, /*!< Software Channel Conversion status flag.*/
adcStatusConvertChD = ADC_INT_STATUS_CHD_COV_MASK, /*!< Channel D Conversion status flag.*/
adcStatusConvertChC = ADC_INT_STATUS_CHC_COV_MASK, /*!< Channel C Conversion status flag.*/
adcStatusConvertChB = ADC_INT_STATUS_CHB_COV_MASK, /*!< Channel B Conversion status flag.*/
adcStatusConvertChA = ADC_INT_STATUS_CHA_COV_MASK, /*!< Channel A Conversion status flag.*/
adcStatusFifoOverrun = ADC_INT_STATUS_FIFO_OVERRUN_MASK, /*!< FIFO Overrun status flag.*/
adcStatusFifoUnderrun = ADC_INT_STATUS_FIFO_UNDERRUN_MASK, /*!< FIFO Underrun status flag.*/
adcStatusDmaReachWatermark = ADC_INT_STATUS_DMA_REACH_WM_MASK, /*!< DMA Reach Watermark Level status flag.*/
adcStatusCmpChD = ADC_INT_STATUS_CHD_CMP_MASK, /*!< Channel D Compare status flag.*/
adcStatusCmpChC = ADC_INT_STATUS_CHC_CMP_MASK, /*!< Channel C Compare status flag.*/
adcStatusCmpChB = ADC_INT_STATUS_CHB_CMP_MASK, /*!< Channel B Compare status flag.*/
adcStatusCmpChA = ADC_INT_STATUS_CHA_CMP_MASK, /*!< Channel A Compare status flag.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name ADC Module Initialization and Configuration functions.
* @{
*/
/*!
* @brief Initialize ADC to reset state and initialize with initialization structure.
*
* @param base ADC base pointer.
* @param initConfig ADC initialization structure.
*/
void ADC_Init(ADC_Type* base, const adc_init_config_t* initConfig);
/*!
* @brief This function reset ADC module register content to its default value.
*
* @param base ADC base pointer.
*/
void ADC_Deinit(ADC_Type* base);
/*!
* @brief This function Enable ADC module build-in Level Shifter.
* For i.MX 7Dual, Level Shifter should always be enabled.
* User can disable Level Shifter to save power.
*
* @param base ADC base pointer.
*/
static inline void ADC_LevelShifterEnable(ADC_Type* base)
{
ADC_ADC_CFG_REG(base) |= ADC_ADC_CFG_ADC_EN_MASK;
}
/*!
* @brief This function Disable ADC module build-in Level Shifter
* to save power.
*
* @param base ADC base pointer.
*/
static inline void ADC_LevelShifterDisable(ADC_Type* base)
{
ADC_ADC_CFG_REG(base) &= ~ADC_ADC_CFG_ADC_EN_MASK;
}
/*!
* @brief This function is used to set ADC module sample rate.
*
* @param base ADC base pointer.
* @param sampleRate Desired ADC sample rate.
*/
void ADC_SetSampleRate(ADC_Type* base, uint32_t sampleRate);
/*@}*/
/*!
* @name ADC Low power control functions.
* @{
*/
/*!
* @brief This function is used to stop all digital part power.
*
* @param base ADC base pointer.
* @param clockDown Stop all ADC digital part or not.
* - true: Clock down.
* - false: Clock running.
*/
void ADC_SetClockDownCmd(ADC_Type* base, bool clockDown);
/*!
* @brief This function is used to power down ADC analogue core.
* Before entering into stop-mode, power down ADC analogue core first.
* @param base ADC base pointer.
* @param powerDown Power down ADC analogue core or not.
* - true: Power down the ADC analogue core.
* - false: Do not power down the ADC analogue core.
*/
void ADC_SetPowerDownCmd(ADC_Type* base, bool powerDown);
/*@}*/
/*!
* @name ADC Convert Channel Initialization and Configuration functions.
* @{
*/
/*!
* @brief Initialize ADC Logic channel with initialization structure.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param chInitConfig ADC logic channel initialization structure.
*/
void ADC_LogicChInit(ADC_Type* base, uint8_t logicCh, const adc_logic_ch_init_config_t* chInitConfig);
/*!
* @brief Reset target ADC logic channel registers to default value.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
*/
void ADC_LogicChDeinit(ADC_Type* base, uint8_t logicCh);
/*!
* @brief Select input channel for target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param inputCh Input channel selection for target logic channel(vary from 0 to 15).
*/
void ADC_SelectInputCh(ADC_Type* base, uint8_t logicCh, uint8_t inputCh);
/*!
* @brief Set ADC conversion rate of target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param convertRate ADC conversion rate in Hz.
*/
void ADC_SetConvertRate(ADC_Type* base, uint8_t logicCh, uint32_t convertRate);
/*!
* @brief Set work state of hardware average feature of target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param enable Enable/Disable hardware average
* - true: Enable hardware average of given logic channel.
* - false: Disable hardware average of given logic channel.
*/
void ADC_SetAverageCmd(ADC_Type* base, uint8_t logicCh, bool enable);
/*!
* @brief Set hardware average number of target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param avgNum hardware average number(should select from @ref _adc_average_number enumeration).
*/
void ADC_SetAverageNum(ADC_Type* base, uint8_t logicCh, uint8_t avgNum);
/*@}*/
/*!
* @name ADC Conversion Control functions.
* @{
*/
/*!
* @brief Set continuous convert work mode of target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param enable Enable/Disable continuous convertion.
* - true: Enable continuous convertion.
* - false: Disable continuous convertion.
*/
void ADC_SetConvertCmd(ADC_Type* base, uint8_t logicCh, bool enable);
/*!
* @brief Trigger single time convert on target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
*/
void ADC_TriggerSingleConvert(ADC_Type* base, uint8_t logicCh);
/*!
* @brief Stop current convert on target logic channel.
* For logic channel A ~ D, current conversion stops immediately.
* For Software channel, this function is waited until current conversion is finished.
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
*/
void ADC_StopConvert(ADC_Type* base, uint8_t logicCh);
/*!
* @brief Get 12-bit length right aligned convert result.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @return convert result on target logic channel.
*/
uint16_t ADC_GetConvertResult(ADC_Type* base, uint8_t logicCh);
/*@}*/
/*!
* @name ADC Comparer Control functions.
* @{
*/
/*!
* @brief Set the work mode of ADC module build-in comparer on target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param cmpMode Comparer work mode selected from @ref _adc_compare_mode enumeration.
*/
void ADC_SetCmpMode(ADC_Type* base, uint8_t logicCh, uint8_t cmpMode);
/*!
* @brief Set ADC module build-in comparer high threshold on target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param threshold Comparer threshold in 12-bit unsigned int formate.
*/
void ADC_SetCmpHighThres(ADC_Type* base, uint8_t logicCh, uint16_t threshold);
/*!
* @brief Set ADC module build-in comparer low threshold on target logic channel.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param threshold Comparer threshold in 12-bit unsigned int formate.
*/
void ADC_SetCmpLowThres(ADC_Type* base, uint8_t logicCh, uint16_t threshold);
/*!
* @brief Set the working mode of ADC module auto disable feature on target logic channel.
* This feature can disable continuous conversion when CMP condition matched.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
* @param enable Enable/Disable Auto Disable feature.
* - true: Enable Auto Disable feature.
* - false: Disable Auto Disable feature.
*/
void ADC_SetAutoDisableCmd(ADC_Type* base, uint8_t logicCh, bool enable);
/*@}*/
/*!
* @name Interrupt and Flag control functions.
* @{
*/
/*!
* @brief Enables or disables ADC interrupt requests.
*
* @param base ADC base pointer.
* @param intSource ADC interrupt sources to configuration.
* @param enable Enable/Disable given ADC interrupt.
* - true: Enable given ADC interrupt.
* - false: Disable given ADC interrupt.
*/
void ADC_SetIntCmd(ADC_Type* base, uint32_t intSource, bool enable);
/*!
* @brief Enables or disables ADC interrupt flag when interrupt condition met.
*
* @param base ADC base pointer.
* @param intSignal ADC interrupt signals to configuration (see @ref _adc_interrupt enumeration).
* @param enable Enable/Disable given ADC interrupt flags.
* - true: Enable given ADC interrupt flags.
* - false: Disable given ADC interrupt flags.
*/
void ADC_SetIntSigCmd(ADC_Type* base, uint32_t intSignal, bool enable);
/*!
* @brief Gets the ADC status flag state.
*
* @param base ADC base pointer.
* @param flags ADC status flag mask defined in @ref _adc_status_flag enumeration.
* @return ADC status, each bit represents one status flag
*/
static inline uint32_t ADC_GetStatusFlag(ADC_Type* base, uint32_t flags)
{
return (ADC_INT_STATUS_REG(base) & flags);
}
/*!
* @brief Clear one or more ADC status flag state.
*
* @param base ADC base pointer.
* @param flags ADC status flag mask defined in @ref _adc_status_flag enumeration.
*/
static inline void ADC_ClearStatusFlag(ADC_Type* base, uint32_t flags)
{
ADC_INT_STATUS_REG(base) &= ~flags;
}
/*@}*/
/*!
* @name DMA & FIFO control functions.
* @{
*/
/*!
* @brief Set the reset state of ADC internal DMA part.
*
* @param base ADC base pointer.
* @param active Reset DMA & DMA FIFO or not.
* - true: Reset the DMA and DMA FIFO return to its reset value.
* - false: Do not reset DMA and DMA FIFO.
*/
void ADC_SetDmaReset(ADC_Type* base, bool active);
/*!
* @brief Set the work mode of ADC DMA part.
*
* @param base ADC base pointer.
* @param enable Enable/Disable ADC DMA part.
* - true: Enable DMA, the data in DMA FIFO should move by SDMA.
* - false: Disable DMA, the data in DMA FIFO can only move by CPU.
*/
void ADC_SetDmaCmd(ADC_Type* base, bool enable);
/*!
* @brief Set the work mode of ADC DMA FIFO part.
*
* @param base ADC base pointer.
* @param enable Enable/Disable DMA FIFO.
* - true: Enable DMA FIFO.
* - false: Disable DMA FIFO.
*/
void ADC_SetDmaFifoCmd(ADC_Type* base, bool enable);
/*!
* @brief Select the logic channel that uses the DMA transfer.
*
* @param base ADC base pointer.
* @param logicCh ADC module logic channel selection (see @ref _adc_logic_ch_selection enumeration).
*/
static inline void ADC_SetDmaCh(ADC_Type* base, uint32_t logicCh)
{
assert(logicCh <= adcLogicChD);
ADC_DMA_FIFO_REG(base) = (ADC_DMA_FIFO_REG(base) & ~ADC_DMA_FIFO_DMA_CH_SEL_MASK) | \
ADC_DMA_FIFO_DMA_CH_SEL(logicCh);
}
/*!
* @brief Set the DMA request trigger watermark.
*
* @param base ADC base pointer.
* @param watermark DMA request trigger watermark.
*/
static inline void ADC_SetDmaWatermark(ADC_Type* base, uint32_t watermark)
{
assert(watermark <= 0x1FF);
ADC_DMA_FIFO_REG(base) = (ADC_DMA_FIFO_REG(base) & ~ADC_DMA_FIFO_DMA_WM_LVL_MASK) | \
ADC_DMA_FIFO_DMA_WM_LVL(watermark);
}
/*!
* @brief Get the convert result from DMA FIFO.
* Data position:
* DMA_FIFO_DATA1(27~16bits)
* DMA_FIFO_DATA0(11~0bits)
*
* @param base ADC base pointer.
* @return Get 2 ADC transfer result from DMA FIFO.
*/
static inline uint32_t ADC_GetFifoData(ADC_Type* base)
{
return ADC_DMA_FIFO_DAT_REG(base);
}
/*!
* @brief Get the DMA FIFO full status
*
* @param base ADC base pointer.
* @retval true: DMA FIFO full.
* @retval false: DMA FIFO not full.
*/
static inline bool ADC_IsFifoFull(ADC_Type* base)
{
return (bool)(ADC_FIFO_STATUS_REG(base) & ADC_FIFO_STATUS_FIFO_FULL_MASK);
}
/*!
* @brief Get the DMA FIFO empty status
*
* @param base ADC base pointer.
* @retval true: DMA FIFO is empty.
* @retval false: DMA FIFO is not empty.
*/
static inline bool ADC_IsFifoEmpty(ADC_Type* base)
{
return (bool)(ADC_FIFO_STATUS_REG(base) & ADC_FIFO_STATUS_FIFO_EMPTY_MASK);
}
/*!
* @brief Get the entries number in DMA FIFO.
*
* @param base ADC base pointer.
* @return The numbers of data in DMA FIFO.
*/
static inline uint8_t ADC_GetFifoEntries(ADC_Type* base)
{
return ADC_FIFO_STATUS_REG(base) & ADC_FIFO_STATUS_FIFO_ENTRIES_MASK;
}
/*@}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* __ADC_IMX7D_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ccm_analog_imx7d.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetArmPllFreq
* Description : Get ARM PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetArmPllFreq(CCM_ANALOG_Type * base)
{
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllArmControl))
return 24000000ul;
return 12000000ul * (CCM_ANALOG_PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetSysPllFreq
* Description : Get system PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetSysPllFreq(CCM_ANALOG_Type * base)
{
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPll480Control))
return 24000000ul;
if (CCM_ANALOG_PLL_480 & CCM_ANALOG_PLL_480_DIV_SELECT_MASK)
return 528000000ul;
else
return 480000000ul;
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetDdrPllFreq
* Description : Get DDR PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetDdrPllFreq(CCM_ANALOG_Type * base)
{
uint8_t divSelect, divTestSelect;
float factor;
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllDdrControl))
return 24000000ul;
divSelect = CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG) & CCM_ANALOG_PLL_DDR_DIV_SELECT_MASK;
divTestSelect = (CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG) & CCM_ANALOG_PLL_DDR_TEST_DIV_SELECT_MASK) >>
CCM_ANALOG_PLL_DDR_TEST_DIV_SELECT_SHIFT;
switch (divTestSelect)
{
case 0x0:
divTestSelect = 2;
break;
case 0x1:
divTestSelect = 1;
break;
case 0x2:
case 0x3:
divTestSelect = 0;
break;
}
if (CCM_ANALOG_PLL_DDR_SS_REG(base) & CCM_ANALOG_PLL_DDR_SS_ENABLE_MASK)
{
factor = ((float)(CCM_ANALOG_PLL_DDR_SS_REG(base) & CCM_ANALOG_PLL_DDR_SS_STEP_MASK)) /
((float)(CCM_ANALOG_PLL_DDR_DENOM_REG(base) & CCM_ANALOG_PLL_DDR_DENOM_B_MASK)) *
((float)(CCM_ANALOG_PLL_DDR_NUM_REG(base) & CCM_ANALOG_PLL_DDR_NUM_A_MASK));
return (uint32_t)((24000000ul >> divTestSelect) * (divSelect + factor));
}
else
{
return (24000000ul >> divTestSelect) * divSelect;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetEnetPllFreq
* Description : Get Ethernet PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetEnetPllFreq(CCM_ANALOG_Type * base)
{
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllEnetControl))
return 24000000ul;
return 1000000000ul;
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetAudioPllFreq
* Description : Get Ethernet PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetAudioPllFreq(CCM_ANALOG_Type * base)
{
uint8_t divSelect, divPostSelect, divTestSelect;
float factor;
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllAudioControl))
return 24000000ul;
divSelect = CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK;
divPostSelect = (CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_POST_DIV_SEL_MASK) >>
CCM_ANALOG_PLL_AUDIO_POST_DIV_SEL_SHIFT;
divTestSelect = (CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_TEST_DIV_SELECT_MASK) >>
CCM_ANALOG_PLL_AUDIO_TEST_DIV_SELECT_SHIFT;
switch (divPostSelect)
{
case 0x0:
case 0x2:
divPostSelect = 0;
break;
case 0x1:
divPostSelect = 1;
break;
case 0x3:
divPostSelect = 2;
break;
}
switch (divTestSelect)
{
case 0x0:
divTestSelect = 2;
break;
case 0x1:
divTestSelect = 1;
break;
case 0x2:
case 0x3:
divTestSelect = 0;
break;
}
if (CCM_ANALOG_PLL_AUDIO_SS_REG(base) & CCM_ANALOG_PLL_AUDIO_SS_ENABLE_MASK)
{
factor = ((float)(CCM_ANALOG_PLL_AUDIO_SS_REG(base) & CCM_ANALOG_PLL_AUDIO_SS_STEP_MASK)) /
((float)(CCM_ANALOG_PLL_AUDIO_DENOM_REG(base) & CCM_ANALOG_PLL_AUDIO_DENOM_B_MASK)) *
((float)(CCM_ANALOG_PLL_AUDIO_NUM_REG(base) & CCM_ANALOG_PLL_AUDIO_NUM_A_MASK));
return (uint32_t)(((24000000ul >> divTestSelect) >> divPostSelect) * (divSelect + factor));
}
else
{
return ((24000000ul >> divTestSelect) >> divPostSelect) * divSelect;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetVideoPllFreq
* Description : Get Ethernet PLL frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetVideoPllFreq(CCM_ANALOG_Type * base)
{
uint8_t divSelect, divPostSelect, divTestSelect;
float factor;
if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllVideoControl))
return 24000000ul;
divSelect = CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK;
divPostSelect = (CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_POST_DIV_SEL_MASK) >>
CCM_ANALOG_PLL_VIDEO_POST_DIV_SEL_SHIFT;
divTestSelect = (CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_TEST_DIV_SELECT_MASK) >>
CCM_ANALOG_PLL_VIDEO_TEST_DIV_SELECT_SHIFT;
switch (divPostSelect)
{
case 0x0:
case 0x2:
divPostSelect = 0;
break;
case 0x1:
divPostSelect = 1;
break;
case 0x3:
divPostSelect = 2;
break;
}
switch (divTestSelect)
{
case 0x0:
divTestSelect = 2;
break;
case 0x1:
divTestSelect = 1;
break;
case 0x2:
case 0x3:
divTestSelect = 0;
break;
}
if (CCM_ANALOG_PLL_VIDEO_SS_REG(base) & CCM_ANALOG_PLL_VIDEO_SS_ENABLE_MASK)
{
factor = ((float)(CCM_ANALOG_PLL_VIDEO_SS_REG(base) & CCM_ANALOG_PLL_VIDEO_SS_STEP_MASK)) /
((float)(CCM_ANALOG_PLL_VIDEO_DENOM_REG(base) & CCM_ANALOG_PLL_VIDEO_DENOM_B_MASK)) *
((float)(CCM_ANALOG_PLL_VIDEO_NUM_REG(base) & CCM_ANALOG_PLL_VIDEO_NUM_A_MASK));
return (uint32_t)(((24000000ul >> divTestSelect) >> divPostSelect) * (divSelect + factor));
}
else
{
return ((24000000ul >> divTestSelect) >> divPostSelect) * divSelect;
}
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_ANALOG_GetPfdFreq
* Description : Get PFD frequency
*
*END**************************************************************************/
uint32_t CCM_ANALOG_GetPfdFreq(CCM_ANALOG_Type * base, uint32_t pfdFrac)
{
uint32_t main, frac;
/* PFD should work with system PLL without bypass */
assert(!CCM_ANALOG_IsPllBypassed(base, ccmAnalogPll480Control));
main = CCM_ANALOG_GetSysPllFreq(base);
frac = CCM_ANALOG_GetPfdFrac(base, pfdFrac);
return main / frac * 18;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,398 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CCM_ANALOG_IMX7D_H__
#define __CCM_ANALOG_IMX7D_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup ccm_analog_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define CCM_ANALOG_TUPLE(reg, shift) ((offsetof(CCM_ANALOG_Type, reg) & 0xFFFF) | ((shift) << 16))
#define CCM_ANALOG_TUPLE_REG_OFF(base, tuple, off) (*((volatile uint32_t *)((uint32_t)base + ((tuple) & 0xFFFF) + off)))
#define CCM_ANALOG_TUPLE_REG(base, tuple) CCM_ANALOG_TUPLE_REG_OFF(base, tuple, 0)
#define CCM_ANALOG_TUPLE_REG_SET(base, tuple) CCM_ANALOG_TUPLE_REG_OFF(base, tuple, 4)
#define CCM_ANALOG_TUPLE_REG_CLR(base, tuple) CCM_ANALOG_TUPLE_REG_OFF(base, tuple, 8)
#define CCM_ANALOG_TUPLE_SHIFT(tuple) (((tuple) >> 16) & 0x1F)
/*!
* @brief PLL control names for PLL power/bypass/lock operations.
*
* These constants define the PLL control names for PLL power/bypass/lock operations.\n
* - 0:15: REG offset to CCM_ANALOG_BASE in bytes.
* - 16:20: Power down bit shift.
*/
enum _ccm_analog_pll_control
{
ccmAnalogPllArmControl = CCM_ANALOG_TUPLE(PLL_ARM, CCM_ANALOG_PLL_ARM_POWERDOWN_SHIFT), /*!< CCM Analog ARM PLL Control.*/
ccmAnalogPllDdrControl = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_POWERDOWN_SHIFT), /*!< CCM Analog DDR PLL Control.*/
ccmAnalogPll480Control = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_POWERDOWN_SHIFT), /*!< CCM Analog 480M PLL Control.*/
ccmAnalogPllEnetControl = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_POWERDOWN_SHIFT), /*!< CCM Analog Ethernet PLL Control.*/
ccmAnalogPllAudioControl = CCM_ANALOG_TUPLE(PLL_AUDIO, CCM_ANALOG_PLL_AUDIO_POWERDOWN_SHIFT), /*!< CCM Analog AUDIO PLL Control.*/
ccmAnalogPllVideoControl = CCM_ANALOG_TUPLE(PLL_VIDEO, CCM_ANALOG_PLL_VIDEO_POWERDOWN_SHIFT), /*!< CCM Analog VIDEO PLL Control.*/
};
/*!
* @brief PLL clock names for clock enable/disable settings.
*
* These constants define the PLL clock names for PLL clock enable/disable operations.\n
* - 0:15: REG offset to CCM_ANALOG_BASE in bytes.
* - 16:20: Clock enable bit shift.
*/
enum _ccm_analog_pll_clock
{
ccmAnalogPllArmClock = CCM_ANALOG_TUPLE(PLL_ARM, CCM_ANALOG_PLL_ARM_ENABLE_CLK_SHIFT), /*!< CCM Analog ARM PLL Clock.*/
ccmAnalogPllDdrClock = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_ENABLE_CLK_SHIFT), /*!< CCM Analog DDR PLL Clock.*/
ccmAnalogPllDdrDiv2Clock = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK_SHIFT), /*!< CCM Analog DDR PLL divided by 2 Clock.*/
ccmAnalogPll480Clock = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_ENABLE_CLK_SHIFT), /*!< CCM Analog 480M PLL Clock.*/
ccmAnalogPllEnet25MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_SHIFT), /*!< CCM Analog Ethernet 25M PLL Clock.*/
ccmAnalogPllEnet40MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_SHIFT), /*!< CCM Analog Ethernet 40M PLL Clock.*/
ccmAnalogPllEnet50MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_SHIFT), /*!< CCM Analog Ethernet 50M PLL Clock.*/
ccmAnalogPllEnet100MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_SHIFT), /*!< CCM Analog Ethernet 100M PLL Clock.*/
ccmAnalogPllEnet125MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_SHIFT), /*!< CCM Analog Ethernet 125M PLL Clock.*/
ccmAnalogPllEnet250MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_SHIFT), /*!< CCM Analog Ethernet 250M PLL Clock.*/
ccmAnalogPllEnet500MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_SHIFT), /*!< CCM Analog Ethernet 500M PLL Clock.*/
ccmAnalogPllAudioClock = CCM_ANALOG_TUPLE(PLL_AUDIO, CCM_ANALOG_PLL_AUDIO_ENABLE_CLK_SHIFT), /*!< CCM Analog AUDIO PLL Clock.*/
ccmAnalogPllVideoClock = CCM_ANALOG_TUPLE(PLL_VIDEO, CCM_ANALOG_PLL_VIDEO_ENABLE_CLK_SHIFT), /*!< CCM Analog VIDEO PLL Clock.*/
};
/*!
* @brief PFD gate names for clock gate settings, clock source is system PLL(PLL_480)
*
* These constants define the PFD gate names for PFD clock enable/disable operations.\n
* - 0:15: REG offset to CCM_ANALOG_BASE in bytes.
* - 16:20: Clock gate bit shift.
*/
enum _ccm_analog_pfd_clkgate
{
ccmAnalogMainDiv1ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_MAIN_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480 MAIN DIV1 Clock Gate.*/
ccmAnalogMainDiv2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_MAIN_DIV2_CLKGATE_SHIFT), /*!< CCM Analog 480 MAIN DIV2 Clock Gate.*/
ccmAnalogMainDiv4ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_MAIN_DIV4_CLKGATE_SHIFT), /*!< CCM Analog 480 MAIN DIV4 Clock Gate.*/
ccmAnalogPfd0Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD0_DIV2_CLKGATE_SHIFT), /*!< CCM Analog 480 PFD0 DIV2 Clock Gate.*/
ccmAnalogPfd1Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD1_DIV2_CLKGATE_SHIFT), /*!< CCM Analog 480 PFD1 DIV2 Clock Gate.*/
ccmAnalogPfd2Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD2_DIV2_CLKGATE_SHIFT), /*!< CCM Analog 480 PFD2 DIV2 Clock Gate.*/
ccmAnalogPfd0Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480A PFD0 DIV1 Clock Gate.*/
ccmAnalogPfd1Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480A PFD1 DIV1 Clock Gate.*/
ccmAnalogPfd2Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480A PFD2 DIV1 Clock Gate.*/
ccmAnalogPfd3Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480A PFD3 DIV1 Clock Gate.*/
ccmAnalogPfd4Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480B PFD4 DIV1 Clock Gate.*/
ccmAnalogPfd5Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480B PFD5 DIV1 Clock Gate.*/
ccmAnalogPfd6Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480B PFD6 DIV1 Clock Gate.*/
ccmAnalogPfd7Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_DIV1_CLKGATE_SHIFT), /*!< CCM Analog 480B PFD7 DIV1 Clock Gate.*/
};
/*!
* @brief PFD fraction names for clock fractional divider operations
*
* These constants define the PFD fraction names for PFD fractional divider operations.\n
* - 0:15: REG offset to CCM_ANALOG_BASE in bytes.
* - 16:20: Fraction bits shift.
*/
enum _ccm_analog_pfd_frac
{
ccmAnalogPfd0Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT), /*!< CCM Analog 480A PFD0 fractional divider.*/
ccmAnalogPfd1Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT), /*!< CCM Analog 480A PFD1 fractional divider.*/
ccmAnalogPfd2Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT), /*!< CCM Analog 480A PFD2 fractional divider.*/
ccmAnalogPfd3Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_FRAC_SHIFT), /*!< CCM Analog 480A PFD3 fractional divider.*/
ccmAnalogPfd4Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_FRAC_SHIFT), /*!< CCM Analog 480B PFD4 fractional divider.*/
ccmAnalogPfd5Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_FRAC_SHIFT), /*!< CCM Analog 480B PFD5 fractional divider.*/
ccmAnalogPfd6Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_FRAC_SHIFT), /*!< CCM Analog 480B PFD6 fractional divider.*/
ccmAnalogPfd7Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_FRAC_SHIFT), /*!< CCM Analog 480B PFD7 fractional divider.*/
};
/*!
* @brief PFD stable names for clock stable query
*
* These constants define the PFD stable names for clock stable query.\n
* - 0:15: REG offset to CCM_ANALOG_BASE in bytes.
* - 16:20: Stable bit shift.
*/
enum _ccm_analog_pfd_stable
{
ccmAnalogPfd0Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_STABLE_SHIFT), /*!< CCM Analog 480A PFD0 clock stable query.*/
ccmAnalogPfd1Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_STABLE_SHIFT), /*!< CCM Analog 480A PFD1 clock stable query.*/
ccmAnalogPfd2Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_STABLE_SHIFT), /*!< CCM Analog 480A PFD2 clock stable query.*/
ccmAnalogPfd3Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_STABLE_SHIFT), /*!< CCM Analog 480A PFD3 clock stable query.*/
ccmAnalogPfd4Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_STABLE_SHIFT), /*!< CCM Analog 480B PFD4 clock stable query.*/
ccmAnalogPfd5Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_STABLE_SHIFT), /*!< CCM Analog 480B PFD5 clock stable query.*/
ccmAnalogPfd6Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_STABLE_SHIFT), /*!< CCM Analog 480B PFD6 clock stable query.*/
ccmAnalogPfd7Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_STABLE_SHIFT), /*!< CCM Analog 480B PFD7 clock stable query.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name CCM Analog PLL Operatoin Functions
* @{
*/
/*!
* @brief Power up PLL
*
* @param base CCM_ANALOG base pointer.
* @param pllControl PLL control name (see @ref _ccm_analog_pll_control enumeration)
*/
static inline void CCM_ANALOG_PowerUpPll(CCM_ANALOG_Type * base, uint32_t pllControl)
{
CCM_ANALOG_TUPLE_REG_CLR(base, pllControl) = 1 << CCM_ANALOG_TUPLE_SHIFT(pllControl);
}
/*!
* @brief Power down PLL
*
* @param base CCM_ANALOG base pointer.
* @param pllControl PLL control name (see @ref _ccm_analog_pll_control enumeration)
*/
static inline void CCM_ANALOG_PowerDownPll(CCM_ANALOG_Type * base, uint32_t pllControl)
{
CCM_ANALOG_TUPLE_REG_SET(base, pllControl) = 1 << CCM_ANALOG_TUPLE_SHIFT(pllControl);
}
/*!
* @brief PLL bypass setting
*
* @param base CCM_ANALOG base pointer.
* @param pllControl PLL control name (see @ref _ccm_analog_pll_control enumeration)
* @param bypass Bypass the PLL.
* - true: Bypass the PLL.
* - false: Do not bypass the PLL.
*/
static inline void CCM_ANALOG_SetPllBypass(CCM_ANALOG_Type * base, uint32_t pllControl, bool bypass)
{
if (bypass)
CCM_ANALOG_TUPLE_REG_SET(base, pllControl) = CCM_ANALOG_PLL_ARM_BYPASS_MASK;
else
CCM_ANALOG_TUPLE_REG_CLR(base, pllControl) = CCM_ANALOG_PLL_ARM_BYPASS_MASK;
}
/*!
* @brief Check if PLL is bypassed
*
* @param base CCM_ANALOG base pointer.
* @param pllControl PLL control name (see @ref _ccm_analog_pll_control enumeration)
* @return PLL bypass status.
* - true: The PLL is bypassed.
* - false: The PLL is not bypassed.
*/
static inline bool CCM_ANALOG_IsPllBypassed(CCM_ANALOG_Type * base, uint32_t pllControl)
{
return (bool)(CCM_ANALOG_TUPLE_REG(base, pllControl) & CCM_ANALOG_PLL_ARM_BYPASS_MASK);
}
/*!
* @brief Check if PLL clock is locked
*
* @param base CCM_ANALOG base pointer.
* @param pllControl PLL control name (see @ref _ccm_analog_pll_control enumeration)
* @return PLL lock status.
* - true: The PLL clock is locked.
* - false: The PLL clock is not locked.
*/
static inline bool CCM_ANALOG_IsPllLocked(CCM_ANALOG_Type * base, uint32_t pllControl)
{
return (bool)(CCM_ANALOG_TUPLE_REG(base, pllControl) & CCM_ANALOG_PLL_ARM_LOCK_MASK);
}
/*!
* @brief Enable PLL clock
*
* @param base CCM_ANALOG base pointer.
* @param pllClock PLL clock name (see @ref _ccm_analog_pll_clock enumeration)
*/
static inline void CCM_ANALOG_EnablePllClock(CCM_ANALOG_Type * base, uint32_t pllClock)
{
CCM_ANALOG_TUPLE_REG_SET(base, pllClock) = 1 << CCM_ANALOG_TUPLE_SHIFT(pllClock);
}
/*!
* @brief Disable PLL clock
*
* @param base CCM_ANALOG base pointer.
* @param pllClock PLL clock name (see @ref _ccm_analog_pll_clock enumeration)
*/
static inline void CCM_ANALOG_DisablePllClock(CCM_ANALOG_Type * base, uint32_t pllClock)
{
CCM_ANALOG_TUPLE_REG_CLR(base, pllClock) = 1 << CCM_ANALOG_TUPLE_SHIFT(pllClock);
}
/*!
* @brief Get ARM PLL clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return ARM PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetArmPllFreq(CCM_ANALOG_Type * base);
/*!
* @brief Get System PLL (PLL_480) clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return System PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetSysPllFreq(CCM_ANALOG_Type * base);
/*!
* @brief Get DDR PLL clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return DDR PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetDdrPllFreq(CCM_ANALOG_Type * base);
/*!
* @brief Get ENET PLL clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return ENET PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetEnetPllFreq(CCM_ANALOG_Type * base);
/*!
* @brief Get Audio PLL clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return Audio PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetAudioPllFreq(CCM_ANALOG_Type * base);
/*!
* @brief Get Video PLL clock frequency
*
* @param base CCM_ANALOG base pointer.
* @return Video PLL clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetVideoPllFreq(CCM_ANALOG_Type * base);
/*@}*/
/*!
* @name CCM Analog PFD Operatoin Functions
* @{
*/
/*!
* @brief Enable PFD clock
*
* @param base CCM_ANALOG base pointer.
* @param pfdClkGate PFD clock gate (see @ref _ccm_analog_pfd_clkgate enumeration)
*/
static inline void CCM_ANALOG_EnablePfdClock(CCM_ANALOG_Type * base, uint32_t pfdClkGate)
{
CCM_ANALOG_TUPLE_REG_CLR(base, pfdClkGate) = 1 << CCM_ANALOG_TUPLE_SHIFT(pfdClkGate);
}
/*!
* @brief Disable PFD clock
*
* @param base CCM_ANALOG base pointer.
* @param pfdClkGate PFD clock gate (see @ref _ccm_analog_pfd_clkgate enumeration)
*/
static inline void CCM_ANALOG_DisablePfdClock(CCM_ANALOG_Type * base, uint32_t pfdClkGate)
{
CCM_ANALOG_TUPLE_REG_SET(base, pfdClkGate) = 1 << CCM_ANALOG_TUPLE_SHIFT(pfdClkGate);
}
/*!
* @brief Check if PFD clock is stable
*
* @param base CCM_ANALOG base pointer.
* @param pfdStable PFD stable identifier (see @ref _ccm_analog_pfd_stable enumeration)
* @return PFD clock stable status.
* - true: The PFD clock is stable.
* - false: The PFD clock is not stable.
*/
static inline bool CCM_ANALOG_IsPfdStable(CCM_ANALOG_Type * base, uint32_t pfdStable)
{
return (bool)(CCM_ANALOG_TUPLE_REG(base, pfdStable) & (1 << CCM_ANALOG_TUPLE_SHIFT(pfdStable)));
}
/*!
* @brief Set PFD clock fraction
*
* @param base CCM_ANALOG base pointer.
* @param pfdFrac PFD clock fraction (see @ref _ccm_analog_pfd_frac enumeration)
* @param value PFD clock fraction value
*/
static inline void CCM_ANALOG_SetPfdFrac(CCM_ANALOG_Type * base, uint32_t pfdFrac, uint32_t value)
{
assert(value >= 12 && value <= 35);
CCM_ANALOG_TUPLE_REG_CLR(base, pfdFrac) = CCM_ANALOG_PFD_480A_CLR_PFD0_FRAC_MASK << CCM_ANALOG_TUPLE_SHIFT(pfdFrac);
CCM_ANALOG_TUPLE_REG_SET(base, pfdFrac) = value << CCM_ANALOG_TUPLE_SHIFT(pfdFrac);
}
/*!
* @brief Get PFD clock fraction
*
* @param base CCM_ANALOG base pointer.
* @param pfdFrac PFD clock fraction (see @ref _ccm_analog_pfd_frac enumeration)
* @return PFD clock fraction value
*/
static inline uint32_t CCM_ANALOG_GetPfdFrac(CCM_ANALOG_Type * base, uint32_t pfdFrac)
{
return (CCM_ANALOG_TUPLE_REG(base, pfdFrac) >> CCM_ANALOG_TUPLE_SHIFT(pfdFrac)) & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK;
}
/*!
* @brief Get PFD clock frequency
*
* @param base CCM_ANALOG base pointer.
* @param pfdFrac PFD clock fraction (see @ref _ccm_analog_pfd_frac enumeration)
* @return PFD clock frequency in Hz
*/
uint32_t CCM_ANALOG_GetPfdFreq(CCM_ANALOG_Type * base, uint32_t pfdFrac);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __CCM_ANALOG_IMX7D_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ccm_imx7d.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : CCM_SetDivider
* Description : Set root clock divider
*
*END**************************************************************************/
void CCM_SetRootDivider(CCM_Type * base, uint32_t ccmRoot, uint32_t pre, uint32_t post)
{
assert (pre < 8);
assert (post < 64);
CCM_REG(ccmRoot) = (CCM_REG(ccmRoot) &
(~(CCM_TARGET_ROOT_PRE_PODF_MASK | CCM_TARGET_ROOT_POST_PODF_MASK))) |
CCM_TARGET_ROOT_PRE_PODF(pre) | CCM_TARGET_ROOT_POST_PODF(post);
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_GetDivider
* Description : Get root clock divider
*
*END**************************************************************************/
void CCM_GetRootDivider(CCM_Type * base, uint32_t ccmRoot, uint32_t *pre, uint32_t *post)
{
assert (pre && post);
*pre = (CCM_REG(ccmRoot) & CCM_TARGET_ROOT_PRE_PODF_MASK) >> CCM_TARGET_ROOT_PRE_PODF_SHIFT;
*post = (CCM_REG(ccmRoot) & CCM_TARGET_ROOT_POST_PODF_MASK) >> CCM_TARGET_ROOT_POST_PODF_SHIFT;
}
/*FUNCTION**********************************************************************
*
* Function Name : CCM_UpdateRoot
* Description : Update clock root in one step, for dynamical clock switching
*
*END**************************************************************************/
void CCM_UpdateRoot(CCM_Type * base, uint32_t ccmRoot, uint32_t mux, uint32_t pre, uint32_t post)
{
assert (pre < 8);
assert (post < 64);
CCM_REG(ccmRoot) = (CCM_REG(ccmRoot) &
(~(CCM_TARGET_ROOT_MUX_MASK | CCM_TARGET_ROOT_PRE_PODF_MASK | CCM_TARGET_ROOT_POST_PODF_MASK))) |
CCM_TARGET_ROOT_MUX(mux) | CCM_TARGET_ROOT_PRE_PODF(pre) | CCM_TARGET_ROOT_POST_PODF(post);
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,470 @@
/*
* Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __CCM_IMX7D_H__
#define __CCM_IMX7D_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup ccm_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define CCM_REG_OFF(root, off) (*((volatile uint32_t *)((uint32_t)root + off)))
#define CCM_REG(root) CCM_REG_OFF(root, 0)
#define CCM_REG_SET(root) CCM_REG_OFF(root, 4)
#define CCM_REG_CLR(root) CCM_REG_OFF(root, 8)
/*! @brief Root control names for root clock setting. */
enum _ccm_root_control
{
ccmRootM4 = (uint32_t)(&CCM_TARGET_ROOT1), /*!< ARM Cortex-M4 Clock control name.*/
ccmRootAxi = (uint32_t)(&CCM_TARGET_ROOT16), /*!< AXI Clock control name.*/
ccmRootAhb = (uint32_t)(&CCM_TARGET_ROOT32), /*!< AHB Clock control name.*/
ccmRootIpg = (uint32_t)(&CCM_TARGET_ROOT33), /*!< IPG Clock control name.*/
ccmRootQspi = (uint32_t)(&CCM_TARGET_ROOT85), /*!< QSPI Clock control name.*/
ccmRootCan1 = (uint32_t)(&CCM_TARGET_ROOT89), /*!< CAN1 Clock control name.*/
ccmRootCan2 = (uint32_t)(&CCM_TARGET_ROOT90), /*!< CAN2 Clock control name.*/
ccmRootI2c1 = (uint32_t)(&CCM_TARGET_ROOT91), /*!< I2C1 Clock control name.*/
ccmRootI2c2 = (uint32_t)(&CCM_TARGET_ROOT92), /*!< I2C2 Clock control name.*/
ccmRootI2c3 = (uint32_t)(&CCM_TARGET_ROOT93), /*!< I2C3 Clock control name.*/
ccmRootI2c4 = (uint32_t)(&CCM_TARGET_ROOT94), /*!< I2C4 Clock control name.*/
ccmRootUart1 = (uint32_t)(&CCM_TARGET_ROOT95), /*!< UART1 Clock control name.*/
ccmRootUart2 = (uint32_t)(&CCM_TARGET_ROOT96), /*!< UART2 Clock control name.*/
ccmRootUart3 = (uint32_t)(&CCM_TARGET_ROOT97), /*!< UART3 Clock control name.*/
ccmRootUart4 = (uint32_t)(&CCM_TARGET_ROOT98), /*!< UART4 Clock control name.*/
ccmRootUart5 = (uint32_t)(&CCM_TARGET_ROOT99), /*!< UART5 Clock control name.*/
ccmRootUart6 = (uint32_t)(&CCM_TARGET_ROOT100), /*!< UART6 Clock control name.*/
ccmRootUart7 = (uint32_t)(&CCM_TARGET_ROOT101), /*!< UART7 Clock control name.*/
ccmRootEcspi1 = (uint32_t)(&CCM_TARGET_ROOT102), /*!< ECSPI1 Clock control name.*/
ccmRootEcspi2 = (uint32_t)(&CCM_TARGET_ROOT103), /*!< ECSPI2 Clock control name.*/
ccmRootEcspi3 = (uint32_t)(&CCM_TARGET_ROOT104), /*!< ECSPI3 Clock control name.*/
ccmRootEcspi4 = (uint32_t)(&CCM_TARGET_ROOT105), /*!< ECSPI4 Clock control name.*/
ccmRootFtm1 = (uint32_t)(&CCM_TARGET_ROOT110), /*!< FTM1 Clock control name.*/
ccmRootFtm2 = (uint32_t)(&CCM_TARGET_ROOT111), /*!< FTM2 Clock control name.*/
ccmRootGpt1 = (uint32_t)(&CCM_TARGET_ROOT114), /*!< GPT1 Clock control name.*/
ccmRootGpt2 = (uint32_t)(&CCM_TARGET_ROOT115), /*!< GPT2 Clock control name.*/
ccmRootGpt3 = (uint32_t)(&CCM_TARGET_ROOT116), /*!< GPT3 Clock control name.*/
ccmRootGpt4 = (uint32_t)(&CCM_TARGET_ROOT117), /*!< GPT4 Clock control name.*/
ccmRootWdog = (uint32_t)(&CCM_TARGET_ROOT119), /*!< WDOG Clock control name.*/
};
/*! @brief Clock source enumeration for ARM Cortex-M4 core. */
enum _ccm_rootmux_m4
{
ccmRootmuxM4Osc24m = 0U, /*!< ARM Cortex-M4 Clock from OSC 24M.*/
ccmRootmuxM4SysPllDiv2 = 1U, /*!< ARM Cortex-M4 Clock from SYSTEM PLL divided by 2.*/
ccmRootmuxM4EnetPll250m = 2U, /*!< ARM Cortex-M4 Clock from Ethernet PLL 250M.*/
ccmRootmuxM4SysPllPfd2 = 3U, /*!< ARM Cortex-M4 Clock from SYSTEM PLL PFD2.*/
ccmRootmuxM4DdrPllDiv2 = 4U, /*!< ARM Cortex-M4 Clock from DDR PLL divided by 2.*/
ccmRootmuxM4AudioPll = 5U, /*!< ARM Cortex-M4 Clock from AUDIO PLL.*/
ccmRootmuxM4VideoPll = 6U, /*!< ARM Cortex-M4 Clock from VIDEO PLL.*/
ccmRootmuxM4UsbPll = 7U, /*!< ARM Cortex-M4 Clock from USB PLL.*/
};
/*! @brief Clock source enumeration for AXI bus. */
enum _ccm_rootmux_axi
{
ccmRootmuxAxiOsc24m = 0U, /*!< AXI Clock from OSC 24M.*/
ccmRootmuxAxiSysPllPfd1 = 1U, /*!< AXI Clock from SYSTEM PLL PFD1.*/
ccmRootmuxAxiDdrPllDiv2 = 2U, /*!< AXI Clock DDR PLL divided by 2.*/
ccmRootmuxAxiEnetPll250m = 3U, /*!< AXI Clock Ethernet PLL 250M.*/
ccmRootmuxAxiSysPllPfd5 = 4U, /*!< AXI Clock SYSTEM PLL PFD5.*/
ccmRootmuxAxiAudioPll = 5U, /*!< AXI Clock AUDIO PLL.*/
ccmRootmuxAxiVideoPll = 6U, /*!< AXI Clock VIDEO PLL.*/
ccmRootmuxAxiSysPllPfd7 = 7U, /*!< AXI Clock SYSTEM PLL PFD7.*/
};
/*! @brief Clock source enumeration for AHB bus. */
enum _ccm_rootmux_ahb
{
ccmRootmuxAhbOsc24m = 0U, /*!< AHB Clock from OSC 24M.*/
ccmRootmuxAhbSysPllPfd2 = 1U, /*!< AHB Clock from SYSTEM PLL PFD2.*/
ccmRootmuxAhbDdrPllDiv2 = 2U, /*!< AHB Clock from DDR PLL divided by 2.*/
ccmRootmuxAhbSysPllPfd0 = 3U, /*!< AHB Clock from SYSTEM PLL PFD0.*/
ccmRootmuxAhbEnetPll125m = 4U, /*!< AHB Clock from Ethernet PLL 125M.*/
ccmRootmuxAhbUsbPll = 5U, /*!< AHB Clock from USB PLL.*/
ccmRootmuxAhbAudioPll = 6U, /*!< AHB Clock from AUDIO PLL.*/
ccmRootmuxAhbVideoPll = 7U, /*!< AHB Clock from VIDEO PLL.*/
};
/*! @brief Clock source enumeration for IPG bus. */
enum _ccm_rootmux_ipg
{
ccmRootmuxIpgAHB = 0U, /*!< IPG Clock from AHB Clock.*/
};
/*! @brief Clock source enumeration for QSPI peripheral. */
enum _ccm_rootmux_qspi
{
ccmRootmuxQspiOsc24m = 0U, /*!< QSPI Clock from OSC 24M.*/
ccmRootmuxQspiSysPllPfd4 = 1U, /*!< QSPI Clock from SYSTEM PLL PFD4.*/
ccmRootmuxQspiDdrPllDiv2 = 2U, /*!< QSPI Clock from DDR PLL divided by 2.*/
ccmRootmuxQspiEnetPll500m = 3U, /*!< QSPI Clock from Ethernet PLL 500M.*/
ccmRootmuxQspiSysPllPfd3 = 4U, /*!< QSPI Clock from SYSTEM PLL PFD3.*/
ccmRootmuxQspiSysPllPfd2 = 5U, /*!< QSPI Clock from SYSTEM PLL PFD2.*/
ccmRootmuxQspiSysPllPfd6 = 6U, /*!< QSPI Clock from SYSTEM PLL PFD6.*/
ccmRootmuxQspiSysPllPfd7 = 7U, /*!< QSPI Clock from SYSTEM PLL PFD7.*/
};
/*! @brief Clock source enumeration for CAN peripheral. */
enum _ccm_rootmux_can
{
ccmRootmuxCanOsc24m = 0U, /*!< CAN Clock from OSC 24M.*/
ccmRootmuxCanSysPllDiv4 = 1U, /*!< CAN Clock from SYSTEM PLL divided by 4.*/
ccmRootmuxCanDdrPllDiv2 = 2U, /*!< CAN Clock from SYSTEM PLL divided by 2.*/
ccmRootmuxCanSysPllDiv1 = 3U, /*!< CAN Clock from SYSTEM PLL divided by 1.*/
ccmRootmuxCanEnetPll40m = 4U, /*!< CAN Clock from Ethernet PLL 40M.*/
ccmRootmuxCanUsbPll = 5U, /*!< CAN Clock from USB PLL.*/
ccmRootmuxCanExtClk1 = 6U, /*!< CAN Clock from External Clock1.*/
ccmRootmuxCanExtClk34 = 7U, /*!< CAN Clock from External Clock34.*/
};
/*! @brief Clock source enumeration for ECSPI peripheral. */
enum _ccm_rootmux_ecspi
{
ccmRootmuxEcspiOsc24m = 0U, /*!< ECSPI Clock from OSC 24M.*/
ccmRootmuxEcspiSysPllDiv2 = 1U, /*!< ECSPI Clock from SYSTEM PLL divided by 2.*/
ccmRootmuxEcspiEnetPll40m = 2U, /*!< ECSPI Clock from Ethernet PLL 40M.*/
ccmRootmuxEcspiSysPllDiv4 = 3U, /*!< ECSPI Clock from SYSTEM PLL divided by 4.*/
ccmRootmuxEcspiSysPllDiv1 = 4U, /*!< ECSPI Clock from SYSTEM PLL divided by 1.*/
ccmRootmuxEcspiSysPllPfd4 = 5U, /*!< ECSPI Clock from SYSTEM PLL PFD4.*/
ccmRootmuxEcspiEnetPll250m = 6U, /*!< ECSPI Clock from Ethernet PLL 250M.*/
ccmRootmuxEcspiUsbPll = 7U, /*!< ECSPI Clock from USB PLL.*/
};
/*! @brief Clock source enumeration for I2C peripheral. */
enum _ccm_rootmux_i2c
{
ccmRootmuxI2cOsc24m = 0U, /*!< I2C Clock from OSC 24M.*/
ccmRootmuxI2cSysPllDiv4 = 1U, /*!< I2C Clock from SYSTEM PLL divided by 4.*/
ccmRootmuxI2cEnetPll50m = 2U, /*!< I2C Clock from Ethernet PLL 50M.*/
ccmRootmuxI2cDdrPllDiv2 = 3U, /*!< I2C Clock from DDR PLL divided by .*/
ccmRootmuxI2cAudioPll = 4U, /*!< I2C Clock from AUDIO PLL.*/
ccmRootmuxI2cVideoPll = 5U, /*!< I2C Clock from VIDEO PLL.*/
ccmRootmuxI2cUsbPll = 6U, /*!< I2C Clock from USB PLL.*/
ccmRootmuxI2cSysPllPfd2Div2 = 7U, /*!< I2C Clock from SYSTEM PLL PFD2 divided by 2.*/
};
/*! @brief Clock source enumeration for UART peripheral. */
enum _ccm_rootmux_uart
{
ccmRootmuxUartOsc24m = 0U, /*!< UART Clock from OSC 24M.*/
ccmRootmuxUartSysPllDiv2 = 1U, /*!< UART Clock from SYSTEM PLL divided by 2.*/
ccmRootmuxUartEnetPll40m = 2U, /*!< UART Clock from Ethernet PLL 40M.*/
ccmRootmuxUartEnetPll100m = 3U, /*!< UART Clock from Ethernet PLL 100M.*/
ccmRootmuxUartSysPllDiv1 = 4U, /*!< UART Clock from SYSTEM PLL divided by 1.*/
ccmRootmuxUartExtClk2 = 5U, /*!< UART Clock from External Clock 2.*/
ccmRootmuxUartExtClk34 = 6U, /*!< UART Clock from External Clock 34.*/
ccmRootmuxUartUsbPll = 7U, /*!< UART Clock from USB PLL.*/
};
/*! @brief Clock source enumeration for FlexTimer peripheral. */
enum _ccm_rootmux_ftm
{
ccmRootmuxFtmOsc24m = 0U, /*!< FTM Clock from OSC 24M.*/
ccmRootmuxFtmEnetPll100m = 1U, /*!< FTM Clock from Ethernet PLL 100M.*/
ccmRootmuxFtmSysPllDiv4 = 2U, /*!< FTM Clock from SYSTEM PLL divided by 4.*/
ccmRootmuxFtmEnetPll40m = 3U, /*!< FTM Clock from Ethernet PLL 40M.*/
ccmRootmuxFtmAudioPll = 4U, /*!< FTM Clock from AUDIO PLL.*/
ccmRootmuxFtmExtClk3 = 5U, /*!< FTM Clock from External Clock 3.*/
ccmRootmuxFtmRef1m = 6U, /*!< FTM Clock from Refernece Clock 1M.*/
ccmRootmuxFtmVideoPll = 7U, /*!< FTM Clock from VIDEO PLL.*/
};
/*! @brief Clock source enumeration for GPT peripheral. */
enum _ccm_rootmux_gpt
{
ccmRootmuxGptOsc24m = 0U, /*!< GPT Clock from OSC 24M.*/
ccmRootmuxGptEnetPll100m = 1U, /*!< GPT Clock from Ethernet PLL 100M.*/
ccmRootmuxGptSysPllPfd0 = 2U, /*!< GPT Clock from SYSTEM PLL PFD0.*/
ccmRootmuxGptEnetPll40m = 3U, /*!< GPT Clock from Ethernet PLL 40M.*/
ccmRootmuxGptVideoPll = 4U, /*!< GPT Clock from VIDEO PLL.*/
ccmRootmuxGptRef1m = 5U, /*!< GPT Clock from Refernece Clock 1M.*/
ccmRootmuxGptAudioPll = 6U, /*!< GPT Clock from AUDIO PLL.*/
ccmRootmuxGptExtClk = 7U, /*!< GPT Clock from External Clock.*/
};
/*! @brief Clock source enumeration for WDOG peripheral. */
enum _ccm_rootmux_wdog
{
ccmRootmuxWdogOsc24m = 0U, /*!< WDOG Clock from OSC 24M.*/
ccmRootmuxWdogSysPllPfd2Div2 = 1U, /*!< WDOG Clock from SYSTEM PLL PFD2 divided by 2.*/
ccmRootmuxWdogSysPllDiv4 = 2U, /*!< WDOG Clock from SYSTEM PLL divided by 4.*/
ccmRootmuxWdogDdrPllDiv2 = 3U, /*!< WDOG Clock from DDR PLL divided by 2.*/
ccmRootmuxWdogEnetPll125m = 4U, /*!< WDOG Clock from Ethernet PLL 125M.*/
ccmRootmuxWdogUsbPll = 5U, /*!< WDOG Clock from USB PLL.*/
ccmRootmuxWdogRef1m = 6U, /*!< WDOG Clock from Refernece Clock 1M.*/
ccmRootmuxWdogSysPllPfd1Div2 = 7U, /*!< WDOG Clock from SYSTEM PLL PFD1 divided by 2.*/
};
/*! @brief CCM PLL gate control. */
enum _ccm_pll_gate
{
ccmPllGateCkil = (uint32_t)(&CCM_PLL_CTRL0), /*!< Ckil PLL Gate.*/
ccmPllGateArm = (uint32_t)(&CCM_PLL_CTRL1), /*!< ARM PLL Gate.*/
ccmPllGateArmDiv1 = (uint32_t)(&CCM_PLL_CTRL2), /*!< ARM PLL Div1 Gate.*/
ccmPllGateDdr = (uint32_t)(&CCM_PLL_CTRL3), /*!< DDR PLL Gate.*/
ccmPllGateDdrDiv1 = (uint32_t)(&CCM_PLL_CTRL4), /*!< DDR PLL Div1 Gate.*/
ccmPllGateDdrDiv2 = (uint32_t)(&CCM_PLL_CTRL5), /*!< DDR PLL Div2 Gate.*/
ccmPllGateSys = (uint32_t)(&CCM_PLL_CTRL6), /*!< SYSTEM PLL Gate.*/
ccmPllGateSysDiv1 = (uint32_t)(&CCM_PLL_CTRL7), /*!< SYSTEM PLL Div1 Gate.*/
ccmPllGateSysDiv2 = (uint32_t)(&CCM_PLL_CTRL8), /*!< SYSTEM PLL Div2 Gate.*/
ccmPllGateSysDiv4 = (uint32_t)(&CCM_PLL_CTRL9), /*!< SYSTEM PLL Div4 Gate.*/
ccmPllGatePfd0 = (uint32_t)(&CCM_PLL_CTRL10), /*!< PFD0 Gate.*/
ccmPllGatePfd0Div2 = (uint32_t)(&CCM_PLL_CTRL11), /*!< PFD0 Div2 Gate.*/
ccmPllGatePfd1 = (uint32_t)(&CCM_PLL_CTRL12), /*!< PFD1 Gate.*/
ccmPllGatePfd1Div2 = (uint32_t)(&CCM_PLL_CTRL13), /*!< PFD1 Div2 Gate.*/
ccmPllGatePfd2 = (uint32_t)(&CCM_PLL_CTRL14), /*!< PFD2 Gate.*/
ccmPllGatePfd2Div2 = (uint32_t)(&CCM_PLL_CTRL15), /*!< PDF2 Div2.*/
ccmPllGatePfd3 = (uint32_t)(&CCM_PLL_CTRL16), /*!< PDF3 Gate.*/
ccmPllGatePfd4 = (uint32_t)(&CCM_PLL_CTRL17), /*!< PDF4 Gate.*/
ccmPllGatePfd5 = (uint32_t)(&CCM_PLL_CTRL18), /*!< PDF5 Gate.*/
ccmPllGatePfd6 = (uint32_t)(&CCM_PLL_CTRL19), /*!< PDF6 Gate.*/
ccmPllGatePfd7 = (uint32_t)(&CCM_PLL_CTRL20), /*!< PDF7 Gate.*/
ccmPllGateEnet = (uint32_t)(&CCM_PLL_CTRL21), /*!< Ethernet PLL Gate.*/
ccmPllGateEnet500m = (uint32_t)(&CCM_PLL_CTRL22), /*!< Ethernet 500M PLL Gate.*/
ccmPllGateEnet250m = (uint32_t)(&CCM_PLL_CTRL23), /*!< Ethernet 250M PLL Gate.*/
ccmPllGateEnet125m = (uint32_t)(&CCM_PLL_CTRL24), /*!< Ethernet 125M PLL Gate.*/
ccmPllGateEnet100m = (uint32_t)(&CCM_PLL_CTRL25), /*!< Ethernet 100M PLL Gate.*/
ccmPllGateEnet50m = (uint32_t)(&CCM_PLL_CTRL26), /*!< Ethernet 50M PLL Gate.*/
ccmPllGateEnet40m = (uint32_t)(&CCM_PLL_CTRL27), /*!< Ethernet 40M PLL Gate.*/
ccmPllGateEnet25m = (uint32_t)(&CCM_PLL_CTRL28), /*!< Ethernet 25M PLL Gate.*/
ccmPllGateAudio = (uint32_t)(&CCM_PLL_CTRL29), /*!< AUDIO PLL Gate.*/
ccmPllGateAudioDiv1 = (uint32_t)(&CCM_PLL_CTRL30), /*!< AUDIO PLL Div1 Gate.*/
ccmPllGateVideo = (uint32_t)(&CCM_PLL_CTRL31), /*!< VIDEO PLL Gate.*/
ccmPllGateVideoDiv1 = (uint32_t)(&CCM_PLL_CTRL32), /*!< VIDEO PLL Div1 Gate.*/
};
/*! @brief CCM CCGR gate control. */
enum _ccm_ccgr_gate
{
ccmCcgrGateSimWakeup = (uint32_t)(&CCM_CCGR9), /*!< Wakeup Mix Bus Clock Gate.*/
ccmCcgrGateIpmux1 = (uint32_t)(&CCM_CCGR10), /*!< IOMUX1 Clock Gate.*/
ccmCcgrGateIpmux2 = (uint32_t)(&CCM_CCGR11), /*!< IOMUX2 Clock Gate.*/
ccmCcgrGateIpmux3 = (uint32_t)(&CCM_CCGR12), /*!< IPMUX3 Clock Gate.*/
ccmCcgrGateOcram = (uint32_t)(&CCM_CCGR17), /*!< OCRAM Clock Gate.*/
ccmCcgrGateOcramS = (uint32_t)(&CCM_CCGR18), /*!< OCRAM S Clock Gate.*/
ccmCcgrGateQspi = (uint32_t)(&CCM_CCGR21), /*!< QSPI Clock Gate.*/
ccmCcgrGateAdc = (uint32_t)(&CCM_CCGR32), /*!< ADC Clock Gate.*/
ccmCcgrGateRdc = (uint32_t)(&CCM_CCGR38), /*!< RDC Clock Gate.*/
ccmCcgrGateMu = (uint32_t)(&CCM_CCGR39), /*!< MU Clock Gate.*/
ccmCcgrGateSemaHs = (uint32_t)(&CCM_CCGR40), /*!< SEMA HS Clock Gate.*/
ccmCcgrGateSema1 = (uint32_t)(&CCM_CCGR64), /*!< SEMA1 Clock Gate.*/
ccmCcgrGateSema2 = (uint32_t)(&CCM_CCGR65), /*!< SEMA2 Clock Gate.*/
ccmCcgrGateCan1 = (uint32_t)(&CCM_CCGR116), /*!< CAN1 Clock Gate.*/
ccmCcgrGateCan2 = (uint32_t)(&CCM_CCGR117), /*!< CAN2 Clock Gate.*/
ccmCcgrGateEcspi1 = (uint32_t)(&CCM_CCGR120), /*!< ECSPI1 Clock Gate.*/
ccmCcgrGateEcspi2 = (uint32_t)(&CCM_CCGR121), /*!< ECSPI2 Clock Gate.*/
ccmCcgrGateEcspi3 = (uint32_t)(&CCM_CCGR122), /*!< ECSPI3 Clock Gate.*/
ccmCcgrGateEcspi4 = (uint32_t)(&CCM_CCGR123), /*!< ECSPI4 Clock Gate.*/
ccmCcgrGateGpt1 = (uint32_t)(&CCM_CCGR124), /*!< GPT1 Clock Gate.*/
ccmCcgrGateGpt2 = (uint32_t)(&CCM_CCGR125), /*!< GPT2 Clock Gate.*/
ccmCcgrGateGpt3 = (uint32_t)(&CCM_CCGR126), /*!< GPT3 Clock Gate.*/
ccmCcgrGateGpt4 = (uint32_t)(&CCM_CCGR127), /*!< GPT4 Clock Gate.*/
ccmCcgrGateI2c1 = (uint32_t)(&CCM_CCGR136), /*!< I2C1 Clock Gate.*/
ccmCcgrGateI2c2 = (uint32_t)(&CCM_CCGR137), /*!< I2C2 Clock Gate.*/
ccmCcgrGateI2c3 = (uint32_t)(&CCM_CCGR138), /*!< I2C3 Clock Gate.*/
ccmCcgrGateI2c4 = (uint32_t)(&CCM_CCGR139), /*!< I2C4 Clock Gate.*/
ccmCcgrGateUart1 = (uint32_t)(&CCM_CCGR148), /*!< UART1 Clock Gate.*/
ccmCcgrGateUart2 = (uint32_t)(&CCM_CCGR149), /*!< UART2 Clock Gate.*/
ccmCcgrGateUart3 = (uint32_t)(&CCM_CCGR150), /*!< UART3 Clock Gate.*/
ccmCcgrGateUart4 = (uint32_t)(&CCM_CCGR151), /*!< UART4 Clock Gate.*/
ccmCcgrGateUart5 = (uint32_t)(&CCM_CCGR152), /*!< UART5 Clock Gate.*/
ccmCcgrGateUart6 = (uint32_t)(&CCM_CCGR153), /*!< UART6 Clock Gate.*/
ccmCcgrGateUart7 = (uint32_t)(&CCM_CCGR154), /*!< UART7 Clock Gate.*/
ccmCcgrGateWdog1 = (uint32_t)(&CCM_CCGR156), /*!< WDOG1 Clock Gate.*/
ccmCcgrGateWdog2 = (uint32_t)(&CCM_CCGR157), /*!< WDOG2 Clock Gate.*/
ccmCcgrGateWdog3 = (uint32_t)(&CCM_CCGR158), /*!< WDOG3 Clock Gate.*/
ccmCcgrGateWdog4 = (uint32_t)(&CCM_CCGR159), /*!< WDOG4 Clock Gate.*/
ccmCcgrGateGpio1 = (uint32_t)(&CCM_CCGR160), /*!< GPIO1 Clock Gate.*/
ccmCcgrGateGpio2 = (uint32_t)(&CCM_CCGR161), /*!< GPIO2 Clock Gate.*/
ccmCcgrGateGpio3 = (uint32_t)(&CCM_CCGR162), /*!< GPIO3 Clock Gate.*/
ccmCcgrGateGpio4 = (uint32_t)(&CCM_CCGR163), /*!< GPIO4 Clock Gate.*/
ccmCcgrGateGpio5 = (uint32_t)(&CCM_CCGR164), /*!< GPIO5 Clock Gate.*/
ccmCcgrGateGpio6 = (uint32_t)(&CCM_CCGR165), /*!< GPIO6 Clock Gate.*/
ccmCcgrGateGpio7 = (uint32_t)(&CCM_CCGR166), /*!< GPIO7 Clock Gate.*/
ccmCcgrGateIomux = (uint32_t)(&CCM_CCGR168), /*!< IOMUX Clock Gate.*/
ccmCcgrGateIomuxLpsr = (uint32_t)(&CCM_CCGR169), /*!< IOMUX LPSR Clock Gate.*/
};
/*! @brief CCM gate control value. */
enum _ccm_gate_value
{
ccmClockNotNeeded = 0x0U, /*!< Clock always disabled.*/
ccmClockNeededRun = 0x1111U, /*!< Clock enabled when CPU is running.*/
ccmClockNeededRunWait = 0x2222U, /*!< Clock enabled when CPU is running or in WAIT mode.*/
ccmClockNeededAll = 0x3333U, /*!< Clock always enabled.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name CCM Root Setting
* @{
*/
/*!
* @brief Set clock root mux
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @param mux Root mux value (see @ref _ccm_rootmux_xxx enumeration)
*/
static inline void CCM_SetRootMux(CCM_Type * base, uint32_t ccmRoot, uint32_t mux)
{
CCM_REG(ccmRoot) = (CCM_REG(ccmRoot) & (~CCM_TARGET_ROOT_MUX_MASK)) |
CCM_TARGET_ROOT_MUX(mux);
}
/*!
* @brief Get clock root mux
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @return root mux value (see @ref _ccm_rootmux_xxx enumeration)
*/
static inline uint32_t CCM_GetRootMux(CCM_Type * base, uint32_t ccmRoot)
{
return (CCM_REG(ccmRoot) & CCM_TARGET_ROOT_MUX_MASK) >> CCM_TARGET_ROOT_MUX_SHIFT;
}
/*!
* @brief Enable clock root
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
*/
static inline void CCM_EnableRoot(CCM_Type * base, uint32_t ccmRoot)
{
CCM_REG_SET(ccmRoot) = CCM_TARGET_ROOT_SET_ENABLE_MASK;
}
/*!
* @brief Disable clock root
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
*/
static inline void CCM_DisableRoot(CCM_Type * base, uint32_t ccmRoot)
{
CCM_REG_CLR(ccmRoot) = CCM_TARGET_ROOT_CLR_ENABLE_MASK;
}
/*!
* @brief Check whether clock root is enabled
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @return CCM root enabled or not.
* - true: Clock root is enabled.
* - false: Clock root is disabled.
*/
static inline bool CCM_IsRootEnabled(CCM_Type * base, uint32_t ccmRoot)
{
return (bool)(CCM_REG(ccmRoot) & CCM_TARGET_ROOT_ENABLE_MASK);
}
/*!
* @brief Set root clock divider
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @param pre Pre divider value (0-7, divider=n+1)
* @param post Post divider value (0-63, divider=n+1)
*/
void CCM_SetRootDivider(CCM_Type * base, uint32_t ccmRoot, uint32_t pre, uint32_t post);
/*!
* @brief Get root clock divider
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @param pre Pointer to pre divider value store address
* @param post Pointer to post divider value store address
*/
void CCM_GetRootDivider(CCM_Type * base, uint32_t ccmRoot, uint32_t *pre, uint32_t *post);
/*!
* @brief Update clock root in one step, for dynamical clock switching
*
* @param base CCM base pointer.
* @param ccmRoot Root control (see @ref _ccm_root_control enumeration)
* @param root mux value (see @ref _ccm_rootmux_xxx enumeration)
* @param pre Pre divider value (0-7, divider=n+1)
* @param post Post divider value (0-63, divider=n+1)
*/
void CCM_UpdateRoot(CCM_Type * base, uint32_t ccmRoot, uint32_t mux, uint32_t pre, uint32_t post);
/*@}*/
/*!
* @name CCM Gate Control
* @{
*/
/*!
* @brief Set PLL or CCGR gate control
*
* @param base CCM base pointer.
* @param ccmGate Gate control (see @ref _ccm_pll_gate and @ref _ccm_ccgr_gate enumeration)
* @param control Gate control value (see @ref _ccm_gate_value)
*/
static inline void CCM_ControlGate(CCM_Type * base, uint32_t ccmGate, uint32_t control)
{
CCM_REG(ccmGate) = control;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __CCM_IMX7D_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,205 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ecspi.h"
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* eCSPI Initialization and Configuration functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_Init
* Description : Initializes the eCSPI module according to the specified
* parameters in the initConfig.
*
*END**************************************************************************/
void ECSPI_Init(ECSPI_Type* base, const ecspi_init_config_t* initConfig)
{
/* Disable eCSPI module */
ECSPI_CONREG_REG(base) = 0;
/* Enable the eCSPI module before write to other registers */
ECSPI_Enable(base);
/* eCSPI CONREG Configuration */
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_BURST_LENGTH(initConfig->burstLength) |
ECSPI_CONREG_CHANNEL_SELECT(initConfig->channelSelect);
ECSPI_CONREG_REG(base) |= initConfig->ecspiAutoStart ? ECSPI_CONREG_SMC_MASK : 0;
/* eCSPI CONFIGREG Configuration */
ECSPI_CONFIGREG_REG(base) = ECSPI_CONFIGREG_SCLK_PHA(((initConfig->clockPhase) & 1) << (initConfig->channelSelect)) |
ECSPI_CONFIGREG_SCLK_POL(((initConfig->clockPolarity) & 1) << (initConfig->channelSelect));
/* Master or Slave mode Configuration */
if(initConfig->mode == ecspiMasterMode)
{
/* Set baud rate in bits per second */
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_CHANNEL_MODE(1 << (initConfig->channelSelect));
ECSPI_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate);
}
else
ECSPI_CONREG_REG(base) &= ~ECSPI_CONREG_CHANNEL_MODE(1 << (initConfig->channelSelect));
}
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_SetSampClockSource
* Description : Configure the clock source for the sample period counter.
*
*END**************************************************************************/
void ECSPI_SetSampClockSource(ECSPI_Type* base, uint32_t source)
{
/* Select the clock source */
if(source == ecspiSclk)
ECSPI_PERIODREG_REG(base) &= ~ECSPI_PERIODREG_CSRC_MASK;
else
ECSPI_PERIODREG_REG(base) |= ECSPI_PERIODREG_CSRC_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_SetBaudRate
* Description : Calculated the eCSPI baud rate in bits per second.
*
*END**************************************************************************/
uint32_t ECSPI_SetBaudRate(ECSPI_Type* base, uint32_t sourceClockInHz, uint32_t bitsPerSec)
{
uint32_t div, pre_div;
uint32_t post_baud; /* baud rate after post divider */
uint32_t pre_baud; /* baud rate before pre divider */
if(sourceClockInHz <= bitsPerSec)
{
ECSPI_CONREG_REG(base) &= ~ECSPI_CONREG_PRE_DIVIDER_MASK;
ECSPI_CONREG_REG(base) &= ~ECSPI_CONREG_POST_DIVIDER_MASK;
return sourceClockInHz;
}
div = sourceClockInHz / bitsPerSec;
if(div < 16) /* pre_divider is enough */
{
if((sourceClockInHz - bitsPerSec * div) < ((bitsPerSec * (div + 1)) - sourceClockInHz))
pre_div = div - 1; /* pre_divider value is one less than the real divider */
else
pre_div = div;
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_PRE_DIVIDER_MASK)) |
ECSPI_CONREG_PRE_DIVIDER(pre_div);
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_POST_DIVIDER_MASK)) |
ECSPI_CONREG_POST_DIVIDER(0);
return sourceClockInHz / (pre_div + 1);
}
pre_baud = bitsPerSec * 16;
for(div = 1; div < 16; div++)
{
post_baud = sourceClockInHz >> div;
if(post_baud < pre_baud)
break;
}
if(div == 16) /* divider is not enough, set the biggest ones */
{
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_PRE_DIVIDER(15);
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_POST_DIVIDER(15);
return post_baud / 16;
}
/* find the closed one */
if((post_baud - bitsPerSec * (post_baud / bitsPerSec)) < ((bitsPerSec * ((post_baud / bitsPerSec) + 1)) - post_baud))
pre_div = post_baud / bitsPerSec - 1;
else
pre_div = post_baud / bitsPerSec;
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_PRE_DIVIDER_MASK)) |
ECSPI_CONREG_PRE_DIVIDER(pre_div);
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_POST_DIVIDER_MASK)) |
ECSPI_CONREG_POST_DIVIDER(div);
return post_baud / (pre_div + 1);
}
/*******************************************************************************
* DMA management functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_SetDMACmd
* Description : Enable or disable the specified DMA Source.
*
*END**************************************************************************/
void ECSPI_SetDMACmd(ECSPI_Type* base, uint32_t source, bool enable)
{
/* Configure the DAM source */
if(enable)
ECSPI_DMAREG_REG(base) |= ((uint32_t)(1 << source));
else
ECSPI_DMAREG_REG(base) &= ~((uint32_t)(1 << source));
}
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_SetFIFOThreshold
* Description : Set the RXFIFO or TXFIFO threshold.
*
*END**************************************************************************/
void ECSPI_SetFIFOThreshold(ECSPI_Type* base, uint32_t fifo, uint32_t threshold)
{
/* configure the RXFIFO and TXFIFO threshold that can triggers a DMA/INT request */
if(fifo == ecspiTxfifoThreshold)
ECSPI_DMAREG_REG(base) = (ECSPI_DMAREG_REG(base) & (~ECSPI_DMAREG_TX_THRESHOLD_MASK)) |
ECSPI_DMAREG_TX_THRESHOLD(threshold);
else
ECSPI_DMAREG_REG(base) = (ECSPI_DMAREG_REG(base) & (~ECSPI_DMAREG_RX_THRESHOLD_MASK)) |
ECSPI_DMAREG_RX_THRESHOLD(threshold);
}
/*******************************************************************************
* Interrupts and flags management functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : ECSPI_SetIntCmd
* Description : Enable or disable eCSPI interrupts.
*
*END**************************************************************************/
void ECSPI_SetIntCmd(ECSPI_Type* base, uint32_t flags, bool enable)
{
/* Configure the Interrupt source */
if(enable)
ECSPI_INTREG_REG(base) |= flags;
else
ECSPI_INTREG_REG(base) &= ~flags;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,493 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __ECSPI_H__
#define __ECSPI_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup ecspi_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Channel select. */
enum _ecspi_channel_select
{
ecspiSelectChannel0 = 0U, /*!< Select Channel 0. Chip Select 0 (SS0) is asserted.*/
ecspiSelectChannel1 = 1U, /*!< Select Channel 1. Chip Select 1 (SS1) is asserted.*/
ecspiSelectChannel2 = 2U, /*!< Select Channel 2. Chip Select 2 (SS2) is asserted.*/
ecspiSelectChannel3 = 3U, /*!< Select Channel 3. Chip Select 3 (SS3) is asserted.*/
};
/*! @brief Channel mode. */
enum _ecspi_master_slave_mode
{
ecspiSlaveMode = 0U, /*!< Set Slave Mode.*/
ecspiMasterMode = 1U, /*!< Set Master Mode.*/
};
/*! @brief Clock phase. */
enum _ecspi_clock_phase
{
ecspiClockPhaseFirstEdge = 0U, /*!< Data is captured on the leading edge of the SCK and
changed on the following edge.*/
ecspiClockPhaseSecondEdge = 1U, /*!< Data is changed on the leading edge of the SCK and
captured on the following edge.*/
};
/*! @brief Clock polarity. */
enum _ecspi_clock_polarity
{
ecspiClockPolarityActiveHigh = 0U, /*!< Active-high eCSPI clock (idles low).*/
ecspiClockPolarityActiveLow = 1U, /*!< Active-low eCSPI clock (idles high).*/
};
/*! @brief SS signal polarity. */
enum _ecspi_ss_polarity
{
ecspiSSPolarityActiveLow = 0U, /*!< Active-low, eCSPI SS signal.*/
ecspiSSPolarityActiveHigh = 1U, /*!< Active-high, eCSPI SS signal.*/
};
/*! @brief Inactive state of data line. */
enum _ecspi_dataline_inactivestate
{
ecspiDataLineStayHigh = 0U, /*!< Data line inactive state stay high.*/
ecspiDataLineStayLow = 1U, /*!< Data line inactive state stay low.*/
};
/*! @brief Inactive state of SCLK. */
enum _ecspi_sclk_inactivestate
{
ecspiSclkStayLow = 0U, /*!< SCLK inactive state stay low.*/
ecspiSclkStayHigh = 1U, /*!< SCLK line inactive state stay high.*/
};
/*! @brief sample period counter clock source. */
enum _ecspi_sampleperiod_clocksource
{
ecspiSclk = 0U, /*!< Sample period counter clock from SCLK.*/
ecspiLowFreq32K = 1U, /*!< Sample period counter clock from from LFRC (32.768 KHz).*/
};
/*! @brief DMA Source definition. */
enum _ecspi_dma_source
{
ecspiDmaTxfifoEmpty = 7U, /*!< TXFIFO Empty DMA Request.*/
ecspiDmaRxfifoRequest = 23U, /*!< RXFIFO DMA Request.*/
ecspiDmaRxfifoTail = 31U, /*!< RXFIFO TAIL DMA Request.*/
};
/*! @brief RXFIFO and TXFIFO threshold. */
enum _ecspi_fifothreshold
{
ecspiTxfifoThreshold = 0U, /*!< Defines the FIFO threshold that triggers a TX DMA/INT request.*/
ecspiRxfifoThreshold = 16U, /*!< defines the FIFO threshold that triggers a RX DMA/INT request.*/
};
/*! @brief Status flag. */
enum _ecspi_status_flag
{
ecspiFlagTxfifoEmpty = 1U << 0, /*!< TXFIFO Empty Flag.*/
ecspiFlagTxfifoDataRequest = 1U << 1, /*!< TXFIFO Data Request Flag.*/
ecspiFlagTxfifoFull = 1U << 2, /*!< TXFIFO Full Flag.*/
ecspiFlagRxfifoReady = 1U << 3, /*!< RXFIFO Ready Flag.*/
ecspiFlagRxfifoDataRequest = 1U << 4, /*!< RXFIFO Data Request Flag.*/
ecspiFlagRxfifoFull = 1U << 5, /*!< RXFIFO Full Flag.*/
ecspiFlagRxfifoOverflow = 1U << 6, /*!< RXFIFO Overflow Flag.*/
ecspiFlagTxfifoTc = 1U << 7, /*!< TXFIFO Transform Completed Flag.*/
};
/*! @brief Data Ready Control. */
enum _ecspi_data_ready
{
ecspiRdyNoCare = 0U, /*!< The SPI_RDY signal is ignored.*/
ecspiRdyFallEdgeTrig = 1U, /*!< Burst is triggered by the falling edge of the SPI_RDY signal (edge-triggered).*/
ecspiRdyLowLevelTrig = 2U, /*!< Burst is triggered by a low level of the SPI_RDY signal (level-triggered).*/
ecspiRdyReserved = 3U, /*!< Reserved.*/
};
/*! @brief Init structure. */
typedef struct _ecspi_init_config
{
uint32_t clockRate; /*!< Specifies ECSPII module clock freq.*/
uint32_t baudRate; /*!< Specifies desired eCSPI baud rate.*/
uint32_t channelSelect; /*!< Specifies the channel select.*/
uint32_t mode; /*!< Specifies the mode.*/
uint32_t burstLength; /*!< Specifies the length of a burst to be transferred.*/
uint32_t clockPhase; /*!< Specifies the clock phase.*/
uint32_t clockPolarity; /*!< Specifies the clock polarity.*/
bool ecspiAutoStart; /*!< Specifies the start mode.*/
} ecspi_init_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name eCSPI Initialization and Configuration functions
* @{
*/
/*!
* @brief Initializes the eCSPI module.
*
* @param base eCSPI base pointer.
* @param initConfig eCSPI initialization structure.
*/
void ECSPI_Init(ECSPI_Type* base, const ecspi_init_config_t* initConfig);
/*!
* @brief Enables the specified eCSPI module.
*
* @param base eCSPI base pointer.
*/
static inline void ECSPI_Enable(ECSPI_Type* base)
{
/* Enable the eCSPI. */
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_EN_MASK;
}
/*!
* @brief Disable the specified eCSPI module.
*
* @param base eCSPI base pointer.
*/
static inline void ECSPI_Disable(ECSPI_Type* base)
{
/* Enable the eCSPI. */
ECSPI_CONREG_REG(base) &= ~ECSPI_CONREG_EN_MASK;
}
/*!
* @brief Insert the number of wait states to be inserted in data transfers.
*
* @param base eCSPI base pointer.
* @param number the number of wait states.
*/
static inline void ECSPI_InsertWaitState(ECSPI_Type* base, uint32_t number)
{
/* Configure the number of wait states inserted. */
ECSPI_PERIODREG_REG(base) = (ECSPI_PERIODREG_REG(base) & (~ECSPI_PERIODREG_SAMPLE_PERIOD_MASK)) |
ECSPI_PERIODREG_SAMPLE_PERIOD(number);
}
/*!
* @brief Set the clock source for the sample period counter.
*
* @param base eCSPI base pointer.
* @param source The clock source (see @ref _ecspi_sampleperiod_clocksource enumeration).
*/
void ECSPI_SetSampClockSource(ECSPI_Type* base, uint32_t source);
/*!
* @brief Set the eCSPI clocks insert between the chip select active edge
* and the first eCSPI clock edge.
*
* @param base eCSPI base pointer.
* @param delay The number of wait states.
*/
static inline void ECSPI_SetDelay(ECSPI_Type* base, uint32_t delay)
{
/* Set the number of clocks insert. */
ECSPI_PERIODREG_REG(base) = (ECSPI_PERIODREG_REG(base) & (~ECSPI_PERIODREG_CSD_CTL_MASK)) |
ECSPI_PERIODREG_CSD_CTL(delay);
}
/*!
* @brief Set the inactive state of SCLK.
*
* @param base eCSPI base pointer.
* @param channel eCSPI channel select (see @ref _ecspi_channel_select enumeration).
* @param state SCLK inactive state (see @ref _ecspi_sclk_inactivestate enumeration).
*/
static inline void ECSPI_SetSCLKInactiveState(ECSPI_Type* base, uint32_t channel, uint32_t state)
{
/* Configure the inactive state of SCLK. */
ECSPI_CONFIGREG_REG(base) = (ECSPI_CONFIGREG_REG(base) & (~ECSPI_CONFIGREG_SCLK_CTL(1 << channel))) |
ECSPI_CONFIGREG_SCLK_CTL((state & 1) << channel);
}
/*!
* @brief Set the inactive state of data line.
*
* @param base eCSPI base pointer.
* @param channel eCSPI channel select (see @ref _ecspi_channel_select enumeration).
* @param state Data line inactive state (see @ref _ecspi_dataline_inactivestate enumeration).
*/
static inline void ECSPI_SetDataInactiveState(ECSPI_Type* base, uint32_t channel, uint32_t state)
{
/* Set the inactive state of Data Line. */
ECSPI_CONFIGREG_REG(base) = (ECSPI_CONFIGREG_REG(base) & (~ECSPI_CONFIGREG_DATA_CTL(1 << channel))) |
ECSPI_CONFIGREG_DATA_CTL((state & 1) << channel);
}
/*!
* @brief Trigger a burst.
*
* @param base eCSPI base pointer.
*/
static inline void ECSPI_StartBurst(ECSPI_Type* base)
{
/* Start a burst. */
ECSPI_CONREG_REG(base) |= ECSPI_CONREG_XCH_MASK;
}
/*!
* @brief Set the burst length.
*
* @param base eCSPI base pointer.
* @param length The value of burst length.
*/
static inline void ECSPI_SetBurstLength(ECSPI_Type* base, uint32_t length)
{
/* Set the burst length according to length. */
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_BURST_LENGTH_MASK)) |
ECSPI_CONREG_BURST_LENGTH(length);
}
/*!
* @brief Set eCSPI SS Wave Form.
*
* @param base eCSPI base pointer.
* @param channel eCSPI channel selected (see @ref _ecspi_channel_select enumeration).
* @param ssMultiBurst For master mode, set true for multiple burst and false for one burst.
* For slave mode, set true to complete burst by SS signal edges and false to complete
* burst by number of bits received.
*/
static inline void ECSPI_SetSSMultipleBurst(ECSPI_Type* base, uint32_t channel, bool ssMultiBurst)
{
/* Set the SS wave form. */
ECSPI_CONFIGREG_REG(base) = (ECSPI_CONFIGREG_REG(base) & (~ECSPI_CONFIGREG_SS_CTL(1 << channel))) |
ECSPI_CONFIGREG_SS_CTL(ssMultiBurst << channel);
}
/*!
* @brief Set eCSPI SS Polarity.
*
* @param base eCSPI base pointer.
* @param channel eCSPI channel selected (see @ref _ecspi_channel_select enumeration).
* @param polarity Set SS signal active logic (see @ref _ecspi_ss_polarity enumeration).
*/
static inline void ECSPI_SetSSPolarity(ECSPI_Type* base, uint32_t channel, uint32_t polarity)
{
/* Set the SS polarity. */
ECSPI_CONFIGREG_REG(base) = (ECSPI_CONFIGREG_REG(base) & (~ECSPI_CONFIGREG_SS_POL(1 << channel))) |
ECSPI_CONFIGREG_SS_POL(polarity << channel);
}
/*!
* @brief Set the Data Ready Control.
*
* @param base eCSPI base pointer.
* @param spidataready eCSPI data ready control (see @ref _ecspi_data_ready enumeration).
*/
static inline void ECSPI_SetSPIDataReady(ECSPI_Type* base, uint32_t spidataready)
{
/* Set the Data Ready Control. */
ECSPI_CONREG_REG(base) = (ECSPI_CONREG_REG(base) & (~ECSPI_CONREG_DRCTL_MASK)) |
ECSPI_CONREG_DRCTL(spidataready);
}
/*!
* @brief Calculated the eCSPI baud rate in bits per second.
* The calculated baud rate must not exceed the desired baud rate.
*
* @param base eCSPI base pointer.
* @param sourceClockInHz eCSPI Clock(SCLK) (in Hz).
* @param bitsPerSec the value of Baud Rate.
* @return The calculated baud rate in bits-per-second, the nearest possible
* baud rate without exceeding the desired baud rate.
*/
uint32_t ECSPI_SetBaudRate(ECSPI_Type* base, uint32_t sourceClockInHz, uint32_t bitsPerSec);
/*@}*/
/*!
* @name Data transfers functions
* @{
*/
/*!
* @brief Transmits a data to TXFIFO.
*
* @param base eCSPI base pointer.
* @param data Data to be transmitted.
*/
static inline void ECSPI_SendData(ECSPI_Type* base, uint32_t data)
{
/* Write data to Transmit Data Register. */
ECSPI_TXDATA_REG(base) = data;
}
/*!
* @brief Receives a data from RXFIFO.
*
* @param base eCSPI base pointer.
* @return The value of received data.
*/
static inline uint32_t ECSPI_ReceiveData(ECSPI_Type* base)
{
/* Read data from Receive Data Register. */
return ECSPI_RXDATA_REG(base);
}
/*!
* @brief Read the number of words in the RXFIFO.
*
* @param base eCSPI base pointer.
* @return The number of words in the RXFIFO.
*/
static inline uint32_t ECSPI_GetRxfifoCounter(ECSPI_Type* base)
{
/* Get the number of words in the RXFIFO. */
return ((ECSPI_TESTREG_REG(base) & ECSPI_TESTREG_RXCNT_MASK) >> ECSPI_TESTREG_RXCNT_SHIFT);
}
/*!
* @brief Read the number of words in the TXFIFO.
*
* @param base eCSPI base pointer.
* @return The number of words in the TXFIFO.
*/
static inline uint32_t ECSPI_GetTxfifoCounter(ECSPI_Type* base)
{
/* Get the number of words in the RXFIFO. */
return ((ECSPI_TESTREG_REG(base) & ECSPI_TESTREG_TXCNT_MASK) >> ECSPI_TESTREG_TXCNT_SHIFT);
}
/*@}*/
/*!
* @name DMA management functions
* @{
*/
/*!
* @brief Enable or disable the specified DMA Source.
*
* @param base eCSPI base pointer.
* @param source specifies DMA source (see @ref _ecspi_dma_source enumeration).
* @param enable Enable/Disable specified DMA Source.
* - true: Enable specified DMA Source.
* - false: Disable specified DMA Source.
*/
void ECSPI_SetDMACmd(ECSPI_Type* base, uint32_t source, bool enable);
/*!
* @brief Set the burst length of a DMA operation.
*
* @param base eCSPI base pointer.
* @param length Specifies the burst length of a DMA operation.
*/
static inline void ECSPI_SetDMABurstLength(ECSPI_Type* base, uint32_t length)
{
/* Configure the burst length of a DMA operation. */
ECSPI_DMAREG_REG(base) = (ECSPI_DMAREG_REG(base) & (~ECSPI_DMAREG_RX_DMA_LENGTH_MASK)) |
ECSPI_DMAREG_RX_DMA_LENGTH(length);
}
/*!
* @brief Set the RXFIFO or TXFIFO threshold.
*
* @param base eCSPI base pointer.
* @param fifo Data transfer FIFO (see @ref _ecspi_fifothreshold enumeration).
* @param threshold Threshold value.
*/
void ECSPI_SetFIFOThreshold(ECSPI_Type* base, uint32_t fifo, uint32_t threshold);
/*@}*/
/*!
* @name Interrupts and flags management functions
* @{
*/
/*!
* @brief Enable or disable the specified eCSPI interrupts.
*
* @param base eCSPI base pointer.
* @param flags eCSPI status flag mask (see @ref _ecspi_status_flag for bit definition).
* @param enable Interrupt enable.
* - true: Enable specified eCSPI interrupts.
* - false: Disable specified eCSPI interrupts.
*/
void ECSPI_SetIntCmd(ECSPI_Type* base, uint32_t flags, bool enable);
/*!
* @brief Checks whether the specified eCSPI flag is set or not.
*
* @param base eCSPI base pointer.
* @param flags eCSPI status flag mask (see @ref _ecspi_status_flag for bit definition).
* @return eCSPI status, each bit represents one status flag.
*/
static inline uint32_t ECSPI_GetStatusFlag(ECSPI_Type* base, uint32_t flags)
{
/* return the vale of eCSPI status. */
return ECSPI_STATREG_REG(base) & flags;
}
/*!
* @brief Clear one or more eCSPI status flag.
*
* @param base eCSPI base pointer.
* @param flags eCSPI status flag mask (see @ref _ecspi_status_flag for bit definition).
*/
static inline void ECSPI_ClearStatusFlag(ECSPI_Type* base, uint32_t flags)
{
/* Write 1 to the status bit. */
ECSPI_STATREG_REG(base) = flags;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /*__ECSPI_H__*/
/*******************************************************************************
* EOF
******************************************************************************/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,712 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __FLEXCAN_H__
#define __FLEXCAN_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/* Start of section using anonymous unions. */
#if defined(__ARMCC_VERSION)
#pragma push
#pragma anon_unions
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma language=extended
#else
#error Not supported compiler type
#endif
/*!
* @addtogroup flexcan_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief FlexCAN message buffer CODE for Rx buffers. */
enum _flexcan_msgbuf_code_rx
{
flexcanRxInactive = 0x0, /*!< MB is not active. */
flexcanRxFull = 0x2, /*!< MB is full. */
flexcanRxEmpty = 0x4, /*!< MB is active and empty. */
flexcanRxOverrun = 0x6, /*!< MB is overwritten into a full buffer. */
flexcanRxBusy = 0x8, /*!< FlexCAN is updating the contents of the MB. */
/*! The CPU must not access the MB. */
flexcanRxRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */
/*! and transmit a Response Frame in return. */
flexcanRxNotUsed = 0xF, /*!< Not used. */
};
/*! @brief FlexCAN message buffer CODE FOR Tx buffers. */
enum _flexcan_msgbuf_code_tx
{
flexcanTxInactive = 0x8, /*!< MB is not active. */
flexcanTxAbort = 0x9, /*!< MB is aborted. */
flexcanTxDataOrRemte = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or */
/*!< MB is a TX Remote Request Frame (when MB RTR = 1). */
flexcanTxTanswer = 0xE, /*!< MB is a TX Response Request Frame from. */
/*! an incoming Remote Request Frame. */
flexcanTxNotUsed = 0xF, /*!< Not used. */
};
/*! @brief FlexCAN operation modes. */
enum _flexcan_operatining_modes
{
flexcanNormalMode = 0x1, /*!< Normal mode or user mode @internal gui name="Normal". */
flexcanListenOnlyMode = 0x2, /*!< Listen-only mode @internal gui name="Listen-only". */
flexcanLoopBackMode = 0x4, /*!< Loop-back mode @internal gui name="Loop back". */
};
/*! @brief FlexCAN RX mask mode. */
enum _flexcan_rx_mask_mode
{
flexcanRxMaskGlobal = 0x0, /*!< Rx global mask. */
flexcanRxMaskIndividual = 0x1, /*!< Rx individual mask. */
};
/*! @brief The ID type used in rx matching process. */
enum _flexcan_rx_mask_id_type
{
flexcanRxMaskIdStd = 0x0, /*!< Standard ID. */
flexcanRxMaskIdExt = 0x1, /*!< Extended ID. */
};
/*! @brief FlexCAN error interrupt source enumeration. */
enum _flexcan_interrutpt
{
flexcanIntRxWarning = 0x01, /*!< Tx Warning interrupt source. */
flexcanIntTxWarning = 0x02, /*!< Tx Warning interrupt source. */
flexcanIntWakeUp = 0x04, /*!< Wake Up interrupt source. */
flexcanIntBusOff = 0x08, /*!< Bus Off interrupt source. */
flexcanIntError = 0x10, /*!< Error interrupt source. */
};
/*! @brief FlexCAN error interrupt flags. */
enum _flexcan_status_flag
{
flexcanStatusSynch = CAN_ESR1_SYNCH_MASK, /*!< Bus Synchronized flag. */
flexcanStatusTxWarningInt = CAN_ESR1_TWRN_INT_MASK, /*!< Tx Warning initerrupt flag. */
flexcanStatusRxWarningInt = CAN_ESR1_RWRN_INT_MASK, /*!< Tx Warning initerrupt flag. */
flexcanStatusBit1Err = CAN_ESR1_BIT1_ERR_MASK, /*!< Bit0 Error flag. */
flexcanStatusBit0Err = CAN_ESR1_BIT0_ERR_MASK, /*!< Bit1 Error flag. */
flexcanStatusAckErr = CAN_ESR1_ACK_ERR_MASK, /*!< Ack Error flag. */
flexcanStatusCrcErr = CAN_ESR1_CRC_ERR_MASK, /*!< CRC Error flag. */
flexcanStatusFrameErr = CAN_ESR1_FRM_ERR_MASK, /*!< Frame Error flag. */
flexcanStatusStuffingErr = CAN_ESR1_STF_ERR_MASK, /*!< Stuffing Error flag. */
flexcanStatusTxWarning = CAN_ESR1_TX_WRN_MASK, /*!< Tx Warning flag. */
flexcanStatusRxWarning = CAN_ESR1_RX_WRN_MASK, /*!< Rx Warning flag. */
flexcanStatusIdle = CAN_ESR1_IDLE_MASK, /*!< FlexCAN Idle flag. */
flexcanStatusTransmitting = CAN_ESR1_TX_MASK, /*!< Trasmitting flag. */
flexcanStatusFltConf = CAN_ESR1_FLT_CONF_MASK, /*!< Fault Config flag. */
flexcanStatusReceiving = CAN_ESR1_RX_MASK, /*!< Receiving flag. */
flexcanStatusBusOff = CAN_ESR1_BOFF_INT_MASK, /*!< Bus Off interrupt flag. */
flexcanStatusError = CAN_ESR1_ERR_INT_MASK, /*!< Error interrupt flag. */
flexcanStatusWake = CAN_ESR1_WAK_INT_MASK, /*!< Wake Up interrupt flag. */
};
/*! @brief The id filter element type selection. */
enum _flexcan_rx_fifo_id_element_format
{
flexcanRxFifoIdElementFormatA = 0x0, /*!< One full ID (standard and extended) per ID Filter Table element. */
flexcanRxFifoIdElementFormatB = 0x1, /*!< Two full standard IDs or two partial 14-bit (standard and extended) IDs per ID Filter Table element. */
flexcanRxFifoIdElementFormatC = 0x2, /*!< Four partial 8-bit Standard IDs per ID Filter Table element. */
flexcanRxFifoIdElementFormatD = 0x3, /*!< All frames rejected. */
};
/*! @brief FlexCAN Rx FIFO filters number. */
enum _flexcan_rx_fifo_filter_id_number
{
flexcanRxFifoIdFilterNum8 = 0x0, /*!< 8 Rx FIFO Filters. @internal gui name="8 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum16 = 0x1, /*!< 16 Rx FIFO Filters. @internal gui name="16 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum24 = 0x2, /*!< 24 Rx FIFO Filters. @internal gui name="24 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum32 = 0x3, /*!< 32 Rx FIFO Filters. @internal gui name="32 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum40 = 0x4, /*!< 40 Rx FIFO Filters. @internal gui name="40 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum48 = 0x5, /*!< 48 Rx FIFO Filters. @internal gui name="48 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum56 = 0x6, /*!< 56 Rx FIFO Filters. @internal gui name="56 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum64 = 0x7, /*!< 64 Rx FIFO Filters. @internal gui name="64 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum72 = 0x8, /*!< 72 Rx FIFO Filters. @internal gui name="72 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum80 = 0x9, /*!< 80 Rx FIFO Filters. @internal gui name="80 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum88 = 0xA, /*!< 88 Rx FIFO Filters. @internal gui name="88 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum96 = 0xB, /*!< 96 Rx FIFO Filters. @internal gui name="96 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum104 = 0xC, /*!< 104 Rx FIFO Filters. @internal gui name="104 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum112 = 0xD, /*!< 112 Rx FIFO Filters. @internal gui name="112 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum120 = 0xE, /*!< 120 Rx FIFO Filters. @internal gui name="120 Rx FIFO Filters" */
flexcanRxFifoIdFilterNum128 = 0xF, /*!< 128 Rx FIFO Filters. @internal gui name="128 Rx FIFO Filters" */
};
/*! @brief FlexCAN RX FIFO ID filter table structure. */
typedef struct _flexcan_id_table
{
uint32_t *idFilter; /*!< Rx FIFO ID filter elements. */
bool isRemoteFrame; /*!< Remote frame. */
bool isExtendedFrame; /*!< Extended frame. */
} flexcan_id_table_t;
/*! @brief FlexCAN message buffer structure. */
typedef struct _flexcan_msgbuf
{
union
{
uint32_t cs; /*!< Code and Status. */
struct
{
uint32_t timeStamp : 16;
uint32_t dlc : 4;
uint32_t rtr : 1;
uint32_t ide : 1;
uint32_t srr : 1;
uint32_t reserved1 : 1;
uint32_t code : 4;
uint32_t reserved2 : 4;
};
};
union
{
uint32_t id; /*!< Message Buffer ID. */
struct
{
uint32_t idExt : 18;
uint32_t idStd : 11;
uint32_t prio : 3;
};
};
union
{
uint32_t word0; /*!< Bytes of the FlexCAN message. */
struct
{
uint8_t data3;
uint8_t data2;
uint8_t data1;
uint8_t data0;
};
};
union
{
uint32_t word1; /*!< Bytes of the FlexCAN message. */
struct
{
uint8_t data7;
uint8_t data6;
uint8_t data5;
uint8_t data4;
};
};
} flexcan_msgbuf_t;
/*! @brief FlexCAN timing-related structures. */
typedef struct _flexcan_timing
{
uint32_t preDiv; /*!< Clock pre divider. */
uint32_t rJumpwidth; /*!< Resync jump width. */
uint32_t phaseSeg1; /*!< Phase segment 1. */
uint32_t phaseSeg2; /*!< Phase segment 2. */
uint32_t propSeg; /*!< Propagation segment. */
} flexcan_timing_t;
/*! @brief FlexCAN module initialization structure. */
typedef struct _flexcan_init_config
{
flexcan_timing_t timing; /*!< Desired FlexCAN module timing configuration. */
uint32_t operatingMode; /*!< Desired FlexCAN module operating mode. */
uint8_t maxMsgBufNum; /*!< The maximal number of available message buffer. */
} flexcan_init_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name FlexCAN Initialization and Configuration functions
* @{
*/
/*!
* @brief Initialize FlexCAN module with given initialization structure.
*
* @param base CAN base pointer.
* @param initConfig CAN initialization structure (see @ref flexcan_init_config_t structure).
*/
void FLEXCAN_Init(CAN_Type* base, const flexcan_init_config_t* initConfig);
/*!
* @brief This function reset FlexCAN module register content to its default value.
*
* @param base FlexCAN base pointer.
*/
void FLEXCAN_Deinit(CAN_Type* base);
/*!
* @brief This function is used to Enable the FlexCAN Module.
*
* @param base FlexCAN base pointer.
*/
void FLEXCAN_Enable(CAN_Type* base);
/*!
* @brief This function is used to Disable the FlexCAN Module.
*
* @param base FlexCAN base pointer.
*/
void FLEXCAN_Disable(CAN_Type* base);
/*!
* @brief Sets the FlexCAN time segments for setting up bit rate.
*
* @param base FlexCAN base pointer.
* @param timing FlexCAN time segments, which need to be set for the bit rate (See @ref flexcan_timing_t structure).
*/
void FLEXCAN_SetTiming(CAN_Type* base, const flexcan_timing_t* timing);
/*!
* @brief Set operation mode.
*
* @param base FlexCAN base pointer.
* @param mode Set an operation mode.
*/
void FLEXCAN_SetOperatingMode(CAN_Type* base, uint8_t mode);
/*!
* @brief Set the maximum number of Message Buffers.
*
* @param base FlexCAN base pointer.
* @param bufNum Maximum number of message buffers.
*/
void FLEXCAN_SetMaxMsgBufNum(CAN_Type* base, uint32_t bufNum);
/*!
* @brief Get the working status of FlexCAN module.
*
* @param base FlexCAN base pointer.
* @return - true: FLEXCAN module is either in Normal Mode, Listen-Only Mode or Loop-Back Mode.
* - false: FLEXCAN module is either in Disable Mode, Stop Mode or Freeze Mode.
*/
static inline bool FLEXCAN_IsModuleReady(CAN_Type* base)
{
return !((CAN_MCR_REG(base) >> CAN_MCR_NOT_RDY_SHIFT) & 0x1);
}
/*!
* @brief Set the Transmit Abort feature enablement.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable Transmit Abort feature.
* - true: Enable Transmit Abort feature.
* - false: Disable Transmit Abort feature.
*/
void FLEXCAN_SetAbortCmd(CAN_Type* base, bool enable);
/*!
* @brief Set the local transmit priority enablement.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable local transmit periority.
* - true: Transmit MB with highest local priority.
* - false: Transmit MB with lowest MB number.
*/
void FLEXCAN_SetLocalPrioCmd(CAN_Type* base, bool enable);
/*!
* @brief Set the Rx matching process priority.
*
* @param base FlexCAN base pointer.
* @param priority Set Rx matching process priority.
* - true: Matching starts from Mailboxes and continues on Rx FIFO.
* - false: Matching starts from Rx FIFO and continues on Mailboxes.
*/
void FLEXCAN_SetMatchPrioCmd(CAN_Type* base, bool priority);
/*@}*/
/*!
* @name FlexCAN Message buffer control functions
* @{
*/
/*!
* @brief Get message buffer pointer for transition.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx message buffer index.
* @return message buffer pointer.
*/
flexcan_msgbuf_t* FLEXCAN_GetMsgBufPtr(CAN_Type* base, uint8_t msgBufIdx);
/*!
* @brief Locks the FlexCAN Rx message buffer.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx Index of the message buffer
* @return - true: Lock Rx Message Buffer successful.
* - false: Lock Rx Message Buffer failed.
*/
bool FLEXCAN_LockRxMsgBuf(CAN_Type* base, uint8_t msgBufIdx);
/*!
* @brief Unlocks the FlexCAN Rx message buffer.
*
* @param base FlexCAN base pointer.
* @return current free run timer counter value.
*/
uint16_t FLEXCAN_UnlockAllRxMsgBuf(CAN_Type* base);
/*@}*/
/*!
* @name FlexCAN Interrupts and flags management functions
* @{
*/
/*!
* @brief Enables/Disables the FlexCAN Message Buffer interrupt.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx Index of the message buffer.
* @param enable Enables/Disables interrupt.
* - true: Enable Message Buffer interrupt.
* - disable: Disable Message Buffer interrupt.
*/
void FLEXCAN_SetMsgBufIntCmd(CAN_Type* base, uint8_t msgBufIdx, bool enable);
/*!
* @brief Gets the individual FlexCAN MB interrupt flag.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx Index of the message buffer.
* @retval true: Message Buffer Interrupt is pending.
* @retval false: There is no Message Buffer Interrupt.
*/
bool FLEXCAN_GetMsgBufStatusFlag(CAN_Type* base, uint8_t msgBufIdx);
/*!
* @brief Clears the interrupt flag of the message buffers.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx Index of the message buffer.
*/
void FLEXCAN_ClearMsgBufStatusFlag(CAN_Type* base, uint32_t msgBufIdx);
/*!
* @brief Enables error interrupt of the FlexCAN module.
*
* @param base FlexCAN base pointer.
* @param errorSrc The interrupt source (see @ref _flexcan_interrutpt enumeration).
* @param enable Choose enable or disable.
*/
void FLEXCAN_SetErrIntCmd(CAN_Type* base, uint32_t errorSrc, bool enable);
/*!
* @brief Gets the FlexCAN module interrupt flag.
*
* @param base FlexCAN base pointer.
* @param errFlags FlexCAN error flags (see @ref _flexcan_status_flag enumeration).
* @return The individual Message Buffer interrupt flag (0 and 1 are the flag value)
*/
uint32_t FLEXCAN_GetErrStatusFlag(CAN_Type* base, uint32_t errFlags);
/*!
* @brief Clears the interrupt flag of the FlexCAN module.
*
* @param base FlexCAN base pointer.
* @param errFlags The value to be written to the interrupt flag1 register (see @ref _flexcan_status_flag enumeration).
*/
void FLEXCAN_ClearErrStatusFlag(CAN_Type* base, uint32_t errFlags);
/*!
* @brief Get the error counter of FlexCAN module.
*
* @param base FlexCAN base pointer.
* @param txError Tx_Err_Counter pointer.
* @param rxError Rx_Err_Counter pointer.
*/
void FLEXCAN_GetErrCounter(CAN_Type* base, uint8_t* txError, uint8_t* rxError);
/*@}*/
/*!
* @name Rx FIFO management functions
* @{
*/
/*!
* @brief Enables the Rx FIFO.
*
* @param base FlexCAN base pointer.
* @param numOfFilters The number of Rx FIFO filters
*/
void FLEXCAN_EnableRxFifo(CAN_Type* base, uint8_t numOfFilters);
/*!
* @brief Disables the Rx FIFO.
*
* @param base FlexCAN base pointer.
*/
void FLEXCAN_DisableRxFifo(CAN_Type* base);
/*!
* @brief Set the number of the Rx FIFO filters.
*
* @param base FlexCAN base pointer.
* @param numOfFilters The number of Rx FIFO filters.
*/
void FLEXCAN_SetRxFifoFilterNum(CAN_Type* base, uint32_t numOfFilters);
/*!
* @brief Set the FlexCAN Rx FIFO fields.
*
* @param base FlexCAN base pointer.
* @param idFormat The format of the Rx FIFO ID Filter Table Elements
* @param idFilterTable The ID filter table elements which contain RTR bit, IDE bit and RX message ID.
*/
void FLEXCAN_SetRxFifoFilter(CAN_Type* base, uint32_t idFormat, flexcan_id_table_t *idFilterTable);
/*!
* @brief Gets the FlexCAN Rx FIFO data pointer.
*
* @param base FlexCAN base pointer.
* @return Rx FIFO data pointer.
*/
flexcan_msgbuf_t* FLEXCAN_GetRxFifoPtr(CAN_Type* base);
/*!
* @brief Gets the FlexCAN Rx FIFO information.
* The return value indicates which Identifier Acceptance Filter
* (see Rx FIFO Structure) was hit by the received message.
* @param base FlexCAN base pointer.
* @return Rx FIFO filter number.
*/
uint16_t FLEXCAN_GetRxFifoInfo(CAN_Type* base);
/*@}*/
/*!
* @name Rx Mask Setting functions
* @{
*/
/*!
* @brief Set the Rx masking mode.
*
* @param base FlexCAN base pointer.
* @param mode The FlexCAN Rx mask mode (see @ref _flexcan_rx_mask_mode enumeration).
*/
void FLEXCAN_SetRxMaskMode(CAN_Type* base, uint32_t mode);
/*!
* @brief Set the remote trasmit request mask enablement.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable remote trasmit request mask.
* - true: Enable RTR matching judgement.
* - false: Disable RTR matching judgement.
*/
void FLEXCAN_SetRxMaskRtrCmd(CAN_Type* base, bool enable);
/*!
* @brief Set the FlexCAN RX global mask.
*
* @param base FlexCAN base pointer.
* @param mask Rx Global mask.
*/
void FLEXCAN_SetRxGlobalMask(CAN_Type* base, uint32_t mask);
/*!
* @brief Set the FlexCAN Rx individual mask for ID filtering in the Rx MBs and the Rx FIFO.
*
* @param base FlexCAN base pointer.
* @param msgBufIdx Index of the message buffer.
* @param mask Individual mask
*/
void FLEXCAN_SetRxIndividualMask(CAN_Type* base, uint32_t msgBufIdx, uint32_t mask);
/*!
* @brief Set the FlexCAN RX Message Buffer BUF14 mask.
*
* @param base FlexCAN base pointer.
* @param mask Message Buffer BUF14 mask.
*/
void FLEXCAN_SetRxMsgBuff14Mask(CAN_Type* base, uint32_t mask);
/*!
* @brief Set the FlexCAN RX Message Buffer BUF15 mask.
*
* @param base FlexCAN base pointer.
* @param mask Message Buffer BUF15 mask.
*/
void FLEXCAN_SetRxMsgBuff15Mask(CAN_Type* base, uint32_t mask);
/*!
* @brief Set the FlexCAN RX Fifo global mask.
*
* @param base FlexCAN base pointer.
* @param mask Rx Fifo Global mask.
*/
void FLEXCAN_SetRxFifoGlobalMask(CAN_Type* base, uint32_t mask);
/*@}*/
/*!
* @name Misc. Functions
* @{
*/
/*!
* @brief Enable/disable the FlexCAN self wakeup feature.
*
* @param base FlexCAN base pointer.
* @param lpfEnable The low pass filter for Rx self wakeup feature enablement.
* @param enable The self wakeup feature enablement.
*/
void FLEXCAN_SetSelfWakeUpCmd(CAN_Type* base, bool lpfEnable, bool enable);
/*!
* @brief Enable/Disable the FlexCAN self reception feature.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable self reception feature.
* - true: Enable self reception feature.
* - false: Disable self reception feature.
*/
void FLEXCAN_SetSelfReceptionCmd(CAN_Type* base, bool enable);
/*!
* @brief Enable/disable the enhance FlexCAN Rx vote.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable FlexCAN Rx vote mechanism
* - true: Three samples are used to determine the value of the received bit.
* - false: Just one sample is used to determine the bit value.
*/
void FLEXCAN_SetRxVoteCmd(CAN_Type* base, bool enable);
/*!
* @brief Enable/disable the Auto Busoff recover feature.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable Auto Busoff Recover
* - true: Enable Auto Bus Off recover feature.
* - false: Disable Auto Bus Off recover feature.
*/
void FLEXCAN_SetAutoBusOffRecoverCmd(CAN_Type* base, bool enable);
/*!
* @brief Enable/disable the Time Sync feature.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable the Time Sync
* - true: Enable Time Sync feature.
* - false: Disable Time Sync feature.
*/
void FLEXCAN_SetTimeSyncCmd(CAN_Type* base, bool enable);
/*!
* @brief Enable/disable the Auto Remote Response feature.
*
* @param base FlexCAN base pointer.
* @param enable Enable/Disable the Auto Remote Response feature
* - true: Enable Auto Remote Response feature.
* - false: Disable Auto Remote Response feature.
*/
void FLEXCAN_SetAutoRemoteResponseCmd(CAN_Type* base, bool enable);
/*!
* @brief Enable/disable the Glitch Filter Width when FLEXCAN enters the STOP mode.
*
* @param base FlexCAN base pointer.
* @param filterWidth The Glitch Filter Width.
*/
static inline void FLEXCAN_SetGlitchFilterWidth(CAN_Type* base, uint8_t filterWidth)
{
CAN_GFWR_REG(base) = filterWidth;
}
/*!
* @brief Get the lowest inactive message buffer number.
*
* @param base FlexCAN base pointer.
* @return bit 22-16 : The lowest number inactive Mailbox.
* bit 14 : Indicates whether the number content is valid or not.
* bit 13 : This bit indicates whether there is any inactive Mailbox.
*/
static inline uint32_t FLEXCAN_GetLowestInactiveMsgBuf(CAN_Type* base)
{
return CAN_ESR2_REG(base);
}
/*!
* @brief Set the Tx Arbitration Start Delay number.
* This function is used to optimize the transmit performance.
* For more information about to set this value, see the Chip Reference Manual.
*
* @param base FlexCAN base pointer.
* @param tasd The lowest number inactive Mailbox.
*/
static inline void FLEXCAN_SetTxArbitrationStartDelay(CAN_Type* base, uint8_t tasd)
{
assert(tasd < 32);
CAN_CTRL2_REG(base) = (CAN_CTRL2_REG(base) & ~CAN_CTRL2_TASD_MASK) | CAN_CTRL2_TASD(tasd);
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#if defined(__ARMCC_VERSION)
#pragma pop
#elif defined(__GNUC__)
/* leave anonymous unions enabled */
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma language=default
#else
#error Not supported compiler type
#endif
#endif /* __FLEXCAN_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,162 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gpio_imx.h"
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* GPIO Initialization and Configuration functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : GPIO_Init
* Description : Initializes the GPIO module according to the specified
* parameters in the initConfig.
*
*END**************************************************************************/
void GPIO_Init(GPIO_Type* base, const gpio_init_config_t* initConfig)
{
uint32_t pin;
volatile uint32_t *icr;
/* Register reset to default value */
GPIO_IMR_REG(base) = 0;
GPIO_EDGE_SEL_REG(base) = 0;
/* Get pin number */
pin = initConfig->pin;
/* Configure GPIO pin direction */
if (initConfig->direction == gpioDigitalOutput)
GPIO_GDIR_REG(base) |= (1U << pin);
else
GPIO_GDIR_REG(base) &= ~(1U << pin);
/* Configure GPIO pin interrupt mode */
if(pin < 16)
icr = &GPIO_ICR1_REG(base);
else
{
icr = &GPIO_ICR2_REG(base);
pin -= 16;
}
switch(initConfig->interruptMode)
{
case(gpioIntLowLevel):
{
*icr &= ~(0x3<<(2*pin));
break;
}
case(gpioIntHighLevel):
{
*icr = (*icr & (~(0x3<<(2*pin)))) | (0x1<<(2*pin));
break;
}
case(gpioIntRisingEdge):
{
*icr = (*icr & (~(0x3<<(2*pin)))) | (0x2<<(2*pin));
break;
}
case(gpioIntFallingEdge):
{
*icr |= (0x3<<(2*pin));
break;
}
case(gpioNoIntmode):
{
break;
}
}
}
/*******************************************************************************
* GPIO Read and Write Functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : GPIO_WritePinOutput
* Description : Sets the output level of the individual GPIO pin.
*
*END**************************************************************************/
void GPIO_WritePinOutput(GPIO_Type* base, uint32_t pin, gpio_pin_action_t pinVal)
{
assert(pin < 32);
if (pinVal == gpioPinSet)
{
GPIO_DR_REG(base) |= (1U << pin); /* Set pin output to high level.*/
}
else
{
GPIO_DR_REG(base) &= ~(1U << pin); /* Set pin output to low level.*/
}
}
/*******************************************************************************
* Interrupts and flags management functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : GPIO_SetPinIntMode
* Description : Enable or Disable the specific pin interrupt.
*
*END**************************************************************************/
void GPIO_SetPinIntMode(GPIO_Type* base, uint32_t pin, bool enable)
{
assert(pin < 32);
if(enable)
GPIO_IMR_REG(base) |= (1U << pin);
else
GPIO_IMR_REG(base) &= ~(1U << pin);
}
/*FUNCTION**********************************************************************
*
* Function Name : GPIO_SetIntEdgeSelect
* Description : Enable or Disable the specific pin interrupt.
*
*END**************************************************************************/
void GPIO_SetIntEdgeSelect(GPIO_Type* base, uint32_t pin, bool enable)
{
assert(pin < 32);
if(enable)
GPIO_EDGE_SEL_REG(base) |= (1U << pin);
else
GPIO_EDGE_SEL_REG(base) &= ~(1U << pin);
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,272 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GPIO_IMX_H__
#define __GPIO_IMX_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup gpio_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief GPIO direction definition. */
typedef enum _gpio_pin_direction
{
gpioDigitalInput = 0U, /*!< Set current pin as digital input.*/
gpioDigitalOutput = 1U, /*!< Set current pin as digital output.*/
} gpio_pin_direction_t;
/*! @brief GPIO interrupt mode definition. */
typedef enum _gpio_interrupt_mode
{
gpioIntLowLevel = 0U, /*!< Set current pin interrupt is low-level sensitive.*/
gpioIntHighLevel = 1U, /*!< Set current pin interrupt is high-level sensitive.*/
gpioIntRisingEdge = 2U, /*!< Set current pin interrupt is rising-edge sensitive.*/
gpioIntFallingEdge = 3U, /*!< Set current pin interrupt is falling-edge sensitive.*/
gpioNoIntmode = 4U, /*!< Set current pin general IO functionality. */
} gpio_interrupt_mode_t;
/*! @brief GPIO pin(bit) value definition. */
typedef enum _gpio_pin_action
{
gpioPinClear = 0U, /*!< Clear GPIO Pin.*/
gpioPinSet = 1U, /*!< Set GPIO Pin.*/
} gpio_pin_action_t;
/*! @brief GPIO Init structure definition. */
typedef struct _gpio_init_config
{
uint32_t pin; /*!< Specifies the pin number. */
gpio_pin_direction_t direction; /*!< Specifies the pin direction. */
gpio_interrupt_mode_t interruptMode; /*!< Specifies the pin interrupt mode, a value of @ref gpio_interrupt_mode_t. */
} gpio_init_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name GPIO Initialization and Configuration functions
* @{
*/
/*!
* @brief Initializes the GPIO peripheral according to the specified
* parameters in the initConfig.
*
* @param base GPIO base pointer.
* @param initConfig pointer to a @ref gpio_init_config_t structure that
* contains the configuration information.
*/
void GPIO_Init(GPIO_Type* base, const gpio_init_config_t* initConfig);
/*@}*/
/*!
* @name GPIO Read and Write Functions
* @{
*/
/*!
* @brief Reads the current input value of the pin when pin's direction is configured as input.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @return GPIO pin input value.
*/
static inline uint8_t GPIO_ReadPinInput(GPIO_Type* base, uint32_t pin)
{
assert(pin < 32);
return (uint8_t)((GPIO_DR_REG(base) >> pin) & 1U);
}
/*!
* @brief Reads the current input value of a specific GPIO port when port's direction are all configured as input.
* This function gets all 32-pin input as a 32-bit integer.
*
* @param base GPIO base pointer.
* @return GPIO port input data.
*/
static inline uint32_t GPIO_ReadPortInput(GPIO_Type* base)
{
return GPIO_DR_REG(base);
}
/*!
* @brief Reads the current pin output.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @return Current pin output value.
*/
static inline uint8_t GPIO_ReadPinOutput(GPIO_Type* base, uint32_t pin)
{
assert(pin < 32);
return (uint8_t)((GPIO_DR_REG(base) >> pin) & 0x1U);
}
/*!
* @brief Reads out all pin output status of the current port.
* This function operates all 32 port pins.
*
* @param base GPIO base pointer.
* @return Current port output status.
*/
static inline uint32_t GPIO_ReadPortOutput(GPIO_Type* base)
{
return GPIO_DR_REG(base);
}
/*!
* @brief Sets the output level of the individual GPIO pin to logic 1 or 0.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @param pinVal pin output value (See @ref gpio_pin_action_t structure).
*/
void GPIO_WritePinOutput(GPIO_Type* base, uint32_t pin, gpio_pin_action_t pinVal);
/*!
* @brief Sets the output of the GPIO port pins to a specific logic value.
* This function operates all 32 port pins.
*
* @param base GPIO base pointer.
* @param portVal data to configure the GPIO output.
*/
static inline void GPIO_WritePortOutput(GPIO_Type* base, uint32_t portVal)
{
GPIO_DR_REG(base) = portVal;
}
/*@}*/
/*!
* @name GPIO Read Pad Status Functions
* @{
*/
/*!
* @brief Reads the current GPIO pin pad status.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @return GPIO pin pad status value.
*/
static inline uint8_t GPIO_ReadPadStatus(GPIO_Type* base, uint32_t pin)
{
assert(pin < 32);
return (uint8_t)((GPIO_PSR_REG(base) >> pin) & 1U);
}
/*@}*/
/*!
* @name Interrupts and flags management functions
* @{
*/
/*!
* @brief Enable or Disable the specific pin interrupt.
*
* @param base GPIO base pointer.
* @param pin GPIO pin number.
* @param enable Enable or disable interrupt.
* - true: Enable GPIO interrupt.
* - false: Disable GPIO interrupt.
*/
void GPIO_SetPinIntMode(GPIO_Type* base, uint32_t pin, bool enable);
/*!
* @brief Check individual pin interrupt status.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @return current pin interrupt status flag.
*/
static inline bool GPIO_IsIntPending(GPIO_Type* base, uint32_t pin)
{
assert(pin < 32);
return (bool)((GPIO_ISR_REG(base) >> pin) & 1U);
}
/*!
* @brief Clear pin interrupt flag. Status flags are cleared by
* writing a 1 to the corresponding bit position.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
*/
static inline void GPIO_ClearStatusFlag(GPIO_Type* base, uint32_t pin)
{
assert(pin < 32);
GPIO_ISR_REG(base) = (1U << pin);
}
/*!
* @brief Enable or disable the edge select bit to override
* the ICR register's configuration.
*
* @param base GPIO base pointer.
* @param pin GPIO port pin number.
* @param enable Enable or disable edge select bit.
*/
void GPIO_SetIntEdgeSelect(GPIO_Type* base, uint32_t pin, bool enable);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __GPIO_IMX_H__*/
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "gpt.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : GPT_Init
* Description : Initialize GPT to reset state and initialize running mode
*
*END**************************************************************************/
void GPT_Init(GPT_Type* base, const gpt_init_config_t* initConfig)
{
assert(initConfig);
base->CR = 0;
GPT_SoftReset(base);
base->CR = (initConfig->freeRun ? GPT_CR_FRR_MASK : 0) |
(initConfig->waitEnable ? GPT_CR_WAITEN_MASK : 0) |
(initConfig->stopEnable ? GPT_CR_STOPEN_MASK : 0) |
(initConfig->dozeEnable ? GPT_CR_DOZEEN_MASK : 0) |
(initConfig->dbgEnable ? GPT_CR_DBGEN_MASK : 0) |
(initConfig->enableMode ? GPT_CR_ENMOD_MASK : 0);
}
/*FUNCTION**********************************************************************
*
* Function Name : GPT_SetClockSource
* Description : Set clock source of GPT
*
*END**************************************************************************/
void GPT_SetClockSource(GPT_Type* base, uint32_t source)
{
assert(source <= gptClockSourceOsc);
if (source == gptClockSourceOsc)
base->CR = (base->CR & ~GPT_CR_CLKSRC_MASK) | GPT_CR_EN_24M_MASK | GPT_CR_CLKSRC(source);
else
base->CR = (base->CR & ~(GPT_CR_CLKSRC_MASK | GPT_CR_EN_24M_MASK)) | GPT_CR_CLKSRC(source);
}
/*FUNCTION**********************************************************************
*
* Function Name : GPT_SetIntCmd
* Description : Enable or disable GPT interrupts
*
*END**************************************************************************/
void GPT_SetIntCmd(GPT_Type* base, uint32_t flags, bool enable)
{
if (enable)
base->IR |= flags;
else
base->IR &= ~flags;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,414 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __GPT_H__
#define __GPT_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup gpt_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Clock source. */
enum _gpt_clock_source
{
gptClockSourceNone = 0U, /*!< No source selected.*/
gptClockSourcePeriph = 1U, /*!< Use peripheral module clock.*/
gptClockSourceLowFreq = 4U, /*!< Use 32 K clock.*/
gptClockSourceOsc = 5U, /*!< Use 24 M OSC clock.*/
};
/*! @brief Input capture channel number. */
enum _gpt_input_capture_channel
{
gptInputCaptureChannel1 = 0U, /*!< Input Capture Channel1.*/
gptInputCaptureChannel2 = 1U, /*!< Input Capture Channel2.*/
};
/*! @brief Input capture operation mode. */
enum _gpt_input_operation_mode
{
gptInputOperationDisabled = 0U, /*!< Don't capture.*/
gptInputOperationRiseEdge = 1U, /*!< Capture on rising edge of input pin.*/
gptInputOperationFallEdge = 2U, /*!< Capture on falling edge of input pin.*/
gptInputOperationBothEdge = 3U, /*!< Capture on both edges of input pin.*/
};
/*! @brief Output compare channel number. */
enum _gpt_output_compare_channel
{
gptOutputCompareChannel1 = 0U, /*!< Output Compare Channel1.*/
gptOutputCompareChannel2 = 1U, /*!< Output Compare Channel2.*/
gptOutputCompareChannel3 = 2U, /*!< Output Compare Channel3.*/
};
/*! @brief Output compare operation mode. */
enum _gpt_output_operation_mode
{
gptOutputOperationDisconnected = 0U, /*!< Don't change output pin.*/
gptOutputOperationToggle = 1U, /*!< Toggle output pin.*/
gptOutputOperationClear = 2U, /*!< Set output pin low.*/
gptOutputOperationSet = 3U, /*!< Set output pin high.*/
gptOutputOperationActivelow = 4U, /*!< Generate a active low pulse on output pin.*/
};
/*! @brief Status flag. */
enum _gpt_status_flag
{
gptStatusFlagOutputCompare1 = 1U << 0, /*!< Output compare channel 1 event.*/
gptStatusFlagOutputCompare2 = 1U << 1, /*!< Output compare channel 2 event.*/
gptStatusFlagOutputCompare3 = 1U << 2, /*!< Output compare channel 3 event.*/
gptStatusFlagInputCapture1 = 1U << 3, /*!< Capture channel 1 event.*/
gptStatusFlagInputCapture2 = 1U << 4, /*!< Capture channel 2 event.*/
gptStatusFlagRollOver = 1U << 5, /*!< Counter reaches maximum value and rolled over to 0 event.*/
};
/*! @brief Structure to configure the running mode. */
typedef struct _gpt_init_config
{
bool freeRun; /*!< true: FreeRun mode, false: Restart mode. */
bool waitEnable; /*!< GPT enabled in wait mode. */
bool stopEnable; /*!< GPT enabled in stop mode. */
bool dozeEnable; /*!< GPT enabled in doze mode. */
bool dbgEnable; /*!< GPT enabled in debug mode. */
bool enableMode; /*!< true: counter reset to 0 when enabled, false: counter retain its value when enabled. */
} gpt_init_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name GPT State Control
* @{
*/
/*!
* @brief Initialize GPT to reset state and initialize running mode.
*
* @param base GPT base pointer.
* @param initConfig GPT mode setting configuration.
*/
void GPT_Init(GPT_Type* base, const gpt_init_config_t* initConfig);
/*!
* @brief Software reset of GPT module.
*
* @param base GPT base pointer.
*/
static inline void GPT_SoftReset(GPT_Type* base)
{
base->CR |= GPT_CR_SWR_MASK;
/* Wait reset finished. */
while (base->CR & GPT_CR_SWR_MASK) {};
}
/*!
* @brief Set clock source of GPT.
*
* @param base GPT base pointer.
* @param source Clock source (see @ref _gpt_clock_source enumeration).
*/
void GPT_SetClockSource(GPT_Type* base, uint32_t source);
/*!
* @brief Get clock source of GPT.
*
* @param base GPT base pointer.
* @return clock source (see @ref _gpt_clock_source enumeration).
*/
static inline uint32_t GPT_GetClockSource(GPT_Type* base)
{
return (base->CR & GPT_CR_CLKSRC_MASK) >> GPT_CR_CLKSRC_SHIFT;
}
/*!
* @brief Set pre scaler of GPT.
*
* @param base GPT base pointer.
* @param prescaler Pre-scaler of GPT (0-4095, divider = prescaler + 1).
*/
static inline void GPT_SetPrescaler(GPT_Type* base, uint32_t prescaler)
{
assert(prescaler <= GPT_PR_PRESCALER_MASK);
base->PR = (base->PR & ~GPT_PR_PRESCALER_MASK) | GPT_PR_PRESCALER(prescaler);
}
/*!
* @brief Get pre scaler of GPT.
*
* @param base GPT base pointer.
* @return pre scaler of GPT (0-4095).
*/
static inline uint32_t GPT_GetPrescaler(GPT_Type* base)
{
return (base->PR & GPT_PR_PRESCALER_MASK) >> GPT_PR_PRESCALER_SHIFT;
}
/*!
* @brief OSC 24M pre-scaler before selected by clock source.
*
* @param base GPT base pointer.
* @param prescaler OSC pre-scaler(0-15, divider = prescaler + 1).
*/
static inline void GPT_SetOscPrescaler(GPT_Type* base, uint32_t prescaler)
{
assert(prescaler <= (GPT_PR_PRESCALER24M_MASK >> GPT_PR_PRESCALER24M_SHIFT));
base->PR = (base->PR & ~GPT_PR_PRESCALER24M_MASK) | GPT_PR_PRESCALER24M(prescaler);
}
/*!
* @brief Get pre-scaler of GPT.
*
* @param base GPT base pointer.
* @return OSC pre scaler of GPT (0-15).
*/
static inline uint32_t GPT_GetOscPrescaler(GPT_Type* base)
{
return (base->PR & GPT_PR_PRESCALER24M_MASK) >> GPT_PR_PRESCALER24M_SHIFT;
}
/*!
* @brief Enable GPT module.
*
* @param base GPT base pointer.
*/
static inline void GPT_Enable(GPT_Type* base)
{
base->CR |= GPT_CR_EN_MASK;
}
/*!
* @brief Disable GPT module.
*
* @param base GPT base pointer.
*/
static inline void GPT_Disable(GPT_Type* base)
{
base->CR &= ~GPT_CR_EN_MASK;
}
/*!
* @brief Get GPT counter value.
*
* @param base GPT base pointer.
* @return GPT counter value.
*/
static inline uint32_t GPT_ReadCounter(GPT_Type* base)
{
return base->CNT;
}
/*@}*/
/*!
* @name GPT Input/Output Signal Control
* @{
*/
/*!
* @brief Set GPT operation mode of input capture channel.
*
* @param base GPT base pointer.
* @param channel GPT capture channel (see @ref _gpt_input_capture_channel enumeration).
* @param mode GPT input capture operation mode (see @ref _gpt_input_operation_mode enumeration).
*/
static inline void GPT_SetInputOperationMode(GPT_Type* base, uint32_t channel, uint32_t mode)
{
assert (channel <= gptInputCaptureChannel2);
base->CR = (base->CR & ~(GPT_CR_IM1_MASK << (channel * 2))) | (GPT_CR_IM1(mode) << (channel * 2));
}
/*!
* @brief Get GPT operation mode of input capture channel.
*
* @param base GPT base pointer.
* @param channel GPT capture channel (see @ref _gpt_input_capture_channel enumeration).
* @return GPT input capture operation mode (see @ref _gpt_input_operation_mode enumeration).
*/
static inline uint32_t GPT_GetInputOperationMode(GPT_Type* base, uint32_t channel)
{
assert (channel <= gptInputCaptureChannel2);
return (base->CR >> (GPT_CR_IM1_SHIFT + channel * 2)) & (GPT_CR_IM1_MASK >> GPT_CR_IM1_SHIFT);
}
/*!
* @brief Get GPT input capture value of certain channel.
*
* @param base GPT base pointer.
* @param channel GPT capture channel (see @ref _gpt_input_capture_channel enumeration).
* @return GPT input capture value.
*/
static inline uint32_t GPT_GetInputCaptureValue(GPT_Type* base, uint32_t channel)
{
assert (channel <= gptInputCaptureChannel2);
return *(&base->ICR1 + channel);
}
/*!
* @brief Set GPT operation mode of output compare channel.
*
* @param base GPT base pointer.
* @param channel GPT output compare channel (see @ref _gpt_output_compare_channel enumeration).
* @param mode GPT output operation mode (see @ref _gpt_output_operation_mode enumeration).
*/
static inline void GPT_SetOutputOperationMode(GPT_Type* base, uint32_t channel, uint32_t mode)
{
assert (channel <= gptOutputCompareChannel3);
base->CR = (base->CR & ~(GPT_CR_OM1_MASK << (channel * 3))) | (GPT_CR_OM1(mode) << (channel * 3));
}
/*!
* @brief Get GPT operation mode of output compare channel.
*
* @param base GPT base pointer.
* @param channel GPT output compare channel (see @ref _gpt_output_compare_channel enumeration).
* @return GPT output operation mode (see @ref _gpt_output_operation_mode enumeration).
*/
static inline uint32_t GPT_GetOutputOperationMode(GPT_Type* base, uint32_t channel)
{
assert (channel <= gptOutputCompareChannel3);
return (base->CR >> (GPT_CR_OM1_SHIFT + channel * 3)) & (GPT_CR_OM1_MASK >> GPT_CR_OM1_SHIFT);
}
/*!
* @brief Set GPT output compare value of output compare channel.
*
* @param base GPT base pointer.
* @param channel GPT output compare channel (see @ref _gpt_output_compare_channel enumeration).
* @param value GPT output compare value.
*/
static inline void GPT_SetOutputCompareValue(GPT_Type* base, uint32_t channel, uint32_t value)
{
assert (channel <= gptOutputCompareChannel3);
*(&base->OCR1 + channel) = value;
}
/*!
* @brief Get GPT output compare value of output compare channel.
*
* @param base GPT base pointer.
* @param channel GPT output compare channel (see @ref _gpt_output_compare_channel enumeration).
* @return GPT output compare value.
*/
static inline uint32_t GPT_GetOutputCompareValue(GPT_Type* base, uint32_t channel)
{
assert (channel <= gptOutputCompareChannel3);
return *(&base->OCR1 + channel);
}
/*!
* @brief Force GPT output action on output compare channel, ignoring comparator.
*
* @param base GPT base pointer.
* @param channel GPT output compare channel (see @ref _gpt_output_compare_channel enumeration).
*/
static inline void GPT_ForceOutput(GPT_Type* base, uint32_t channel)
{
assert (channel <= gptOutputCompareChannel3);
base->CR |= (GPT_CR_FO1_MASK << channel);
}
/*@}*/
/*!
* @name GPT Interrupt and Status Control
* @{
*/
/*!
* @brief Get GPT status flag.
*
* @param base GPT base pointer.
* @param flags GPT status flag mask (see @ref _gpt_status_flag for bit definition).
* @return GPT status, each bit represents one status flag.
*/
static inline uint32_t GPT_GetStatusFlag(GPT_Type* base, uint32_t flags)
{
return base->SR & flags;
}
/*!
* @brief Clear one or more GPT status flag.
*
* @param base GPT base pointer.
* @param flags GPT status flag mask (see @ref _gpt_status_flag for bit definition).
*/
static inline void GPT_ClearStatusFlag(GPT_Type* base, uint32_t flags)
{
base->SR = flags;
}
/*!
* @brief Enable or Disable GPT interrupts.
*
* @param base GPT base pointer.
* @param flags GPT status flag mask (see @ref _gpt_status_flag for bit definition).
* @param enable Enable/Disable GPT interrupts.
* -true: Enable GPT interrupts.
* -false: Disable GPT interrupts.
*/
void GPT_SetIntCmd(GPT_Type* base, uint32_t flags, bool enable);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __GPT_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "i2c_imx.h"
/*******************************************************************************
* Constant
******************************************************************************/
static const uint32_t i2cClkDivTab[][2] =
{
{22, 0x20}, {24, 0x21}, {26, 0x22}, {28, 0x23}, {30, 0x00}, {32, 0x24}, {36, 0x25}, {40, 0x26},
{42, 0x03}, {44, 0x27}, {48, 0x28}, {52, 0x05}, {56, 0x29}, {60, 0x06}, {64, 0x2A}, {72, 0x2B},
{80, 0x2C}, {88, 0x09}, {96, 0x2D}, {104, 0x0A}, {112, 0x2E}, {128, 0x2F}, {144, 0x0C}, {160, 0x30},
{192, 0x31}, {224, 0x32}, {240, 0x0F}, {256, 0x33}, {288, 0x10}, {320, 0x34}, {384, 0x35}, {448, 0x36},
{480, 0x13}, {512, 0x37}, {576, 0x14}, {640, 0x38}, {768, 0x39}, {896, 0x3A}, {960, 0x17}, {1024, 0x3B},
{1152, 0x18}, {1280, 0x3C}, {1536, 0x3D}, {1792, 0x3E}, {1920, 0x1B}, {2048, 0x3F}, {2304, 0x1C}, {2560, 0x1D},
{3072, 0x1E}, {3840, 0x1F}
};
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* I2C Initialization and Configuration functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : I2C_Init
* Description : Initialize I2C module with given initialize structure.
*
*END**************************************************************************/
void I2C_Init(I2C_Type* base, const i2c_init_config_t* initConfig)
{
assert(initConfig);
/* Disable I2C Module. */
I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK;
/* Reset I2C register to its default value. */
I2C_Deinit(base);
/* Set I2C Module own Slave Address. */
I2C_SetSlaveAddress(base, initConfig->slaveAddress);
/* Set I2C BaudRate according to i2c initialize struct. */
I2C_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate);
}
/*FUNCTION**********************************************************************
*
* Function Name : I2C_Deinit
* Description : This function reset I2C module register content to
* its default value.
*
*END**************************************************************************/
void I2C_Deinit(I2C_Type* base)
{
/* Disable I2C Module */
I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK;
/* Reset I2C Module Register content to default value */
I2C_IADR_REG(base) = 0x0;
I2C_IFDR_REG(base) = 0x0;
I2C_I2CR_REG(base) = 0x0;
}
/*FUNCTION**********************************************************************
*
* Function Name : I2C_SetBaudRate
* Description : This function is used to set the baud rate of I2C Module.
*
*END**************************************************************************/
void I2C_SetBaudRate(I2C_Type* base, uint32_t clockRate, uint32_t baudRate)
{
uint32_t clockDiv;
uint8_t clkDivIndex = 0;
assert(baudRate <= 400000);
/* Calculate accurate baudRate divider. */
clockDiv = clockRate / baudRate;
if (clockDiv < i2cClkDivTab[0][0])
{
/* If clock divider is too small, using smallest legal divider */
clkDivIndex = 0;
}
else if (clockDiv > i2cClkDivTab[sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1][0])
{
/* If clock divider is too large, using largest legal divider */
clkDivIndex = sizeof(i2cClkDivTab)/sizeof(i2cClkDivTab[0]) - 1;
}
else
{
while (i2cClkDivTab[clkDivIndex][0] < clockDiv)
clkDivIndex++;
}
I2C_IFDR_REG(base) = i2cClkDivTab[clkDivIndex][1];
}
/*******************************************************************************
* I2C Bus Control functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : I2C_SetAckBit
* Description : This function is used to set the Transmit Acknowledge
* action when receive data from other device.
*
*END**************************************************************************/
void I2C_SetAckBit(I2C_Type* base, bool ack)
{
if (ack)
I2C_I2CR_REG(base) &= ~I2C_I2CR_TXAK_MASK;
else
I2C_I2CR_REG(base) |= I2C_I2CR_TXAK_MASK;
}
/*******************************************************************************
* Interrupts and flags management functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : I2C_SetIntCmd
* Description : Enables or disables I2C interrupt requests.
*
*END**************************************************************************/
void I2C_SetIntCmd(I2C_Type* base, bool enable)
{
if (enable)
I2C_I2CR_REG(base) |= I2C_I2CR_IIEN_MASK;
else
I2C_I2CR_REG(base) &= ~I2C_I2CR_IIEN_MASK;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,284 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __I2C_IMX_H__
#define __I2C_IMX_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup i2c_imx_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief I2C module initialization structure. */
typedef struct _i2c_init_config
{
uint32_t clockRate; /*!< Current I2C module clock freq. */
uint32_t baudRate; /*!< Desired I2C baud rate. */
uint8_t slaveAddress; /*!< I2C module's own address when addressed as slave device. */
} i2c_init_config_t;
/*! @brief Flag for I2C interrupt status check or polling status. */
enum _i2c_status_flag
{
i2cStatusTransferComplete = I2C_I2SR_ICF_MASK, /*!< Data Transfer complete flag. */
i2cStatusAddressedAsSlave = I2C_I2SR_IAAS_MASK, /*!< Addressed as a slave flag. */
i2cStatusBusBusy = I2C_I2SR_IBB_MASK, /*!< Bus is busy flag. */
i2cStatusArbitrationLost = I2C_I2SR_IAL_MASK, /*!< Arbitration is lost flag. */
i2cStatusSlaveReadWrite = I2C_I2SR_SRW_MASK, /*!< Master reading from slave flag(De-assert if master writing to slave). */
i2cStatusInterrupt = I2C_I2SR_IIF_MASK, /*!< An interrupt is pending flag. */
i2cStatusReceivedAck = I2C_I2SR_RXAK_MASK, /*!< No acknowledge detected flag. */
};
/*! @brief I2C Bus role of this module. */
enum _i2c_work_mode
{
i2cModeSlave = 0x0, /*!< This module works as I2C Slave. */
i2cModeMaster = I2C_I2CR_MSTA_MASK, /*!< This module works as I2C Master. */
};
/*! @brief Data transfer direction. */
enum _i2c_direction_mode
{
i2cDirectionReceive = 0x0, /*!< This module works at receive mode. */
i2cDirectionTransmit = I2C_I2CR_MTX_MASK, /*!< This module works at transmit mode. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name I2C Initialization and Configuration functions
* @{
*/
/*!
* @brief Initialize I2C module with given initialization structure.
*
* @param base I2C base pointer.
* @param initConfig I2C initialization structure (see @ref i2c_init_config_t).
*/
void I2C_Init(I2C_Type* base, const i2c_init_config_t* initConfig);
/*!
* @brief This function reset I2C module register content to its default value.
*
* @param base I2C base pointer.
*/
void I2C_Deinit(I2C_Type* base);
/*!
* @brief This function is used to Enable the I2C Module.
*
* @param base I2C base pointer.
*/
static inline void I2C_Enable(I2C_Type* base)
{
I2C_I2CR_REG(base) |= I2C_I2CR_IEN_MASK;
}
/*!
* @brief This function is used to Disable the I2C Module.
*
* @param base I2C base pointer.
*/
static inline void I2C_Disable(I2C_Type* base)
{
I2C_I2CR_REG(base) &= ~I2C_I2CR_IEN_MASK;
}
/*!
* @brief This function is used to set the baud rate of I2C Module.
*
* @param base I2C base pointer.
* @param clockRate I2C module clock frequency.
* @param baudRate Desired I2C module baud rate.
*/
void I2C_SetBaudRate(I2C_Type* base, uint32_t clockRate, uint32_t baudRate);
/*!
* @brief This function is used to set the own I2C bus address when addressed as a slave.
*
* @param base I2C base pointer.
* @param slaveAddress Own I2C Bus address.
*/
static inline void I2C_SetSlaveAddress(I2C_Type* base, uint8_t slaveAddress)
{
assert(slaveAddress < 0x80);
I2C_IADR_REG(base) = (I2C_IADR_REG(base) & ~I2C_IADR_ADR_MASK) | I2C_IADR_ADR(slaveAddress);
}
/*!
* @name I2C Bus Control functions
* @{
*/
/*!
* @brief This function is used to Generate a Repeat Start Signal on I2C Bus.
*
* @param base I2C base pointer.
*/
static inline void I2C_SendRepeatStart(I2C_Type* base)
{
I2C_I2CR_REG(base) |= I2C_I2CR_RSTA_MASK;
}
/*!
* @brief This function is used to select the I2C bus role of this module,
* both I2C Bus Master and Slave can be select.
*
* @param base I2C base pointer.
* @param mode I2C Bus role to set (see @ref _i2c_work_mode enumeration).
*/
static inline void I2C_SetWorkMode(I2C_Type* base, uint32_t mode)
{
assert((mode == i2cModeMaster) || (mode == i2cModeSlave));
I2C_I2CR_REG(base) = (I2C_I2CR_REG(base) & ~I2C_I2CR_MSTA_MASK) | mode;
}
/*!
* @brief This function is used to select the data transfer direction of this module,
* both Transmit and Receive can be select.
*
* @param base I2C base pointer.
* @param direction I2C Bus data transfer direction (see @ref _i2c_direction_mode enumeration).
*/
static inline void I2C_SetDirMode(I2C_Type* base, uint32_t direction)
{
assert((direction == i2cDirectionReceive) || (direction == i2cDirectionTransmit));
I2C_I2CR_REG(base) = (I2C_I2CR_REG(base) & ~I2C_I2CR_MTX_MASK) | direction;
}
/*!
* @brief This function is used to set the Transmit Acknowledge action when receive
* data from other device.
*
* @param base I2C base pointer.
* @param ack The ACK value answerback to remote I2C device.
* - true: An acknowledge signal is sent to the bus at the ninth clock bit.
* - false: No acknowledge signal response is sent.
*/
void I2C_SetAckBit(I2C_Type* base, bool ack);
/*!
* @name Data transfers functions
* @{
*/
/*!
* @brief Writes one byte of data to the I2C bus.
*
* @param base I2C base pointer.
* @param byte The byte of data to transmit.
*/
static inline void I2C_WriteByte(I2C_Type* base, uint8_t byte)
{
I2C_I2DR_REG(base) = byte;
}
/*!
* @brief Returns the last byte of data read from the bus and initiate another read.
*
* In a master receive mode, calling this function initiates receiving the next byte of data.
*
* @param base I2C base pointer.
* @return This function returns the last byte received while the I2C module is configured in master
* receive or slave receive mode.
*/
static inline uint8_t I2C_ReadByte(I2C_Type* base)
{
return (uint8_t)(I2C_I2DR_REG(base) & I2C_I2DR_DATA_MASK);
}
/*!
* @name Interrupts and flags management functions
* @{
*/
/*!
* @brief Enable or disable I2C interrupt requests.
*
* @param base I2C base pointer.
* @param enable Enable/Disbale I2C interrupt.
* - true: Enable I2C interrupt.
* - false: Disable I2C interrupt.
*/
void I2C_SetIntCmd(I2C_Type* base, bool enable);
/*!
* @brief Gets the I2C status flag state.
*
* @param base I2C base pointer.
* @param flags I2C status flag mask (see @ref _i2c_status_flag enumeration.)
* @return I2C status, each bit represents one status flag
*/
static inline uint32_t I2C_GetStatusFlag(I2C_Type* base, uint32_t flags)
{
return (I2C_I2SR_REG(base) & flags);
}
/*!
* @brief Clear one or more I2C status flag state.
*
* @param base I2C base pointer.
* @param flags I2C status flag mask (see @ref _i2c_status_flag enumeration.)
*/
static inline void I2C_ClearStatusFlag(I2C_Type* base, uint32_t flags)
{
/* Write 0 to clear. */
I2C_I2SR_REG(base) &= ~flags;
}
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* __I2C_IMX_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,348 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "lmem.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define LMEM_CACHE_LINE_SIZE 32
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* System Cache control functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_EnableSystemCache
* Description : This function enable the System Cache.
*
*END**************************************************************************/
void LMEM_EnableSystemCache(LMEM_Type *base)
{
/* set command to invalidate all ways */
/* and write GO bit to initiate command */
LMEM_PSCCR_REG(base) = LMEM_PSCCR_INVW1_MASK | LMEM_PSCCR_INVW0_MASK;
LMEM_PSCCR_REG(base) |= LMEM_PSCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PSCCR_REG(base) & LMEM_PSCCR_GO_MASK);
/* Enable cache, enable write buffer */
LMEM_PSCCR_REG(base) = (LMEM_PSCCR_ENWRBUF_MASK | LMEM_PSCCR_ENCACHE_MASK);
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_DisableSystemCache
* Description : This function disable the System Cache.
*
*END**************************************************************************/
void LMEM_DisableSystemCache(LMEM_Type *base)
{
LMEM_PSCCR_REG(base) = 0x0;
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushSystemCache
* Description : This function flush the System Cache.
*
*END**************************************************************************/
void LMEM_FlushSystemCache(LMEM_Type *base)
{
LMEM_PSCCR_REG(base) |= LMEM_PSCCR_PUSHW0_MASK | LMEM_PSCCR_PUSHW1_MASK ;
LMEM_PSCCR_REG(base) |= LMEM_PSCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PSCCR_REG(base) & LMEM_PSCCR_GO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushSystemCacheLine
* Description : This function is called to push a line out of the System Cache.
*
*END**************************************************************************/
static void LMEM_FlushSystemCacheLine(LMEM_Type *base, void *address)
{
assert((uint32_t)address >= 0x20000000);
/* Invalidate by physical address */
LMEM_PSCLCR_REG(base) = LMEM_PSCLCR_LADSEL_MASK | LMEM_PSCLCR_LCMD(2);
/* Set physical address and activate command */
LMEM_PSCSAR_REG(base) = ((uint32_t)address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
/* wait until the command completes */
while (LMEM_PSCSAR_REG(base) & LMEM_PSCSAR_LGO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushSystemCacheLines
* Description : This function is called to flush the System Cache by
* performing cache copy-backs. It must determine how
* many cache lines need to be copied back and then
* perform the copy-backs.
*
*END**************************************************************************/
void LMEM_FlushSystemCacheLines(LMEM_Type *base, void *address, uint32_t length)
{
void *endAddress = (void *)((uint32_t)address + length);
address = (void *) ((uint32_t)address & ~(LMEM_CACHE_LINE_SIZE - 1));
do
{
LMEM_FlushSystemCacheLine(base, address);
address = (void *) ((uint32_t)address + LMEM_CACHE_LINE_SIZE);
} while (address < endAddress);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateSystemCache
* Description : This function invalidate the System Cache.
*
*END**************************************************************************/
void LMEM_InvalidateSystemCache(LMEM_Type *base)
{
LMEM_PSCCR_REG(base) |= LMEM_PSCCR_INVW0_MASK | LMEM_PSCCR_INVW1_MASK;
LMEM_PSCCR_REG(base) |= LMEM_PSCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PSCCR_REG(base) & LMEM_PSCCR_GO_MASK);
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateSystemCacheLine
* Description : This function is called to invalidate a line out of
* the System Cache.
*
*END**************************************************************************/
static void LMEM_InvalidateSystemCacheLine(LMEM_Type *base, void *address)
{
assert((uint32_t)address >= 0x20000000);
/* Invalidate by physical address */
LMEM_PSCLCR_REG(base) = LMEM_PSCLCR_LADSEL_MASK | LMEM_PSCLCR_LCMD(1);
/* Set physical address and activate command */
LMEM_PSCSAR_REG(base) = ((uint32_t)address & LMEM_PSCSAR_PHYADDR_MASK) | LMEM_PSCSAR_LGO_MASK;
/* wait until the command completes */
while (LMEM_PSCSAR_REG(base) & LMEM_PSCSAR_LGO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateSystemCacheLines
* Description : This function is responsible for performing an data
* cache invalidate. It must determine how many cache
* lines need to be invalidated and then perform the
* invalidation.
*
*END**************************************************************************/
void LMEM_InvalidateSystemCacheLines(LMEM_Type *base, void *address, uint32_t length)
{
void *endAddress = (void *)((uint32_t)address + length);
address = (void *)((uint32_t)address & ~(LMEM_CACHE_LINE_SIZE - 1));
do
{
LMEM_InvalidateSystemCacheLine(base, address);
address = (void *)((uint32_t)address + LMEM_CACHE_LINE_SIZE);
} while (address < endAddress);
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_EnableCodeCache
* Description : This function enable the Code Cache.
*
*END**************************************************************************/
void LMEM_EnableCodeCache(LMEM_Type *base)
{
/* set command to invalidate all ways, enable write buffer */
/* and write GO bit to initiate command */
LMEM_PCCCR_REG(base) = LMEM_PCCCR_INVW1_MASK | LMEM_PCCCR_INVW0_MASK;
LMEM_PCCCR_REG(base) |= LMEM_PCCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PCCCR_REG(base) & LMEM_PCCCR_GO_MASK);
/* Enable cache, enable write buffer */
LMEM_PCCCR_REG(base) = (LMEM_PCCCR_ENWRBUF_MASK | LMEM_PCCCR_ENCACHE_MASK);
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_DisableCodeCache
* Description : This function disable the Code Cache.
*
*END**************************************************************************/
void LMEM_DisableCodeCache(LMEM_Type *base)
{
LMEM_PCCCR_REG(base) = 0x0;
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushCodeCache
* Description : This function flush the Code Cache.
*
*END**************************************************************************/
void LMEM_FlushCodeCache(LMEM_Type *base)
{
LMEM_PCCCR_REG(base) |= LMEM_PCCCR_PUSHW0_MASK | LMEM_PCCCR_PUSHW1_MASK;
LMEM_PCCCR_REG(base) |= LMEM_PCCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PCCCR_REG(base) & LMEM_PCCCR_GO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushCodeCacheLine
* Description : This function is called to push a line out of the
* Code Cache.
*
*END**************************************************************************/
static void LMEM_FlushCodeCacheLine(LMEM_Type *base, void *address)
{
assert((uint32_t)address < 0x20000000);
/* Invalidate by physical address */
LMEM_PCCLCR_REG(base) = LMEM_PCCLCR_LADSEL_MASK | LMEM_PCCLCR_LCMD(2);
/* Set physical address and activate command */
LMEM_PCCSAR_REG(base) = ((uint32_t)address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
/* wait until the command completes */
while (LMEM_PCCSAR_REG(base) & LMEM_PCCSAR_LGO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_FlushCodeCacheLines
* Description : This function is called to flush the instruction
* cache by performing cache copy-backs. It must
* determine how many cache lines need to be copied
* back and then perform the copy-backs.
*
*END**************************************************************************/
void LMEM_FlushCodeCacheLines(LMEM_Type *base, void *address, uint32_t length)
{
void *endAddress = (void *)((uint32_t)address + length);
address = (void *) ((uint32_t)address & ~(LMEM_CACHE_LINE_SIZE - 1));
do
{
LMEM_FlushCodeCacheLine(base, address);
address = (void *)((uint32_t)address + LMEM_CACHE_LINE_SIZE);
} while (address < endAddress);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateCodeCache
* Description : This function invalidate the Code Cache.
*
*END**************************************************************************/
void LMEM_InvalidateCodeCache(LMEM_Type *base)
{
LMEM_PCCCR_REG(base) |= LMEM_PCCCR_INVW0_MASK | LMEM_PCCCR_INVW1_MASK;
LMEM_PCCCR_REG(base) |= LMEM_PCCCR_GO_MASK;
/* wait until the command completes */
while (LMEM_PCCCR_REG(base) & LMEM_PCCCR_GO_MASK);
__ISB();
__DSB();
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateCodeCacheLine
* Description : This function is called to invalidate a line out
* of the Code Cache.
*
*END**************************************************************************/
static void LMEM_InvalidateCodeCacheLine(LMEM_Type *base, void *address)
{
assert((uint32_t)address < 0x20000000);
/* Invalidate by physical address */
LMEM_PCCLCR_REG(base) = LMEM_PCCLCR_LADSEL_MASK | LMEM_PCCLCR_LCMD(1);
/* Set physical address and activate command */
LMEM_PCCSAR_REG(base) = ((uint32_t)address & LMEM_PCCSAR_PHYADDR_MASK) | LMEM_PCCSAR_LGO_MASK;
/* wait until the command completes */
while (LMEM_PCCSAR_REG(base) & LMEM_PCCSAR_LGO_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : LMEM_InvalidateCodeCacheLines
* Description : This function is responsible for performing an
* Code Cache invalidate. It must determine
* how many cache lines need to be invalidated and then
* perform the invalidation.
*
*END**************************************************************************/
void LMEM_InvalidateCodeCacheLines(LMEM_Type *base, void *address, uint32_t length)
{
void *endAddress = (void *)((uint32_t)address + length);
address = (void *)((uint32_t)address & ~(LMEM_CACHE_LINE_SIZE - 1));
do
{
LMEM_InvalidateCodeCacheLine(base, address);
address = (void *)((uint32_t)address + LMEM_CACHE_LINE_SIZE);
} while (address < endAddress);
__ISB();
__DSB();
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,174 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __LMEM_H__
#define __LMEM_H__
#include <stdint.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup lmem_driver
* @{
*/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Processor System Cache control functions
* @{
*/
/*!
* @brief This function enable the System Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_EnableSystemCache(LMEM_Type *base);
/*!
* @brief This function disable the System Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_DisableSystemCache(LMEM_Type *base);
/*!
* @brief This function flush the System Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_FlushSystemCache(LMEM_Type *base);
/*!
* @brief This function is called to flush the System Cache by performing cache copy-backs.
* It must determine how many cache lines need to be copied back and then
* perform the copy-backs.
*
* @param base LMEM base pointer.
* @param address The start address of cache line.
* @param length The length of flush address space.
*/
void LMEM_FlushSystemCacheLines(LMEM_Type *base, void *address, uint32_t length);
/*!
* @brief This function invalidate the System Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_InvalidateSystemCache(LMEM_Type *base);
/*!
* @brief This function is responsible for performing an System Cache invalidate.
* It must determine how many cache lines need to be invalidated and then
* perform the invalidation.
*
* @param base LMEM base pointer.
* @param address The start address of cache line.
* @param length The length of invalidate address space.
*/
void LMEM_InvalidateSystemCacheLines(LMEM_Type *base, void *address, uint32_t length);
/*@}*/
/*!
* @name Processor Code Cache control functions
* @{
*/
/*!
* @brief This function enable the Code Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_EnableCodeCache(LMEM_Type *base);
/*!
* @brief This function disable the Code Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_DisableCodeCache(LMEM_Type *base);
/*!
* @brief This function flush the Code Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_FlushCodeCache(LMEM_Type *base);
/*!
* @brief This function is called to flush the Code Cache by performing cache copy-backs.
* It must determine how many cache lines need to be copied back and then
* perform the copy-backs.
*
* @param base LMEM base pointer.
* @param address The start address of cache line.
* @param length The length of flush address space.
*/
void LMEM_FlushCodeCacheLines(LMEM_Type *base, void *address, uint32_t length);
/*!
* @brief This function invalidate the Code Cache.
*
* @param base LMEM base pointer.
*/
void LMEM_InvalidateCodeCache(LMEM_Type *base);
/*!
* @brief This function is responsible for performing an Code Cache invalidate.
* It must determine how many cache lines need to be invalidated and then
* perform the invalidation.
*
* @param base LMEM base pointer.
* @param address The start address of cache line.
* @param length The length of invalidate address space.
*/
void LMEM_InvalidateCodeCacheLines(LMEM_Type *base, void *address, uint32_t length);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __LMEM_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "mu_imx.h"
/*FUNCTION**********************************************************************
*
* Function Name : MU_TrySendMsg
* Description : Try to send message to the other core.
*
*END**************************************************************************/
mu_status_t MU_TrySendMsg(MU_Type * base, uint32_t regIndex, uint32_t msg)
{
assert(regIndex < MU_TR_COUNT);
// TX register is empty.
if(MU_IsTxEmpty(base, regIndex))
{
base->TR[regIndex] = msg;
return kStatus_MU_Success;
}
return kStatus_MU_TxNotEmpty;
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_SendMsg
* Description : Wait and send message to the other core.
*
*END**************************************************************************/
void MU_SendMsg(MU_Type * base, uint32_t regIndex, uint32_t msg)
{
assert(regIndex < MU_TR_COUNT);
uint32_t mask = MU_SR_TE0_MASK >> regIndex;
// Wait TX register to be empty.
while (!(base->SR & mask)) { }
base->TR[regIndex] = msg;
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_TryReceiveMsg
* Description : Try to receive message from the other core.
*
*END**************************************************************************/
mu_status_t MU_TryReceiveMsg(MU_Type * base, uint32_t regIndex, uint32_t *msg)
{
assert(regIndex < MU_RR_COUNT);
// RX register is full.
if(MU_IsRxFull(base, regIndex))
{
*msg = base->RR[regIndex];
return kStatus_MU_Success;
}
return kStatus_MU_RxNotFull;
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_ReceiveMsg
* Description : Wait to receive message from the other core.
*
*END**************************************************************************/
void MU_ReceiveMsg(MU_Type * base, uint32_t regIndex, uint32_t *msg)
{
assert(regIndex < MU_TR_COUNT);
uint32_t mask = MU_SR_RF0_MASK >> regIndex;
// Wait RX register to be full.
while (!(base->SR & mask)) { }
*msg = base->RR[regIndex];
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_TriggerGeneralInt
* Description : Trigger general purpose interrupt to the other core.
*
*END**************************************************************************/
mu_status_t MU_TriggerGeneralInt(MU_Type * base, uint32_t index)
{
// Previous interrupt has been accepted.
if (MU_IsGeneralIntAccepted(base, index))
{
// All interrupts have been accepted, trigger now.
base->CR = (base->CR & ~MU_CR_GIRn_MASK) // Clear GIRn
| (MU_CR_GIR0_MASK>>index); // Set GIRn
return kStatus_MU_Success;
}
return kStatus_MU_IntPending;
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_TrySetFlags
* Description : Try to set some bits of the 3-bit flag.
*
*END**************************************************************************/
mu_status_t MU_TrySetFlags(MU_Type * base, uint32_t flags)
{
if(MU_IsFlagPending(base))
{
return kStatus_MU_FlagPending;
}
base->CR = (base->CR & ~(MU_CR_GIRn_MASK | MU_CR_Fn_MASK)) | flags;
return kStatus_MU_Success;
}
/*FUNCTION**********************************************************************
*
* Function Name : MU_SetFlags
* Description : Block to set some bits of the 3-bit flag.
*
*END**************************************************************************/
void MU_SetFlags(MU_Type * base, uint32_t flags)
{
while (MU_IsFlagPending(base)) { }
base->CR = (base->CR & ~(MU_CR_GIRn_MASK | MU_CR_Fn_MASK)) | flags;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,569 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MU_IMX_H__
#define __MU_IMX_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup mu_driver
* @{
*/
/******************************************************************************
* Definitions
*****************************************************************************/
/*!@brief Bit mask for general purpose interrupt 0 pending. */
#define MU_SR_GIP0_MASK (1U<<31U)
/*!@brief Bit mask for RX full interrupt 0 pending. */
#define MU_SR_RF0_MASK (1U<<27U)
/*!@brief Bit mask for TX empty interrupt 0 pending. */
#define MU_SR_TE0_MASK (1U<<23U)
/*!@brief Bit mask for general purpose interrupt 0 enable. */
#define MU_CR_GIE0_MASK (1U<<31U)
/*!@brief Bit mask for RX full interrupt 0 enable. */
#define MU_CR_RIE0_MASK (1U<<27U)
/*!@brief Bit mask for TX empty interrupt 0 enable. */
#define MU_CR_TIE0_MASK (1U<<23U)
/*!@brief Bit mask to trigger general purpose interrupt 0. */
#define MU_CR_GIR0_MASK (1U<<19U)
/*!@brief Number of general purpose interrupt. */
#define MU_GPn_COUNT (4U)
/* Mask for MU_CR_GIRN. When read-modify-write to MU_CR, should
pay attention to these bits in case of trigger interrupts by mistake.*/
/*! @brief MU status return codes. */
typedef enum _mu_status
{
kStatus_MU_Success = 0U, /*!< Success. */
kStatus_MU_TxNotEmpty = 1U, /*!< TX register is not empty. */
kStatus_MU_RxNotFull = 2U, /*!< RX register is not full. */
kStatus_MU_FlagPending = 3U, /*!< Previous flags update pending. */
kStatus_MU_EventPending = 4U, /*!< MU event is pending. */
kStatus_MU_Initialized = 5U, /*!< MU driver has initialized previously. */
kStatus_MU_IntPending = 6U, /*!< Previous general interrupt still pending. */
kStatus_MU_Failed = 7U /*!< Execution failed. */
} mu_status_t;
/*! @brief MU message status. */
typedef enum _mu_msg_status
{
kMuTxEmpty0 = MU_SR_TE0_MASK, /*!< TX0 empty status. */
kMuTxEmpty1 = MU_SR_TE0_MASK >> 1U, /*!< TX1 empty status. */
kMuTxEmpty2 = MU_SR_TE0_MASK >> 2U, /*!< TX2 empty status. */
kMuTxEmpty3 = MU_SR_TE0_MASK >> 3U, /*!< TX3 empty status. */
kMuTxEmpty = kMuTxEmpty0 |
kMuTxEmpty1 |
kMuTxEmpty2 |
kMuTxEmpty3, /*!< TX empty status. */
kMuRxFull0 = MU_SR_RF0_MASK, /*!< RX0 full status. */
kMuRxFull1 = MU_SR_RF0_MASK >> 1U, /*!< RX1 full status. */
kMuRxFull2 = MU_SR_RF0_MASK >> 2U, /*!< RX2 full status. */
kMuRxFull3 = MU_SR_RF0_MASK >> 3U, /*!< RX3 full status. */
kMuRxFull = kMuRxFull0 |
kMuRxFull1 |
kMuRxFull2 |
kMuRxFull3, /*!< RX empty status. */
kMuGenInt0 = MU_SR_GIP0_MASK, /*!< General purpose interrupt 0 pending status. */
kMuGenInt1 = MU_SR_GIP0_MASK >> 1U, /*!< General purpose interrupt 2 pending status. */
kMuGenInt2 = MU_SR_GIP0_MASK >> 2U, /*!< General purpose interrupt 2 pending status. */
kMuGenInt3 = MU_SR_GIP0_MASK >> 3U, /*!< General purpose interrupt 3 pending status. */
kMuGenInt = kMuGenInt0 |
kMuGenInt1 |
kMuGenInt2 |
kMuGenInt3, /*!< General purpose interrupt pending status. */
kMuStatusAll = kMuTxEmpty |
kMuRxFull |
kMuGenInt, /*!< All MU status. */
} mu_msg_status_t;
/*! @brief Power mode definition. */
typedef enum _mu_power_mode
{
kMuPowerModeRun = 0x00U, /*!< Run mode. */
kMuPowerModeWait = 0x01U, /*!< WAIT mode. */
kMuPowerModeStop = 0x02U, /*!< STOP mode. */
kMuPowerModeDsm = 0x03U, /*!< DSM mode. */
} mu_power_mode_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization.
* @{
*/
/*!
* @brief Initializes the MU module to reset state.
* This function sets the MU module control register to its default reset value.
*
* @param base Register base address for the module.
*/
static inline void MU_Init(MU_Type * base)
{
// Clear GIEn, RIEn, TIEn, GIRn and ABFn.
base->CR &= ~(MU_CR_GIEn_MASK | MU_CR_RIEn_MASK | MU_CR_TIEn_MASK | MU_CR_GIRn_MASK | MU_CR_Fn_MASK);
}
/* @} */
/*!
* @name Send Messages.
* @{
*/
/*!
* @brief Try to send a message.
*
* This function tries to send a message, if the TX register is not empty,
* this function returns kStatus_MU_TxNotEmpty.
*
* @param base Register base address for the module.
* @param regIdex Tx register index.
* @param msg Message to send.
* @retval kStatus_MU_Success Message send successfully.
* @retval kStatus_MU_TxNotEmpty Message not send because TX is not empty.
*/
mu_status_t MU_TrySendMsg(MU_Type * base, uint32_t regIndex, uint32_t msg);
/*!
* @brief Block to send a message.
*
* This function waits until TX register is empty and send the message.
*
* @param base Register base address for the module.
* @param regIdex Tx register index.
* @param msg Message to send.
*/
void MU_SendMsg(MU_Type * base, uint32_t regIndex, uint32_t msg);
/*!
* @brief Check TX empty status.
*
* This function checks the specific transmit register empty status.
*
* @param base Register base address for the module.
* @param index TX register index to check.
* @retval true TX register is empty.
* @retval false TX register is not empty.
*/
static inline bool MU_IsTxEmpty(MU_Type * base, uint32_t index)
{
return (bool)(base->SR & (MU_SR_TE0_MASK >> index));
}
/*!
* @brief Enable TX empty interrupt.
*
* This function enables specific TX empty interrupt.
*
* @param base Register base address for the module.
* @param index TX interrupt index to enable.
*
* Example:
@code
// To enable TX0 empty interrupts.
MU_EnableTxEmptyInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_EnableTxEmptyInt(MU_Type * base, uint32_t index)
{
base->CR = (base->CR & ~ MU_CR_GIRn_MASK) // Clear GIRn
| (MU_CR_TIE0_MASK>>index); // Set TIEn
}
/*!
* @brief Disable TX empty interrupt.
*
* This function disables specific TX empty interrupt.
*
* @param base Register base address for the module.
* @param disableMask Bitmap of the interrupts to disable.
*
* Example:
@code
// To disable TX0 empty interrupts.
MU_DisableTxEmptyInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_DisableTxEmptyInt(MU_Type * base, uint32_t index)
{
base->CR &= ~(MU_CR_GIRn_MASK | (MU_CR_TIE0_MASK>>index)); // Clear GIRn , clear TIEn
}
/* @} */
/*!
* @name Receive Messages.
* @{
*/
/*!
* @brief Try to receive a message.
*
* This function tries to receive a message, if the RX register is not full,
* this function returns kStatus_MU_RxNotFull.
*
* @param base Register base address for the module.
* @param regIdex Rx register index.
* @param msg Message to receive.
* @retval kStatus_MU_Success Message receive successfully.
* @retval kStatus_MU_RxNotFull Message not received because RX is not full.
*/
mu_status_t MU_TryReceiveMsg(MU_Type * base, uint32_t regIndex, uint32_t *msg);
/*!
* @brief Block to receive a message.
*
* This function waits until RX register is full and receive the message.
*
* @param base Register base address for the module.
* @param regIdex Rx register index.
* @param msg Message to receive.
*/
void MU_ReceiveMsg(MU_Type * base, uint32_t regIndex, uint32_t *msg);
/*!
* @brief Check RX full status.
*
* This function checks the specific receive register full status.
*
* @param base Register base address for the module.
* @param index RX register index to check.
* @retval true RX register is full.
* @retval false RX register is not full.
*/
static inline bool MU_IsRxFull(MU_Type * base, uint32_t index)
{
return (bool)(base->SR & (MU_SR_RF0_MASK >> index));
}
/*!
* @brief Enable RX full interrupt.
*
* This function enables specific RX full interrupt.
*
* @param base Register base address for the module.
* @param index RX interrupt index to enable.
*
* Example:
@code
// To enable RX0 full interrupts.
MU_EnableRxFullInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_EnableRxFullInt(MU_Type * base, uint32_t index)
{
base->CR = (base->CR & ~MU_CR_GIRn_MASK) // Clear GIRn
| (MU_CR_RIE0_MASK>>index); // Set RIEn
}
/*!
* @brief Disable RX full interrupt.
*
* This function disables specific RX full interrupt.
*
* @param base Register base address for the module.
* @param disableMask Bitmap of the interrupts to disable.
*
* Example:
@code
// To disable RX0 full interrupts.
MU_DisableRxFullInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_DisableRxFullInt(MU_Type * base, uint32_t index)
{
base->CR &= ~(MU_CR_GIRn_MASK | (MU_CR_RIE0_MASK>>index)); // Clear GIRn, clear RIEn
}
/* @} */
/*!
* @name General Purpose Interrupt.
* @{
*/
/*!
* @brief Enable general purpose interrupt.
*
* This function enables specific general purpose interrupt.
*
* @param base Register base address for the module.
* @param index General purpose interrupt index to enable.
*
* Example:
@code
// To enable general purpose interrupts 0.
MU_EnableGeneralInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_EnableGeneralInt(MU_Type * base, uint32_t index)
{
base->CR = (base->CR & ~MU_CR_GIRn_MASK) // Clear GIRn
| (MU_CR_GIE0_MASK>>index); // Set GIEn
}
/*!
* @brief Disable general purpose interrupt.
*
* This function disables specific general purpose interrupt.
*
* @param base Register base address for the module.
* @param index General purpose interrupt index to disable.
*
* Example:
@code
// To disable general purpose interrupts 0.
MU_DisableGeneralInt(MU0_BASE, 0U);
@endcode
*/
static inline void MU_DisableGeneralInt(MU_Type * base, uint32_t index)
{
base->CR &= ~(MU_CR_GIRn_MASK | (MU_CR_GIE0_MASK>>index)); // Clear GIRn, clear GIEn
}
/*!
* @brief Check specific general purpose interrupt pending flag.
*
* This function checks the specific general purpose interrupt pending status.
*
* @param base Register base address for the module.
* @param index Index of the general purpose interrupt flag to check.
* @retval true General purpose interrupt is pending.
* @retval false General purpose interrupt is not pending.
*/
static inline bool MU_IsGeneralIntPending(MU_Type * base, uint32_t index)
{
return (bool)(base->SR & (MU_SR_GIP0_MASK >> index));
}
/*!
* @brief Clear specific general purpose interrupt pending flag.
*
* This function clears the specific general purpose interrupt pending status.
*
* @param base Register base address for the module.
* @param index Index of the general purpose interrupt flag to clear.
*/
static inline void MU_ClearGeneralIntPending(MU_Type * base, uint32_t index)
{
base->SR = (MU_SR_GIP0_MASK >> index);
}
/*!
* @brief Trigger specific general purpose interrupt.
*
* This function triggers specific general purpose interrupt to other core.
*
* To ensure proper operations, make sure the correspond general purpose
* interrupt triggered previously has been accepted by the other core. The
* function MU_IsGeneralIntAccepted can be used for this check. If the
* previous general interrupt has not been accepted by the other core, this
* function does not trigger interrupt actually and returns an error.
*
* @param base Register base address for the module.
* @param index Index of general purpose interrupt to trigger.
* @retval kStatus_MU_Success Interrupt has been triggered successfully.
* @retval kStatus_MU_IntPending Previous interrupt has not been accepted.
*/
mu_status_t MU_TriggerGeneralInt(MU_Type * base, uint32_t index);
/*!
* @brief Check specific general purpose interrupt is accepted or not.
*
* This function checks whether the specific general purpose interrupt has
* been accepted by the other core or not.
*
* @param base Register base address for the module.
* @param index Index of the general purpose interrupt to check.
* @retval true General purpose interrupt is accepted.
* @retval false General purpose interrupt is not accepted.
*/
static inline bool MU_IsGeneralIntAccepted(MU_Type * base, uint32_t index)
{
return !(bool)(base->CR & (MU_CR_GIR0_MASK >> index));
}
/* @} */
/*!
* @name Flags
* @{
*/
/*!
* @brief Try to set some bits of the 3-bit flag reflect on the other MU side.
*
* This functions tries to set some bits of the 3-bit flag. If previous flags
* update is still pending, this function returns kStatus_MU_FlagPending.
*
* @param base Register base address for the module.
* @retval kStatus_MU_Success Flag set successfully.
* @retval kStatus_MU_FlagPending Previous flag update is pending.
*/
mu_status_t MU_TrySetFlags(MU_Type * base, uint32_t flags);
/*!
* @brief Set some bits of the 3-bit flag reflect on the other MU side.
*
* This functions set some bits of the 3-bit flag. If previous flags update is
* still pending, this function blocks and polls to set the flag.
*
* @param base Register base address for the module.
*/
void MU_SetFlags(MU_Type * base, uint32_t flags);
/*!
* @brief Checks whether the previous flag update is pending.
*
* After setting flags, the flags update request is pending until internally
* acknowledged. During the pending period, it is not allowed to set flags again.
* This function is used to check the pending status, it can be used together
* with function MU_TrySetFlags.
*
* @param base Register base address for the module.
* @return True if pending, false if not.
*/
static inline bool MU_IsFlagPending(MU_Type * base)
{
return (bool)(base->SR & MU_SR_FUP_MASK);
}
/*!
* @brief Get the current value of the 3-bit flag set by other side.
*
* This functions gets the current value of the 3-bit flag.
*
* @param base Register base address for the module.
* @return flags Current value of the 3-bit flag.
*/
static inline uint32_t MU_GetFlags(MU_Type * base)
{
return base->SR & MU_SR_Fn_MASK;
}
/* @} */
/*!
* @name Misc.
* @{
*/
/*!
* @brief Get the power mode of the other core.
*
* This functions gets the power mode of the other core.
*
* @param base Register base address for the module.
* @return powermode Power mode of the other core.
*/
static inline mu_power_mode_t MU_GetOtherCorePowerMode(MU_Type * base)
{
return (mu_power_mode_t)((base->SR & MU_SR_PM_MASK) >> MU_SR_PM_SHIFT);
}
/*!
* @brief Get the event pending status.
*
* This functions gets the event pending status. To ensure events have been
* posted to the other side before entering STOP mode, verify the
* event pending status using this function.
*
* @param base Register base address for the module.
* @retval true Event is pending.
* @retval false Event is not pending.
*/
static inline bool MU_IsEventPending(MU_Type * base)
{
return (bool)(base->SR & MU_SR_EP_MASK);
}
/*!
* @brief Get the the MU message status.
*
* This functions gets TX/RX and general purpose interrupt pending status. The
* parameter is passed in as bitmask of the status to check.
*
* @param base Register base address for the module.
* @param statusToCheck The status to check, see mu_msg_status_t.
* @return Status checked.
*
* Example:
@code
// To check TX0 empty status.
MU_GetMsgStatus(MU0_BASE, kMuTxEmpty0);
// To check all RX full status.
MU_GetMsgStatus(MU0_BASE, kMuRxFull);
// To check general purpose interrupt 0 and 3 pending status.
MU_GetMsgStatus(MU0_BASE, kMuGenInt0 | kMuGenInt3);
// To check all status.
MU_GetMsgStatus(MU0_BASE, kMuStatusAll);
@endcode
*/
static inline uint32_t MU_GetMsgStatus(MU_Type * base, uint32_t statusToCheck)
{
return base->SR & statusToCheck;
}
/* @} */
#if defined(__cplusplus)
}
#endif
/*!
* @}
*/
#endif /* __MU_IMX_H__ */
/******************************************************************************
* EOF
*****************************************************************************/

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "rdc.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SetMrAccess
* Description : Set RDC memory region access permission for RDC domains
*
*END**************************************************************************/
void RDC_SetMrAccess(RDC_Type * base, uint32_t mr, uint32_t startAddr, uint32_t endAddr,
uint8_t perm, bool enable, bool lock)
{
base->MR[mr].MRSA = startAddr;
base->MR[mr].MREA = endAddr;
base->MR[mr].MRC = perm | (enable ? RDC_MRC_ENA_MASK : 0) | (lock ? RDC_MRC_LCK_MASK : 0);
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_GetMrAccess
* Description : Get RDC memory region access permission for RDC domains
*
*END**************************************************************************/
uint8_t RDC_GetMrAccess(RDC_Type * base, uint32_t mr, uint32_t *startAddr, uint32_t *endAddr)
{
if (startAddr)
*startAddr = base->MR[mr].MRSA;
if (endAddr)
*endAddr = base->MR[mr].MREA;
return base->MR[mr].MRC & 0xFF;
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_GetViolationStatus
* Description : Get RDC memory violation status
*
*END**************************************************************************/
bool RDC_GetViolationStatus(RDC_Type * base, uint32_t mr, uint32_t *violationAddr, uint32_t *violationDomain)
{
uint32_t mrvs;
mrvs = base->MR[mr].MRVS;
if (violationAddr)
*violationAddr = mrvs & RDC_MRVS_VADR_MASK;
if (violationDomain)
*violationDomain = (mrvs & RDC_MRVS_VDID_MASK) >> RDC_MRVS_VDID_SHIFT;
return (bool)(mrvs & RDC_MRVS_AD_MASK);
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RDC_H__
#define __RDC_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup rdc_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name RDC State Control
* @{
*/
/*!
* @brief Get domain ID of core that is reading this
*
* @param base RDC base pointer.
* @return Domain ID of self core
*/
static inline uint32_t RDC_GetSelfDomainID(RDC_Type * base)
{
return (base->STAT & RDC_STAT_DID_MASK) >> RDC_STAT_DID_SHIFT;
}
/*!
* @brief Check whether memory region controlled by RDC is accessible after low power recovery
*
* @param base RDC base pointer.
* @return Memory region power status.
* - true: on and accessible.
* - false: off.
*/
static inline bool RDC_IsMemPowered(RDC_Type * base)
{
return (bool)(base->STAT & RDC_STAT_PDS_MASK);
}
/*!
* @brief Check whether there's pending RDC memory region restoration interrupt
*
* @param base RDC base pointer.
* @return RDC interrupt status
* - true: Interrupt pending.
* - false: No interrupt pending.
*/
static inline bool RDC_IsIntPending(RDC_Type * base)
{
return (bool)(base->INTSTAT);
}
/*!
* @brief Clear interrupt status
*
* @param base RDC base pointer.
*/
static inline void RDC_ClearStatusFlag(RDC_Type * base)
{
base->INTSTAT = RDC_INTSTAT_INT_MASK;
}
/*!
* @brief Set RDC interrupt mode
*
* @param base RDC base pointer
* @param enable RDC interrupt control.
* - true: enable interrupt.
* - false: disable interrupt.
*/
static inline void RDC_SetIntCmd(RDC_Type * base, bool enable)
{
base->INTCTRL = enable ? RDC_INTCTRL_RCI_EN_MASK : 0;
}
/*@}*/
/*!
* @name RDC Domain Control
* @{
*/
/*!
* @brief Set RDC domain ID for RDC master
*
* @param base RDC base pointer
* @param mda RDC master assignment (see @ref _rdc_mda in rdc_defs_<device>.h)
* @param domainId RDC domain ID (0-3)
* @param lock Whether to lock this setting? Once locked, no one can change the domain assignment until reset
*/
static inline void RDC_SetDomainID(RDC_Type * base, uint32_t mda, uint32_t domainId, bool lock)
{
assert (domainId <= RDC_MDA_DID_MASK);
base->MDA[mda] = RDC_MDA_DID(domainId) | (lock ? RDC_MDA_LCK_MASK : 0);
}
/*!
* @brief Get RDC domain ID for RDC master
*
* @param base RDC base pointer
* @param mda RDC master assignment (see @ref _rdc_mda in rdc_defs_<device>.h)
* @return RDC domain ID (0-3)
*/
static inline uint32_t RDC_GetDomainID(RDC_Type * base, uint32_t mda)
{
return base->MDA[mda] & RDC_MDA_DID_MASK;
}
/*!
* @brief Set RDC peripheral access permission for RDC domains
*
* @param base RDC base pointer
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @param perm RDC access permission from RDC domain to peripheral (byte: D3R D3W D2R D2W D1R D1W D0R D0W)
* @param sreq Force acquiring SEMA42 to access this peripheral or not
* @param lock Whether to lock this setting or not. Once locked, no one can change the RDC setting until reset
*/
static inline void RDC_SetPdapAccess(RDC_Type * base, uint32_t pdap, uint8_t perm, bool sreq, bool lock)
{
base->PDAP[pdap] = perm | (sreq ? RDC_PDAP_SREQ_MASK : 0) | (lock ? RDC_PDAP_LCK_MASK : 0);
}
/*!
* @brief Get RDC peripheral access permission for RDC domains
*
* @param base RDC base pointer
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @return RDC access permission from RDC domain to peripheral (byte: D3R D3W D2R D2W D1R D1W D0R D0W)
*/
static inline uint8_t RDC_GetPdapAccess(RDC_Type * base, uint32_t pdap)
{
return base->PDAP[pdap] & 0xFF;
}
/*!
* @brief Check whether RDC semaphore is required to access the peripheral
*
* @param base RDC base pointer
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @return RDC semaphore required or not.
* - true: RDC semaphore is required.
* - false: RDC semaphore is not required.
*/
static inline bool RDC_IsPdapSemaphoreRequired(RDC_Type * base, uint32_t pdap)
{
return (bool)(base->PDAP[pdap] & RDC_PDAP_SREQ_MASK);
}
/*!
* @brief Set RDC memory region access permission for RDC domains
*
* @param base RDC base pointer
* @param mr RDC memory region assignment (see @ref _rdc_mr in rdc_defs_<device>.h)
* @param startAddr memory region start address (inclusive)
* @param endAddr memory region end address (exclusive)
* @param perm RDC access permission from RDC domain to peripheral (byte: D3R D3W D2R D2W D1R D1W D0R D0W)
* @param enable Enable this memory region for RDC control or not
* @param lock Whether to lock this setting or not. Once locked, no one can change the RDC setting until reset
*/
void RDC_SetMrAccess(RDC_Type * base, uint32_t mr, uint32_t startAddr, uint32_t endAddr,
uint8_t perm, bool enable, bool lock);
/*!
* @brief Get RDC memory region access permission for RDC domains
*
* @param base RDC base pointer
* @param mr RDC memory region assignment (see @ref _rdc_mr in rdc_defs_<device>.h)
* @param startAddr pointer to get memory region start address (inclusive), NULL is allowed.
* @param endAddr pointer to get memory region end address (exclusive), NULL is allowed.
* @return RDC access permission from RDC domain to peripheral (byte: D3R D3W D2R D2W D1R D1W D0R D0W)
*/
uint8_t RDC_GetMrAccess(RDC_Type * base, uint32_t mr, uint32_t *startAddr, uint32_t *endAddr);
/*!
* @brief Check whether the memory region is enabled
*
* @param base RDC base pointer
* @param mr RDC memory region assignment (see _rdc_mr in rdc_defs_<device>.h)
* @return Memory region enabled or not.
* - true: Memory region is enabled.
* - false: Memory region is not enabled.
*/
static inline bool RDC_IsMrEnabled(RDC_Type * base, uint32_t mr)
{
return (bool)(base->MR[mr].MRC & RDC_MRC_ENA_MASK);
}
/*!
* @brief Get memory violation status
*
* @param base RDC base pointer
* @param mr RDC memory region assignment (see @ref _rdc_mr in rdc_defs_<device>.h)
* @param violationAddr Pointer to store violation address, NULL allowed
* @param violationDomain Pointer to store domain ID causing violation, NULL allowed
* @return Memory violation occurred or not.
* - true: violation happened.
* - false: No violation happened.
*/
bool RDC_GetViolationStatus(RDC_Type * base, uint32_t mr, uint32_t *violationAddr, uint32_t *violationDomain);
/*!
* @brief Clear RDC violation status
*
* @param base RDC base pointer
* @param mr RDC memory region assignment (see @ref _rdc_mr in rdc_defs_<device>.h)
*/
static inline void RDC_ClearViolationStatus(RDC_Type * base, uint32_t mr)
{
base->MR[mr].MRVS = RDC_MRVS_AD_MASK;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __RDC_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RDC_DEFS_IMX7D__
#define __RDC_DEFS_IMX7D__
/*!
* @addtogroup rdc_def_imx7d
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief RDC master assignment. */
enum _rdc_mda
{
rdcMdaA7 = 0U, /*!< ARM Cortex-A7 RDC Master. */
rdcMdaM4 = 1U, /*!< ARM Cortex-M4 RDC Master. */
rdcMdaPcie = 2U, /*!< PCIe RDC Master. */
rdcMdaCsi = 3U, /*!< CSI RDC Master. */
rdcMdaEpdc = 4U, /*!< EPDC RDC Master. */
rdcMdaLcdif = 5U, /*!< LCDIF RDC Master. */
rdcMdaDisplayPort = 6U, /*!< DISPLAY PORT RDC Master. */
rdcMdaPxp = 7U, /*!< PXP RDC Master. */
rdcMdaCoresight = 8U, /*!< CORESIGHT RDC Master. */
rdcMdaDap = 9U, /*!< DAP RDC Master. */
rdcMdaCaam = 10U, /*!< CAAM RDC Master. */
rdcMdaSdmaPeriph = 11U, /*!< SDMA PERIPHERAL RDC Master. */
rdcMdaSdmaBurst = 12U, /*!< SDMA BURST RDC Master. */
rdcMdaApbhdma = 13U, /*!< APBH DMA RDC Master. */
rdcMdaRawnand = 14U, /*!< RAW NAND RDC Master. */
rdcMdaUsdhc1 = 15U, /*!< USDHC1 RDC Master. */
rdcMdaUsdhc2 = 16U, /*!< USDHC2 RDC Master. */
rdcMdaUsdhc3 = 17U, /*!< USDHC3 RDC Master. */
rdcMdaNc1 = 18U, /*!< NC1 RDC Master. */
rdcMdaUsb = 19U, /*!< USB RDC Master. */
rdcMdaNc2 = 20U, /*!< NC2 RDC Master. */
rdcMdaTest = 21U, /*!< TEST RDC Master. */
rdcMdaEnet1Tx = 22U, /*!< Ethernet1 Tx RDC Master. */
rdcMdaEnet1Rx = 23U, /*!< Ethernet1 Rx RDC Master. */
rdcMdaEnet2Tx = 24U, /*!< Ethernet2 Tx RDC Master. */
rdcMdaEnet2Rx = 25U, /*!< Ethernet2 Rx RDC Master. */
rdcMdaSdmaPort = 26U, /*!< SDMA PORT RDC Master. */
};
/*! @brief RDC peripheral assignment. */
enum _rdc_pdap
{
rdcPdapGpio1 = 0U, /*!< GPIO1 RDC Peripheral. */
rdcPdapGpio2 = 1U, /*!< GPIO2 RDC Peripheral. */
rdcPdapGpio3 = 2U, /*!< GPIO3 RDC Peripheral. */
rdcPdapGpio4 = 3U, /*!< GPIO4 RDC Peripheral. */
rdcPdapGpio5 = 4U, /*!< GPIO5 RDC Peripheral. */
rdcPdapGpio6 = 5U, /*!< GPIO6 RDC Peripheral. */
rdcPdapGpio7 = 6U, /*!< GPIO7 RDC Peripheral. */
rdcPdapIomuxcLpsrGpr = 7U, /*!< IOMXUC LPSR GPR RDC Peripheral. */
rdcPdapWdog1 = 8U, /*!< WDOG1 RDC Peripheral. */
rdcPdapWdog2 = 9U, /*!< WDOG2 RDC Peripheral. */
rdcPdapWdog3 = 10U, /*!< WDOG3 RDC Peripheral. */
rdcPdapWdog4 = 11U, /*!< WDOG4 RDC Peripheral. */
rdcPdapIomuxcLpsr = 12U, /*!< IOMUXC LPSR RDC Peripheral. */
rdcPdapGpt1 = 13U, /*!< GPT1 RDC Peripheral. */
rdcPdapGpt2 = 14U, /*!< GPT2 RDC Peripheral. */
rdcPdapGpt3 = 15U, /*!< GPT3 RDC Peripheral. */
rdcPdapGpt4 = 16U, /*!< GPT4 RDC Peripheral. */
rdcPdapRomcp = 17U, /*!< ROMCP RDC Peripheral. */
rdcPdapKpp = 18U, /*!< KPP RDC Peripheral. */
rdcPdapIomuxc = 19U, /*!< IOMUXC RDC Peripheral. */
rdcPdapIomuxcGpr = 20U, /*!< IOMUXC GPR RDC Peripheral. */
rdcPdapOcotpCtrl = 21U, /*!< OCOTP CTRL RDC Peripheral. */
rdcPdapAnatopDig = 22U, /*!< ANATOPDIG RDC Peripheral. */
rdcPdapSnvs = 23U, /*!< SNVS RDC Peripheral. */
rdcPdapCcm = 24U, /*!< CCM RDC Peripheral. */
rdcPdapSrc = 25U, /*!< SRC RDC Peripheral. */
rdcPdapGpc = 26U, /*!< GPC RDC Peripheral. */
rdcPdapSemaphore1 = 27U, /*!< SEMAPHORE1 RDC Peripheral. */
rdcPdapSemaphore2 = 28U, /*!< SEMAPHORE2 RDC Peripheral. */
rdcPdapRdc = 29U, /*!< RDC RDC Peripheral. */
rdcPdapCsu = 30U, /*!< CSU RDC Peripheral. */
rdcPdapReserved1 = 31U, /*!< Reserved1 RDC Peripheral. */
rdcPdapReserved2 = 32U, /*!< Reserved2 RDC Peripheral. */
rdcPdapAdc1 = 33U, /*!< ADC1 RDC Peripheral. */
rdcPdapAdc2 = 34U, /*!< ADC2 RDC Peripheral. */
rdcPdapEcspi4 = 35U, /*!< ECSPI4 RDC Peripheral. */
rdcPdapFlexTimer1 = 36U, /*!< FTM1 RDC Peripheral. */
rdcPdapFlexTimer2 = 37U, /*!< FTM2 RDC Peripheral. */
rdcPdapPwm1 = 38U, /*!< PWM1 RDC Peripheral. */
rdcPdapPwm2 = 39U, /*!< PWM2 RDC Peripheral. */
rdcPdapPwm3 = 40U, /*!< PWM3 RDC Peripheral. */
rdcPdapPwm4 = 41U, /*!< PWM4 RDC Peripheral. */
rdcPdapSystemCounterRead = 42U, /*!< System Counter Read RDC Peripheral. */
rdcPdapSystemCounterCompare = 43U, /*!< System Counter Compare RDC Peripheral. */
rdcPdapSystemCounterControl = 44U, /*!< System Counter Control RDC Peripheral. */
rdcPdapPcie = 45U, /*!< PCIE RDC Peripheral. */
rdcPdapReserved3 = 46U, /*!< Reserved3 RDC Peripheral. */
rdcPdapEpdc = 47U, /*!< EPDC RDC Peripheral. */
rdcPdapPxp = 48U, /*!< PXP RDC Peripheral. */
rdcPdapCsi = 49U, /*!< CSI RDC Peripheral. */
rdcPdapReserved4 = 50U, /*!< Reserved4 RDC Peripheral. */
rdcPdapLcdif = 51U, /*!< LCDIF RDC Peripheral. */
rdcPdapReserved5 = 52U, /*!< Reserved5 RDC Peripheral. */
rdcPdapMipiCsi = 53U, /*!< MIPI CSI RDC Peripheral. */
rdcPdapMipiDsi = 54U, /*!< MIPI DSI RDC Peripheral. */
rdcPdapReserved6 = 55U, /*!< Reserved6 RDC Peripheral. */
rdcPdapTzasc = 56U, /*!< TZASC RDC Peripheral. */
rdcPdapDdrPhy = 57U, /*!< DDR PHY RDC Peripheral. */
rdcPdapDdrc = 58U, /*!< DDRC RDC Peripheral. */
rdcPdapReserved7 = 59U, /*!< Reserved7 RDC Peripheral. */
rdcPdapPerfMon1 = 60U, /*!< PerfMon1 RDC Peripheral. */
rdcPdapPerfMon2 = 61U, /*!< PerfMon2 RDC Peripheral. */
rdcPdapAxi = 62U, /*!< AXI RDC Peripheral. */
rdcPdapQosc = 63U, /*!< QOSC RDC Peripheral. */
rdcPdapFlexCan1 = 64U, /*!< FLEXCAN1 RDC Peripheral. */
rdcPdapFlexCan2 = 65U, /*!< FLEXCAN2 RDC Peripheral. */
rdcPdapI2c1 = 66U, /*!< I2C1 RDC Peripheral. */
rdcPdapI2c2 = 67U, /*!< I2C2 RDC Peripheral. */
rdcPdapI2c3 = 68U, /*!< I2C3 RDC Peripheral. */
rdcPdapI2c4 = 69U, /*!< I2C4 RDC Peripheral. */
rdcPdapUart4 = 70U, /*!< UART4 RDC Peripheral. */
rdcPdapUart5 = 71U, /*!< UART5 RDC Peripheral. */
rdcPdapUart6 = 72U, /*!< UART6 RDC Peripheral. */
rdcPdapUart7 = 73U, /*!< UART7 RDC Peripheral. */
rdcPdapMuA = 74U, /*!< MUA RDC Peripheral. */
rdcPdapMuB = 75U, /*!< MUB RDC Peripheral. */
rdcPdapSemaphoreHs = 76U, /*!< SEMAPHORE HS RDC Peripheral. */
rdcPdapUsbPl301 = 77U, /*!< USB PL301 RDC Peripheral. */
rdcPdapReserved8 = 78U, /*!< Reserved8 RDC Peripheral. */
rdcPdapReserved9 = 79U, /*!< Reserved9 RDC Peripheral. */
rdcPdapReserved10 = 80U, /*!< Reserved10 RDC Peripheral. */
rdcPdapUSB1Otg1 = 81U, /*!< USB2 OTG1 RDC Peripheral. */
rdcPdapUSB2Otg2 = 82U, /*!< USB2 OTG2 RDC Peripheral. */
rdcPdapUSB3Host = 83U, /*!< USB3 HOST RDC Peripheral. */
rdcPdapUsdhc1 = 84U, /*!< USDHC1 RDC Peripheral. */
rdcPdapUsdhc2 = 85U, /*!< USDHC2 RDC Peripheral. */
rdcPdapUsdhc3 = 86U, /*!< USDHC3 RDC Peripheral. */
rdcPdapReserved11 = 87U, /*!< Reserved11 RDC Peripheral. */
rdcPdapReserved12 = 88U, /*!< Reserved12 RDC Peripheral. */
rdcPdapSim1 = 89U, /*!< SIM1 RDC Peripheral. */
rdcPdapSim2 = 90U, /*!< SIM2 RDC Peripheral. */
rdcPdapQspi = 91U, /*!< QSPI RDC Peripheral. */
rdcPdapWeim = 92U, /*!< WEIM RDC Peripheral. */
rdcPdapSdma = 93U, /*!< SDMA RDC Peripheral. */
rdcPdapEnet1 = 94U, /*!< Eneternet1 RDC Peripheral. */
rdcPdapEnet2 = 95U, /*!< Eneternet2 RDC Peripheral. */
rdcPdapReserved13 = 96U, /*!< Reserved13 RDC Peripheral. */
rdcPdapReserved14 = 97U, /*!< Reserved14 RDC Peripheral. */
rdcPdapEcspi1 = 98U, /*!< ECSPI1 RDC Peripheral. */
rdcPdapEcspi2 = 99U, /*!< ECSPI2 RDC Peripheral. */
rdcPdapEcspi3 = 100U, /*!< ECSPI3 RDC Peripheral. */
rdcPdapReserved15 = 101U, /*!< Reserved15 RDC Peripheral. */
rdcPdapUart1 = 102U, /*!< UART1 RDC Peripheral. */
rdcPdapReserved16 = 103U, /*!< Reserved16 RDC Peripheral. */
rdcPdapUart3 = 104U, /*!< UART3 RDC Peripheral. */
rdcPdapUart2 = 105U, /*!< UART2 RDC Peripheral. */
rdcPdapSai1 = 106U, /*!< SAI1 RDC Peripheral. */
rdcPdapSai2 = 107U, /*!< SAI2 RDC Peripheral. */
rdcPdapSai3 = 108U, /*!< SAI3 RDC Peripheral. */
rdcPdapReserved17 = 109U, /*!< Reserved17 RDC Peripheral. */
rdcPdapReserved18 = 110U, /*!< Reserved18 RDC Peripheral. */
rdcPdapSpba = 111U, /*!< SPBA RDC Peripheral. */
rdcPdapDap = 112U, /*!< DAP RDC Peripheral. */
rdcPdapReserved19 = 113U, /*!< Reserved19 RDC Peripheral. */
rdcPdapReserved20 = 114U, /*!< Reserved20 RDC Peripheral. */
rdcPdapReserved21 = 115U, /*!< Reserved21 RDC Peripheral. */
rdcPdapCaam = 116U, /*!< CAAM RDC Peripheral. */
rdcPdapReserved22 = 117U, /*!< Reserved22 RDC Peripheral. */
};
/*! @brief RDC memory region. */
enum _rdc_mr
{
rdcMrMmdc = 0U, /*!< alignment 4096 */
rdcMrMmdcLast = 7U, /*!< alignment 4096 */
rdcMrQspi = 8U, /*!< alignment 4096 */
rdcMrQspiLast = 15U, /*!< alignment 4096 */
rdcMrWeim = 16U, /*!< alignment 4096 */
rdcMrWeimLast = 23U, /*!< alignment 4096 */
rdcMrPcie = 24U, /*!< alignment 4096 */
rdcMrPcieLast = 31U, /*!< alignment 4096 */
rdcMrOcram = 32U, /*!< alignment 128 */
rdcMrOcramLast = 36U, /*!< alignment 128 */
rdcMrOcramS = 37U, /*!< alignment 128 */
rdcMrOcramSLast = 41U, /*!< alignment 128 */
rdcMrOcramEpdc = 42U, /*!< alignment 128 */
rdcMrOcramEpdcLast = 46U, /*!< alignment 128 */
rdcMrOcramPxp = 47U, /*!< alignment 128 */
rdcMrOcramPxpLast = 51U, /*!< alignment 128 */
};
#endif /* __RDC_DEFS_IMX7D__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,187 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include "rdc_semaphore.h"
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* Private Functions
******************************************************************************/
static RDC_SEMAPHORE_Type *RDC_SEMAPHORE_GetGate(uint32_t *pdap)
{
RDC_SEMAPHORE_Type *semaphore;
if (*pdap < 64)
semaphore = RDC_SEMAPHORE1;
else
{
semaphore = RDC_SEMAPHORE2;
*pdap -= 64;
}
return semaphore;
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_TryLock
* Description : Lock RDC semaphore for shared peripheral access
*
*END**************************************************************************/
rdc_semaphore_status_t RDC_SEMAPHORE_TryLock(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
semaphore = RDC_SEMAPHORE_GetGate(&index);
semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1);
return ((semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) ==
RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1)) ?
statusRdcSemaphoreSuccess : statusRdcSemaphoreBusy;
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_Lock
* Description : Lock RDC semaphore for shared peripheral access, polling until
* success.
*
*END**************************************************************************/
void RDC_SEMAPHORE_Lock(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
semaphore = RDC_SEMAPHORE_GetGate(&index);
do {
/* Wait gate status free */
while (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) { }
semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1);
} while ((semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) !=
RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1));
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_Unlock
* Description : Unlock RDC semaphore
*
*END**************************************************************************/
void RDC_SEMAPHORE_Unlock(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
semaphore = RDC_SEMAPHORE_GetGate(&index);
semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(0);
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_GetLockDomainID
* Description : Get domain ID which locks the semaphore
*
*END**************************************************************************/
uint32_t RDC_SEMAPHORE_GetLockDomainID(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
semaphore = RDC_SEMAPHORE_GetGate(&index);
return (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_LDOM_MASK) >> RDC_SEMAPHORE_GATE_LDOM_SHIFT;
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_GetLockMaster
* Description : Get master index which locks the semaphore
*
*END**************************************************************************/
uint32_t RDC_SEMAPHORE_GetLockMaster(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
uint8_t master;
semaphore = RDC_SEMAPHORE_GetGate(&index);
master = (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) >> RDC_SEMAPHORE_GATE_GTFSM_SHIFT;
return master == 0 ? RDC_SEMAPHORE_MASTER_NONE : master - 1;
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_Reset
* Description : Reset RDC semaphore to unlocked status
*
*END**************************************************************************/
void RDC_SEMAPHORE_Reset(uint32_t pdap)
{
RDC_SEMAPHORE_Type *semaphore;
uint32_t index = pdap;
semaphore = RDC_SEMAPHORE_GetGate(&index);
/* The reset state machine must be in idle state */
assert ((semaphore->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK) == 0);
semaphore->RSTGT_W = 0xE2;
semaphore->RSTGT_W = 0x1D | RDC_SEMAPHORE_RSTGT_W_RSTGTN(index);
}
/*FUNCTION**********************************************************************
*
* Function Name : RDC_SEMAPHORE_ResetAll
* Description : Reset all RDC semaphores to unlocked status for certain
* RDC_SEMAPHORE instance
*
*END**************************************************************************/
void RDC_SEMAPHORE_ResetAll(RDC_SEMAPHORE_Type *base)
{
/* The reset state machine must be in idle state */
assert ((base->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK) == 0);
base->RSTGT_W = 0xE2;
base->RSTGT_W = 0x1D | RDC_SEMAPHORE_RSTGT_W_RSTGTN_MASK;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __RDC_SEMAPHORE_H__
#define __RDC_SEMAPHORE_H__
#include <stdint.h>
#include <stdbool.h>
#include "device_imx.h"
/*!
* @addtogroup rdc_semaphore_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define RDC_SEMAPHORE_MASTER_NONE (0xFF)
/*! @brief RDC Semaphore status return codes. */
typedef enum _rdc_semaphore_status
{
statusRdcSemaphoreSuccess = 0U, /*!< Success. */
statusRdcSemaphoreBusy = 1U, /*!< RDC semaphore has been locked by other processor. */
} rdc_semaphore_status_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name RDC_SEMAPHORE State Control
* @{
*/
/*!
* @brief Lock RDC semaphore for shared peripheral access
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @retval statusRdcSemaphoreSuccess Lock the semaphore successfully.
* @retval statusRdcSemaphoreBusy Semaphore has been locked by other processor.
*/
rdc_semaphore_status_t RDC_SEMAPHORE_TryLock(uint32_t pdap);
/*!
* @brief Lock RDC semaphore for shared peripheral access, polling until success.
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
*/
void RDC_SEMAPHORE_Lock(uint32_t pdap);
/*!
* @brief Unlock RDC semaphore
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
*/
void RDC_SEMAPHORE_Unlock(uint32_t pdap);
/*!
* @brief Get domain ID which locks the semaphore
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @return domain ID which locks the RDC semaphore
*/
uint32_t RDC_SEMAPHORE_GetLockDomainID(uint32_t pdap);
/*!
* @brief Get master index which locks the semaphore
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
* @return master index which locks the RDC semaphore, or RDC_SEMAPHORE_MASTER_NONE
* to indicate it is not locked.
*/
uint32_t RDC_SEMAPHORE_GetLockMaster(uint32_t pdap);
/*@}*/
/*!
* @name RDC_SEMAPHORE Reset Control
* @{
*/
/*!
* @brief Reset RDC semaphore to unlocked status
*
* @param pdap RDC peripheral assignment (see @ref _rdc_pdap in rdc_defs_<device>.h)
*/
void RDC_SEMAPHORE_Reset(uint32_t pdap);
/*!
* @brief Reset all RDC semaphore to unlocked status for certain RDC_SEMAPHORE instance
*
* @param base RDC semaphore base pointer.
*/
void RDC_SEMAPHORE_ResetAll(RDC_SEMAPHORE_Type *base);
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __RDC_SEMAPHORE_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,199 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assert.h>
#include "sema4.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_TryLock
* Description : Lock SEMA4 gate for exclusive access between multicore
*
*END**************************************************************************/
sema4_status_t SEMA4_TryLock(SEMA4_Type *base, uint32_t gateIndex)
{
__IO uint8_t *gate;
assert(gateIndex < 16);
gate = &base->GATE00 + gateIndex;
*gate = SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1);
return ((*gate & SEMA4_GATE00_GTFSM_MASK) == SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1)) ?
statusSema4Success : statusSema4Busy;
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_Lock
* Description : Lock SEMA4 gate for exclusive access between multicore,
* polling until success
*
*END**************************************************************************/
void SEMA4_Lock(SEMA4_Type *base, uint32_t gateIndex)
{
__IO uint8_t *gate;
assert(gateIndex < 16);
gate = &base->GATE00 + gateIndex;
do {
/* Wait gate status free */
while (*gate & SEMA4_GATE00_GTFSM_MASK) { }
*gate = SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1);
} while ((*gate & SEMA4_GATE00_GTFSM_MASK) != SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1));
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_Unlock
* Description : Unlock SEMA4 gate
*
*END**************************************************************************/
void SEMA4_Unlock(SEMA4_Type *base, uint32_t gateIndex)
{
__IO uint8_t *gate;
assert(gateIndex < 16);
gate = &base->GATE00 + gateIndex;
*gate = SEMA4_GATE00_GTFSM(0);
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_GetLockProcessor
* Description : Get master index which locks the semaphore
*
*END**************************************************************************/
uint32_t SEMA4_GetLockProcessor(SEMA4_Type *base, uint32_t gateIndex)
{
__IO uint8_t *gate;
uint8_t proc;
assert(gateIndex < 16);
gate = &base->GATE00 + gateIndex;
proc = (*gate & SEMA4_GATE00_GTFSM_MASK) >> SEMA4_GATE00_GTFSM_SHIFT;
return proc == 0 ? SEMA4_PROCESSOR_NONE : proc - 1;
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_ResetGate
* Description : Reset SEMA4 gate to unlocked status
*
*END**************************************************************************/
void SEMA4_ResetGate(SEMA4_Type *base, uint32_t gateIndex)
{
assert(gateIndex < 16);
/* The reset state machine must be in idle state */
assert ((base->RSTGT & 0x30) == 0);
base->RSTGT = 0xE2;
base->RSTGT = 0x1D | SEMA4_RSTGT_RSTGTN(gateIndex);
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_ResetAllGates
* Description : Reset all SEMA4 gates to unlocked status for certain
* SEMA4 instance
*
*END**************************************************************************/
void SEMA4_ResetAllGates(SEMA4_Type *base)
{
/* The reset state machine must be in idle state */
assert ((base->RSTGT & 0x30) == 0);
base->RSTGT = 0xE2;
base->RSTGT = 0x1D | SEMA4_RSTGT_RSTGTN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_ResetNotification
* Description : Reset SEMA4 IRQ notifications
*
*END**************************************************************************/
void SEMA4_ResetNotification(SEMA4_Type *base, uint32_t gateIndex)
{
assert(gateIndex < 16);
/* The reset state machine must be in idle state */
assert ((base->RSTNTF & 0x30) == 0);
base->RSTNTF = 0x47;
base->RSTNTF = 0xB8 | SEMA4_RSTNTF_RSTNTN(gateIndex);
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_ResetAllNotifications
* Description : Reset all SEMA4 gates to unlocked status for certain
* SEMA4 instance
*
*END**************************************************************************/
void SEMA4_ResetAllNotifications(SEMA4_Type *base)
{
/* The reset state machine must be in idle state */
assert ((base->RSTNTF & 0x30) == 0);
base->RSTNTF = 0x47;
base->RSTNTF = 0xB8 | SEMA4_RSTNTF_RSTNTN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : SEMA4_SetIntCmd
* Description : Enable or disable SEMA4 IRQ notification.
*
*END**************************************************************************/
void SEMA4_SetIntCmd(SEMA4_Type * base, uint16_t intMask, bool enable)
{
if (enable)
base->CPnINE[SEMA4_PROCESSOR_SELF].INE |= intMask;
else
base->CPnINE[SEMA4_PROCESSOR_SELF].INE &= ~intMask;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,278 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SEMA4_H__
#define __SEMA4_H__
#include <stdint.h>
#include <stdbool.h>
#include "device_imx.h"
/*!
* @addtogroup sema4_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#define SEMA4_PROCESSOR_NONE (0xFF)
#define SEMA4_GATE_STATUS_FLAG(gate) ((uint16_t)(1U << ((gate) ^ 7)))
/*! @brief Status flag. */
enum _sema4_status_flag
{
sema4StatusFlagGate0 = 1U << 7, /*!< Sema4 Gate 0 flag. */
sema4StatusFlagGate1 = 1U << 6, /*!< Sema4 Gate 1 flag. */
sema4StatusFlagGate2 = 1U << 5, /*!< Sema4 Gate 2 flag. */
sema4StatusFlagGate3 = 1U << 4, /*!< Sema4 Gate 3 flag. */
sema4StatusFlagGate4 = 1U << 3, /*!< Sema4 Gate 4 flag. */
sema4StatusFlagGate5 = 1U << 2, /*!< Sema4 Gate 5 flag. */
sema4StatusFlagGate6 = 1U << 1, /*!< Sema4 Gate 6 flag. */
sema4StatusFlagGate7 = 1U << 0, /*!< Sema4 Gate 7 flag. */
sema4StatusFlagGate8 = 1U << 15, /*!< Sema4 Gate 8 flag. */
sema4StatusFlagGate9 = 1U << 14, /*!< Sema4 Gate 9 flag. */
sema4StatusFlagGate10 = 1U << 13, /*!< Sema4 Gate 10 flag. */
sema4StatusFlagGate11 = 1U << 12, /*!< Sema4 Gate 11 flag. */
sema4StatusFlagGate12 = 1U << 11, /*!< Sema4 Gate 12 flag. */
sema4StatusFlagGate13 = 1U << 10, /*!< Sema4 Gate 13 flag. */
sema4StatusFlagGate14 = 1U << 9, /*!< Sema4 Gate 14 flag. */
sema4StatusFlagGate15 = 1U << 8, /*!< Sema4 Gate 15 flag. */
};
/*! @brief SEMA4 reset finite state machine. */
enum _sema4_reset_state
{
sema4ResetIdle = 0U, /*!< Idle, waiting for the first data pattern write. */
sema4ResetMid = 1U, /*!< Waiting for the second data pattern write. */
sema4ResetFinished = 2U, /*!< Reset completed. Software can't get this state. */
};
/*! @brief SEMA4 status return codes. */
typedef enum _sema4_status
{
statusSema4Success = 0U, /*!< Success. */
statusSema4Busy = 1U, /*!< SEMA4 gate has been locked by other processor. */
} sema4_status_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name SEMA4 State Control
* @{
*/
/*!
* @brief Lock SEMA4 gate for exclusive access between multicore.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
* @retval statusSema4Success Lock the gate successfully.
* @retval statusSema4Busy SEMA4 gate has been locked by other processor.
*/
sema4_status_t SEMA4_TryLock(SEMA4_Type *base, uint32_t gateIndex);
/*!
* @brief Lock SEMA4 gate for exclusive access between multicore, polling until success.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
*/
void SEMA4_Lock(SEMA4_Type *base, uint32_t gateIndex);
/*!
* @brief Unlock SEMA4 gate.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
*/
void SEMA4_Unlock(SEMA4_Type *base, uint32_t gateIndex);
/*!
* @brief Get processor number which locks the SEMA4 gate.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
* @return processor number which locks the SEMA4 gate, or SEMA4_PROCESSOR_NONE
* to indicate the gate is not locked.
*/
uint32_t SEMA4_GetLockProcessor(SEMA4_Type *base, uint32_t gateIndex);
/*@}*/
/*!
* @name SEMA4 Reset Control
* @{
*/
/*!
* @brief Reset SEMA4 gate to unlocked status.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
*/
void SEMA4_ResetGate(SEMA4_Type *base, uint32_t gateIndex);
/*!
* @brief Reset all SEMA4 gates to unlocked status.
*
* @param base SEMA4 base pointer.
*/
void SEMA4_ResetAllGates(SEMA4_Type *base);
/*!
* @brief Get bus master number which performing the gate reset function.
* This function gets the bus master number which performing the
* gate reset function.
*
* @param base SEMA4 base pointer.
* @return Bus master number.
*/
static inline uint8_t SEMA4_GetGateResetBus(SEMA4_Type *base)
{
return (uint8_t)(base->RSTGT & 7);
}
/*!
* @brief Get sema4 gate reset state.
* This function gets current state of the sema4 reset gate finite
* state machine.
*
* @param base SEMA4 base pointer.
* @return Current state (see @ref _sema4_reset_state).
*/
static inline uint8_t SEMA4_GetGateResetState(SEMA4_Type *base)
{
return (uint8_t)((base->RSTGT & 0x30) >> 4);
}
/*!
* @brief Reset SEMA4 IRQ notification.
*
* @param base SEMA4 base pointer.
* @param gateIndex SEMA4 gate index.
*/
void SEMA4_ResetNotification(SEMA4_Type *base, uint32_t gateIndex);
/*!
* @brief Reset all IRQ notifications.
*
* @param base SEMA4 base pointer.
*/
void SEMA4_ResetAllNotifications(SEMA4_Type *base);
/*!
* @brief Get bus master number which performing the notification reset function.
* This function gets the bus master number which performing the notification
* reset function.
*
* @param base SEMA4 base pointer.
* @return Bus master number.
*/
static inline uint8_t SEMA4_GetNotificationResetBus(SEMA4_Type *base)
{
return (uint8_t)(base->RSTNTF & 7);
}
/*!
* @brief Get sema4 notification reset state.
*
* This function gets current state of the sema4 reset notification finite state machine.
*
* @param base SEMA4 base pointer.
* @return Current state (See @ref _sema4_reset_state).
*/
static inline uint8_t SEMA4_GetNotificationResetState(SEMA4_Type *base)
{
return (uint8_t)((base->RSTNTF & 0x30) >> 4);
}
/*@}*/
/*!
* @name SEMA4 Interrupt and Status Control
* @{
*/
/*!
* @brief Get SEMA4 notification status.
*
* @param base SEMA4 base pointer.
* @param flags SEMA4 gate status mask (See @ref _sema4_status_flag).
* @return SEMA4 notification status bits. If bit value is set, the corresponding
* gate's notification is available.
*/
static inline uint16_t SEMA4_GetStatusFlag(SEMA4_Type * base, uint16_t flags)
{
return base->CPnNTF[SEMA4_PROCESSOR_SELF].NTF & flags;
}
/*!
* @brief Enable or disable SEMA4 IRQ notification.
*
* @param base SEMA4 base pointer.
* @param intMask SEMA4 gate status mask (see @ref _sema4_status_flag).
* @param enable Enable/Disable Sema4 interrupt, only those gates whose intMask is set are affected.
* - true: Enable Sema4 interrupt.
* - false: Disable Sema4 interrupt.
*/
void SEMA4_SetIntCmd(SEMA4_Type * base, uint16_t intMask, bool enable);
/*!
* @brief check whether SEMA4 IRQ notification enabled.
*
* @param base SEMA4 base pointer.
* @param flags SEMA4 gate status mask (see @ref _sema4_status_flag).
* @return SEMA4 notification interrupt enable status bits. If bit value is set,
* the corresponding gate's notification is enabled
*/
static inline uint16_t SEMA4_GetIntEnabled(SEMA4_Type * base, uint16_t flags)
{
return base->CPnINE[SEMA4_PROCESSOR_SELF].INE & flags;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __SEMA4_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,612 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "uart_imx.h"
/*******************************************************************************
* Code
******************************************************************************/
/*******************************************************************************
* Initialization and Configuration functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_Init
* Description : This function initializes the module according to uart
* initialize structure.
*
*END**************************************************************************/
void UART_Init(UART_Type* base, const uart_init_config_t* initConfig)
{
assert(initConfig);
/* Disable UART Module. */
UART_UCR1_REG(base) &= ~UART_UCR1_UARTEN_MASK;
/* Reset UART register to its default value. */
UART_Deinit(base);
/* Set UART data word length, stop bit count, parity mode and communication
* direction according to uart init struct, disable RTS hardware flow
* control. */
UART_UCR2_REG(base) |= (initConfig->wordLength |
initConfig->stopBitNum |
initConfig->parity |
initConfig->direction |
UART_UCR2_IRTS_MASK);
/* For imx family device, UARTs are used in MUXED mode,
* so that this bit should always be set.*/
UART_UCR3_REG(base) |= UART_UCR3_RXDMUXSEL_MASK;
/* Set BaudRate according to uart initialize struct. */
/* Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)) */
UART_SetBaudRate(base, initConfig->clockRate, initConfig->baudRate);
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_Deinit
* Description : This function reset Uart module register content to its
* default value.
*
*END**************************************************************************/
void UART_Deinit(UART_Type* base)
{
/* Disable UART Module */
UART_UCR1_REG(base) &= ~UART_UCR1_UARTEN_MASK;
/* Reset UART Module Register content to default value */
UART_UCR1_REG(base) = 0x0;
UART_UCR2_REG(base) = UART_UCR2_SRST_MASK;
UART_UCR3_REG(base) = UART_UCR3_DSR_MASK |
UART_UCR3_DCD_MASK |
UART_UCR3_RI_MASK;
UART_UCR4_REG(base) = UART_UCR4_CTSTL(32);
UART_UFCR_REG(base) = UART_UFCR_TXTL(2) | UART_UFCR_RXTL(1);
UART_UESC_REG(base) = UART_UESC_ESC_CHAR(0x2B);
UART_UTIM_REG(base) = 0x0;
UART_ONEMS_REG(base) = 0x0;
UART_UTS_REG(base) = UART_UTS_TXEMPTY_MASK | UART_UTS_RXEMPTY_MASK;
UART_UMCR_REG(base) = 0x0;
/* Reset the transmit and receive state machines, all FIFOs and register
* USR1, USR2, UBIR, UBMR, UBRC, URXD, UTXD and UTS[6-3]. */
UART_UCR2_REG(base) &= ~UART_UCR2_SRST_MASK;
while (!(UART_UCR2_REG(base) & UART_UCR2_SRST_MASK));
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetBaudRate
* Description :
*
*END**************************************************************************/
void UART_SetBaudRate(UART_Type* base, uint32_t clockRate, uint32_t baudRate)
{
uint32_t numerator;
uint32_t denominator;
uint32_t divisor;
uint32_t refFreqDiv;
uint32_t divider = 1;
/* get the approximately maximum divisor */
numerator = clockRate;
denominator = baudRate << 4;
divisor = 1;
while (denominator != 0)
{
divisor = denominator;
denominator = numerator % denominator;
numerator = divisor;
}
numerator = clockRate / divisor;
denominator = (baudRate << 4) / divisor;
/* numerator ranges from 1 ~ 7 * 64k */
/* denominator ranges from 1 ~ 64k */
if ((numerator > (UART_UBIR_INC_MASK * 7)) ||
(denominator > UART_UBIR_INC_MASK))
{
uint32_t m = (numerator - 1) / (UART_UBIR_INC_MASK * 7) + 1;
uint32_t n = (denominator - 1) / UART_UBIR_INC_MASK + 1;
uint32_t max = m > n ? m : n;
numerator /= max;
denominator /= max;
if (0 == numerator)
numerator = 1;
if (0 == denominator)
denominator = 1;
}
divider = (numerator - 1) / UART_UBIR_INC_MASK + 1;
switch (divider)
{
case 1:
refFreqDiv = 0x05;
break;
case 2:
refFreqDiv = 0x04;
break;
case 3:
refFreqDiv = 0x03;
break;
case 4:
refFreqDiv = 0x02;
break;
case 5:
refFreqDiv = 0x01;
break;
case 6:
refFreqDiv = 0x00;
break;
case 7:
refFreqDiv = 0x06;
break;
default:
refFreqDiv = 0x05;
}
UART_UFCR_REG(base) &= ~UART_UFCR_RFDIV_MASK;
UART_UFCR_REG(base) |= UART_UFCR_RFDIV(refFreqDiv);
UART_UBIR_REG(base) = UART_UBIR_INC(denominator - 1);
UART_UBMR_REG(base) = UART_UBMR_MOD(numerator / divider - 1);
UART_ONEMS_REG(base) = UART_ONEMS_ONEMS(clockRate/(1000 * divider));
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetInvertCmd
* Description : This function is used to set the polarity of UART signal.
* The polarity of Tx and Rx can be set separately.
*
*END**************************************************************************/
void UART_SetInvertCmd(UART_Type* base, uint32_t direction, bool invert)
{
assert((direction & uartDirectionTx) || (direction & uartDirectionRx));
if (invert)
{
if (direction & UART_UCR2_RXEN_MASK)
UART_UCR4_REG(base) |= UART_UCR4_INVR_MASK;
if (direction & UART_UCR2_TXEN_MASK)
UART_UCR3_REG(base) |= UART_UCR3_INVT_MASK;
}
else
{
if (direction & UART_UCR2_RXEN_MASK)
UART_UCR4_REG(base) &= ~UART_UCR4_INVR_MASK;
if (direction & UART_UCR2_TXEN_MASK)
UART_UCR3_REG(base) &= ~UART_UCR3_INVT_MASK;
}
}
/*******************************************************************************
* Low Power Mode functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetDozeMode
* Description : This function is used to set UART enable condition in the
* DOZE state.
*
*END**************************************************************************/
void UART_SetDozeMode(UART_Type* base, bool enable)
{
if (enable)
UART_UCR1_REG(base) &= UART_UCR1_DOZE_MASK;
else
UART_UCR1_REG(base) |= ~UART_UCR1_DOZE_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetLowPowerMode
* Description : This function is used to set UART enable condition of the
* UART low power feature.
*
*END**************************************************************************/
void UART_SetLowPowerMode(UART_Type* base, bool enable)
{
if (enable)
UART_UCR4_REG(base) &= ~UART_UCR4_LPBYP_MASK;
else
UART_UCR4_REG(base) |= UART_UCR4_LPBYP_MASK;
}
/*******************************************************************************
* Interrupt and Flag control functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetIntCmd
* Description : This function is used to set the enable condition of
* specific UART interrupt source. The available interrupt
* source can be select from uart_int_source enumeration.
*
*END**************************************************************************/
void UART_SetIntCmd(UART_Type* base, uint32_t intSource, bool enable)
{
volatile uint32_t* uart_reg = 0;
uint32_t uart_mask = 0;
uart_reg = (uint32_t *)((uint32_t)base + (intSource >> 16));
uart_mask = (1 << (intSource & 0x0000FFFF));
if (enable)
*uart_reg |= uart_mask;
else
*uart_reg &= ~uart_mask;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_GetStatusFlag
* Description : This function is used to get the current status of specific
* UART status flag. The available status flag can be select
* from uart_status_flag & uart_interrupt_flag enumeration.
*
*END**************************************************************************/
/*
bool UART_GetStatusFlag(UART_Type* base, uint32_t flag)
{
volatile uint32_t* uart_reg = 0;
uart_reg = (uint32_t *)((uint32_t)base + (flag >> 16));
return (bool)((*uart_reg >> (flag & 0x0000FFFF)) & 0x1);
}
*/
/*FUNCTION**********************************************************************
*
* Function Name : UART_ClearStatusFlag
* Description : This function is used to get the current status
* of specific UART status flag. The available status
* flag can be select from uart_status_flag &
* uart_interrupt_flag enumeration.
*
*END**************************************************************************/
void UART_ClearStatusFlag(UART_Type* base, uint32_t flag)
{
volatile uint32_t* uart_reg = 0;
uint32_t uart_mask = 0;
uart_reg = (uint32_t *)((uint32_t)base + (flag >> 16));
uart_mask = (1 << (flag & 0x0000FFFF));
/* write 1 to clear. */
*uart_reg = uart_mask;
}
/*******************************************************************************
* DMA control functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetDmaCmd
* Description : This function is used to set the enable condition of
* specific UART DMA source. The available DMA
* source can be select from uart_dma_source enumeration.
*
*END**************************************************************************/
void UART_SetDmaCmd(UART_Type* base, uint32_t dmaSource, bool enable)
{
volatile uint32_t* uart_reg = 0;
uint32_t uart_mask = 0;
uart_reg = (uint32_t *)((uint32_t)base + (dmaSource >> 16));
uart_mask = (1 << (dmaSource & 0x0000FFFF));
if (enable)
*uart_reg |= uart_mask;
else
*uart_reg &= ~uart_mask;
}
/*******************************************************************************
* Hardware Flow control and Modem Signal functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetRtsFlowCtrlCmd
* Description : This function is used to set the enable condition of RTS
* Hardware flow control.
*
*END**************************************************************************/
void UART_SetRtsFlowCtrlCmd(UART_Type* base, bool enable)
{
if (enable)
UART_UCR2_REG(base) &= ~UART_UCR2_IRTS_MASK;
else
UART_UCR2_REG(base) |= UART_UCR2_IRTS_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetCtsFlowCtrlCmd
* Description : This function is used to set the enable condition of CTS
* auto control. if CTS control is enabled, the CTS_B pin will
* be controlled by the receiver, otherwise the CTS_B pin will
* controlled by UART_CTSPinCtrl function.
*
*END**************************************************************************/
void UART_SetCtsFlowCtrlCmd(UART_Type* base, bool enable)
{
if (enable)
UART_UCR2_REG(base) |= UART_UCR2_CTSC_MASK;
else
UART_UCR2_REG(base) &= ~UART_UCR2_CTSC_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetCtsPinLevel
* Description : This function is used to control the CTS_B pin state when
* auto CTS control is disabled.
* The CTS_B pin is low (active)
* The CTS_B pin is high (inactive)
*
*END**************************************************************************/
void UART_SetCtsPinLevel(UART_Type* base, bool active)
{
if (active)
UART_UCR2_REG(base) |= UART_UCR2_CTS_MASK;
else
UART_UCR2_REG(base) &= ~UART_UCR2_CTS_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetModemMode
* Description : This function is used to set the role(DTE/DCE) of UART module
* in RS-232 communication.
*
*END**************************************************************************/
void UART_SetModemMode(UART_Type* base, uint32_t mode)
{
assert((mode == uartModemModeDce) || (mode == uartModemModeDte));
if (uartModemModeDce == mode)
UART_UFCR_REG(base) &= ~UART_UFCR_DCEDTE_MASK;
else
UART_UFCR_REG(base) |= UART_UFCR_DCEDTE_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetDtrPinLevel
* Description : This function is used to set the pin state of
* DSR pin(for DCE mode) or DTR pin(for DTE mode) for the
* modem interface.
*
*END**************************************************************************/
void UART_SetDtrPinLevel(UART_Type* base, bool active)
{
if (active)
UART_UCR3_REG(base) |= UART_UCR3_DSR_MASK;
else
UART_UCR3_REG(base) &= ~UART_UCR3_DSR_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetDcdPinLevel
* Description : This function is used to set the pin state of
* DCD pin. THIS FUNCTION IS FOR DCE MODE ONLY.
*
*END**************************************************************************/
void UART_SetDcdPinLevel(UART_Type* base, bool active)
{
if (active)
UART_UCR3_REG(base) |= UART_UCR3_DCD_MASK;
else
UART_UCR3_REG(base) &= ~UART_UCR3_DCD_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetRiPinLevel
* Description : This function is used to set the pin state of
* RI pin. THIS FUNCTION IS FOR DCE MODE ONLY.
*
*END**************************************************************************/
void UART_SetRiPinLevel(UART_Type* base, bool active)
{
if (active)
UART_UCR3_REG(base) |= UART_UCR3_RI_MASK;
else
UART_UCR3_REG(base) &= ~UART_UCR3_RI_MASK;
}
/*******************************************************************************
* Multiprocessor and RS-485 functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_Putchar9
* Description : This function is used to send 9 Bits length data in
* RS-485 Multidrop mode.
*
*END**************************************************************************/
void UART_Putchar9(UART_Type* base, uint16_t data)
{
assert(data <= 0x1FF);
if (data & 0x0100)
UART_UMCR_REG(base) |= UART_UMCR_TXB8_MASK;
else
UART_UMCR_REG(base) &= ~UART_UMCR_TXB8_MASK;
UART_UTXD_REG(base) = (data & UART_UTXD_TX_DATA_MASK);
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_Getchar9
* Description : This functions is used to receive 9 Bits length data in
* RS-485 Multidrop mode.
*
*END**************************************************************************/
uint16_t UART_Getchar9(UART_Type* base)
{
uint16_t rxData = UART_URXD_REG(base);
if (rxData & UART_URXD_PRERR_MASK)
{
rxData = (rxData & 0x00FF) | 0x0100;
}
else
{
rxData &= 0x00FF;
}
return rxData;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetMultidropMode
* Description : This function is used to set the enable condition of
* 9-Bits data or Multidrop mode.
*
*END**************************************************************************/
void UART_SetMultidropMode(UART_Type* base, bool enable)
{
if (enable)
UART_UMCR_REG(base) |= UART_UMCR_MDEN_MASK;
else
UART_UMCR_REG(base) &= ~UART_UMCR_MDEN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetSlaveAddressDetectCmd
* Description : This function is used to set the enable condition of
* Automatic Address Detect Mode.
*
*END**************************************************************************/
void UART_SetSlaveAddressDetectCmd(UART_Type* base, bool enable)
{
if (enable)
UART_UMCR_REG(base) |= UART_UMCR_SLAM_MASK;
else
UART_UMCR_REG(base) &= ~UART_UMCR_SLAM_MASK;
}
/*******************************************************************************
* IrDA control functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetIrDACmd
* Description : This function is used to set the enable condition of
* IrDA Mode.
*
*END**************************************************************************/
void UART_SetIrDACmd(UART_Type* base, bool enable)
{
if (enable)
UART_UCR1_REG(base) |= UART_UCR1_IREN_MASK;
else
UART_UCR1_REG(base) &= ~UART_UCR1_IREN_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetIrDAVoteClock
* Description : This function is used to set the clock for the IR pulsed
* vote logic. The available clock can be select from
* uart_irda_vote_clock enumeration.
*
*END**************************************************************************/
void UART_SetIrDAVoteClock(UART_Type* base, uint32_t voteClock)
{
assert((voteClock == uartIrdaVoteClockSampling) || \
(voteClock == uartIrdaVoteClockReference));
if (uartIrdaVoteClockSampling == voteClock)
UART_UCR4_REG(base) |= UART_UCR4_IRSC_MASK;
else
UART_UCR4_REG(base) &= ~UART_UCR4_IRSC_MASK;
}
/*******************************************************************************
* Misc. functions
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetAutoBaudRateCmd
* Description : This function is used to set the enable condition of
* Automatic Baud Rate Detection feature.
*
*END**************************************************************************/
void UART_SetAutoBaudRateCmd(UART_Type* base, bool enable)
{
if (enable)
UART_UCR1_REG(base) |= UART_UCR1_ADBR_MASK;
else
UART_UCR1_REG(base) &= ~UART_UCR1_ADBR_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SendBreakChar
* Description : This function is used to send BREAK character.It is
* important that SNDBRK is asserted high for a sufficient
* period of time to generate a valid BREAK.
*
*END**************************************************************************/
void UART_SendBreakChar(UART_Type* base, bool active)
{
if (active)
UART_UCR1_REG(base) |= UART_UCR1_SNDBRK_MASK;
else
UART_UCR1_REG(base) &= ~UART_UCR1_SNDBRK_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : UART_SetEscapeDecectCmd
* Description : This function is used to set the enable condition of
* Escape Sequence Detection feature.
*
*END**************************************************************************/
void UART_SetEscapeDecectCmd(UART_Type* base, bool enable)
{
if (enable)
UART_UCR2_REG(base) |= UART_UCR2_ESCEN_MASK;
else
UART_UCR2_REG(base) &= ~UART_UCR2_ESCEN_MASK;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,779 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __UART_IMX_H__
#define __UART_IMX_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup uart_imx_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief Uart module initialization structure. */
typedef struct _uart_init_config
{
uint32_t clockRate; /*!< Current UART module clock freq. */
uint32_t baudRate; /*!< Desired UART baud rate. */
uint32_t wordLength; /*!< Data bits in one frame. */
uint32_t stopBitNum; /*!< Number of stop bits in one frame. */
uint32_t parity; /*!< Parity error check mode of this module. */
uint32_t direction; /*!< Data transfer direction of this module. */
} uart_init_config_t;
/*! @brief UART number of data bits in a character. */
enum _uart_word_length
{
uartWordLength7Bits = 0x0, /*!< One character has 7 bits. */
uartWordLength8Bits = UART_UCR2_WS_MASK, /*!< One character has 8 bits. */
};
/*! @brief UART number of stop bits. */
enum _uart_stop_bit_num
{
uartStopBitNumOne = 0x0, /*!< One bit Stop. */
uartStopBitNumTwo = UART_UCR2_STPB_MASK, /*!< Two bits Stop. */
};
/*! @brief UART parity mode. */
enum _uart_partity_mode
{
uartParityDisable = 0x0, /*!< Parity error check disabled. */
uartParityEven = UART_UCR2_PREN_MASK, /*!< Even error check is selected. */
uartParityOdd = UART_UCR2_PREN_MASK | UART_UCR2_PROE_MASK, /*!< Odd error check is selected. */
};
/*! @brief Data transfer direction. */
enum _uart_direction_mode
{
uartDirectionDisable = 0x0, /*!< Both Tx and Rx are disabled. */
uartDirectionTx = UART_UCR2_TXEN_MASK, /*!< Tx is enabled. */
uartDirectionRx = UART_UCR2_RXEN_MASK, /*!< Rx is enabled. */
uartDirectionTxRx = UART_UCR2_TXEN_MASK | UART_UCR2_RXEN_MASK, /*!< Both Tx and Rx are enabled. */
};
/*! @brief This enumeration contains the settings for all of the UART interrupt configurations. */
enum _uart_interrupt
{
uartIntAutoBaud = 0x0080000F, /*!< Automatic baud rate detection Interrupt Enable. */
uartIntTxReady = 0x0080000D, /*!< transmitter ready Interrupt Enable. */
uartIntIdle = 0x0080000C, /*!< IDLE Interrupt Enable. */
uartIntRxReady = 0x00800009, /*!< Receiver Ready Interrupt Enable. */
uartIntTxEmpty = 0x00800006, /*!< Transmitter Empty Interrupt Enable. */
uartIntRtsDelta = 0x00800005, /*!< RTS Delta Interrupt Enable. */
uartIntEscape = 0x0084000F, /*!< Escape Sequence Interrupt Enable. */
uartIntRts = 0x00840004, /*!< Request to Send Interrupt Enable. */
uartIntAgingTimer = 0x00840003, /*!< Aging Timer Interrupt Enable. */
uartIntDtr = 0x0088000D, /*!< Data Terminal Ready Interrupt Enable. */
uartIntParityError = 0x0088000C, /*!< Parity Error Interrupt Enable. */
uartIntFrameError = 0x0088000B, /*!< Frame Error Interrupt Enable. */
uartIntDcd = 0x00880009, /*!< Data Carrier Detect Interrupt Enable. */
uartIntRi = 0x00880008, /*!< Ring Indicator Interrupt Enable. */
uartIntRxDs = 0x00880006, /*!< Receive Status Interrupt Enable. */
uartInttAirWake = 0x00880005, /*!< Asynchronous IR WAKE Interrupt Enable. */
uartIntAwake = 0x00880004, /*!< Asynchronous WAKE Interrupt Enable. */
uartIntDtrDelta = 0x00880003, /*!< Data Terminal Ready Delta Interrupt Enable. */
uartIntAutoBaudCnt = 0x00880000, /*!< Autobaud Counter Interrupt Enable. */
uartIntIr = 0x008C0008, /*!< Serial Infrared Interrupt Enable. */
uartIntWake = 0x008C0007, /*!< WAKE Interrupt Enable. */
uartIntTxComplete = 0x008C0003, /*!< TransmitComplete Interrupt Enable. */
uartIntBreakDetect = 0x008C0002, /*!< BREAK Condition Detected Interrupt Enable. */
uartIntRxOverrun = 0x008C0001, /*!< Receiver Overrun Interrupt Enable. */
uartIntRxDataReady = 0x008C0000, /*!< Receive Data Ready Interrupt Enable. */
uartIntRs485SlaveAddrMatch = 0x00B80003, /*!< RS-485 Slave Address Detected Interrupt Enable. */
};
/*! @brief Flag for UART interrupt/DMA status check or polling status. */
enum _uart_status_flag
{
uartStatusRxCharReady = 0x0000000F, /*!< Rx Character Ready Flag. */
uartStatusRxError = 0x0000000E, /*!< Rx Error Detect Flag. */
uartStatusRxOverrunError = 0x0000000D, /*!< Rx Overrun Flag. */
uartStatusRxFrameError = 0x0000000C, /*!< Rx Frame Error Flag. */
uartStatusRxBreakDetect = 0x0000000B, /*!< Rx Break Detect Flag. */
uartStatusRxParityError = 0x0000000A, /*!< Rx Parity Error Flag. */
uartStatusParityError = 0x0094000F, /*!< Parity Error Interrupt Flag. */
uartStatusRtsStatus = 0x0094000E, /*!< RTS_B Pin Status Flag. */
uartStatusTxReady = 0x0094000D, /*!< Transmitter Ready Interrupt/DMA Flag. */
uartStatusRtsDelta = 0x0094000C, /*!< RTS Delta Flag. */
uartStatusEscape = 0x0094000B, /*!< Escape Sequence Interrupt Flag. */
uartStatusFrameError = 0x0094000A, /*!< Frame Error Interrupt Flag. */
uartStatusRxReady = 0x00940009, /*!< Receiver Ready Interrupt/DMA Flag. */
uartStatusAgingTimer = 0x00940008, /*!< Ageing Timer Interrupt Flag. */
uartStatusDtrDelta = 0x00940007, /*!< DTR Delta Flag. */
uartStatusRxDs = 0x00940006, /*!< Receiver IDLE Interrupt Flag. */
uartStatustAirWake = 0x00940005, /*!< Asynchronous IR WAKE Interrupt Flag. */
uartStatusAwake = 0x00940004, /*!< Asynchronous WAKE Interrupt Flag. */
uartStatusRs485SlaveAddrMatch = 0x00940003, /*!< RS-485 Slave Address Detected Interrupt Flag. */
uartStatusAutoBaud = 0x0098000F, /*!< Automatic Baud Rate Detect Complete Flag. */
uartStatusTxEmpty = 0x0098000E, /*!< Transmit Buffer FIFO Empty. */
uartStatusDtr = 0x0098000D, /*!< DTR edge triggered interrupt flag. */
uartStatusIdle = 0x0098000C, /*!< Idle Condition Flag. */
uartStatusAutoBaudCntStop = 0x0098000B, /*!< Autobaud Counter Stopped Flag. */
uartStatusRiDelta = 0x0098000A, /*!< Ring Indicator Delta Flag. */
uartStatusRi = 0x00980009, /*!< Ring Indicator Input Flag. */
uartStatusIr = 0x00980008, /*!< Serial Infrared Interrupt Flag. */
uartStatusWake = 0x00980007, /*!< Wake Flag. */
uartStatusDcdDelta = 0x00980006, /*!< Data Carrier Detect Delta Flag. */
uartStatusDcd = 0x00980005, /*!< Data Carrier Detect Input Flag. */
uartStatusRts = 0x00980004, /*!< RTS Edge Triggered Interrupt Flag. */
uartStatusTxComplete = 0x00980003, /*!< Transmitter Complete Flag. */
uartStatusBreakDetect = 0x00980002, /*!< BREAK Condition Detected Flag. */
uartStatusRxOverrun = 0x00980001, /*!< Overrun Error Flag. */
uartStatusRxDataReady = 0x00980000, /*!< Receive Data Ready Flag. */
};
/*! @brief The events generate the DMA Request. */
enum _uart_dma
{
uartDmaRxReady = 0x00800008, /*!< Receive Ready DMA Enable. */
uartDmaTxReady = 0x00800003, /*!< Transmitter Ready DMA Enable. */
uartDmaAgingTimer = 0x00800002, /*!< Aging DMA Timer Enable. */
uartDmaIdle = 0x008C0006, /*!< DMA IDLE Condition Detected Interrupt Enable. */
};
/*! @brief RTS pin interrupt trigger edge. */
enum _uart_rts_int_trigger_edge
{
uartRtsTriggerEdgeRising = UART_UCR2_RTEC(0), /*!< RTS pin interrupt triggered on rising edge. */
uartRtsTriggerEdgeFalling = UART_UCR2_RTEC(1), /*!< RTS pin interrupt triggered on falling edge. */
uartRtsTriggerEdgeBoth = UART_UCR2_RTEC(2), /*!< RTS pin interrupt triggered on both edge. */
};
/*! @brief UART module modem role selections. */
enum _uart_modem_mode
{
uartModemModeDce = 0, /*!< UART module works as DCE. */
uartModemModeDte = UART_UFCR_DCEDTE_MASK, /*!< UART module works as DTE. */
};
/*! @brief DTR pin interrupt trigger edge. */
enum _uart_dtr_int_trigger_edge
{
uartDtrTriggerEdgeRising = UART_UCR3_DPEC(0), /*!< DTR pin interrupt triggered on rising edge. */
uartDtrTriggerEdgeFalling = UART_UCR3_DPEC(1), /*!< DTR pin interrupt triggered on falling edge. */
uartDtrTriggerEdgeBoth = UART_UCR3_DPEC(2), /*!< DTR pin interrupt triggered on both edge. */
};
/*! @brief IrDA vote clock selections. */
enum _uart_irda_vote_clock
{
uartIrdaVoteClockSampling = 0x0, /*!< The vote logic uses the sampling clock (16x baud rate) for normal operation. */
uartIrdaVoteClockReference = UART_UCR4_IRSC_MASK, /*!< The vote logic uses the UART reference clock. */
};
/*! @brief UART module Rx Idle condition selections. */
enum _uart_rx_idle_condition
{
uartRxIdleMoreThan4Frames = UART_UCR1_ICD(0), /*!< Idle for more than 4 frames. */
uartRxIdleMoreThan8Frames = UART_UCR1_ICD(1), /*!< Idle for more than 8 frames. */
uartRxIdleMoreThan16Frames = UART_UCR1_ICD(2), /*!< Idle for more than 16 frames. */
uartRxIdleMoreThan32Frames = UART_UCR1_ICD(3), /*!< Idle for more than 32 frames. */
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name UART Initialization and Configuration functions
* @{
*/
/*!
* @brief Initialize UART module with given initialization structure.
*
* @param base UART base pointer.
* @param initConfig UART initialization structure (see @ref uart_init_config_t structure above).
*/
void UART_Init(UART_Type* base, const uart_init_config_t* initConfig);
/*!
* @brief This function reset UART module register content to its default value.
*
* @param base UART base pointer.
*/
void UART_Deinit(UART_Type* base);
/*!
* @brief This function is used to Enable the UART Module.
*
* @param base UART base pointer.
*/
static inline void UART_Enable(UART_Type* base)
{
UART_UCR1_REG(base) |= UART_UCR1_UARTEN_MASK;
}
/*!
* @brief This function is used to Disable the UART Module.
*
* @param base UART base pointer.
*/
static inline void UART_Disable(UART_Type* base)
{
UART_UCR1_REG(base) &= ~UART_UCR1_UARTEN_MASK;
}
/*!
* @brief This function is used to set the baud rate of UART Module.
*
* @param base UART base pointer.
* @param clockRate UART module clock frequency.
* @param baudRate Desired UART module baud rate.
*/
void UART_SetBaudRate(UART_Type* base, uint32_t clockRate, uint32_t baudRate);
/*!
* @brief This function is used to set the transform direction of UART Module.
*
* @param base UART base pointer.
* @param direction UART transfer direction (see @ref _uart_direction_mode enumeration).
*/
static inline void UART_SetDirMode(UART_Type* base, uint32_t direction)
{
assert((direction & uartDirectionTx) || (direction & uartDirectionRx));
UART_UCR2_REG(base) = (UART_UCR2_REG(base) & ~(UART_UCR2_RXEN_MASK | UART_UCR2_TXEN_MASK)) | direction;
}
/*!
* @brief This function is used to set the number of frames RXD is allowed to
* be idle before an idle condition is reported. The available condition
* can be select from @ref _uart_idle_condition enumeration.
*
* @param base UART base pointer.
* @param idleCondition The condition that an idle condition is reported
* (see @ref _uart_idle_condition enumeration).
*/
static inline void UART_SetRxIdleCondition(UART_Type* base, uint32_t idleCondition)
{
assert(idleCondition <= uartRxIdleMoreThan32Frames);
UART_UCR1_REG(base) = (UART_UCR1_REG(base) & ~UART_UCR1_ICD_MASK) | idleCondition;
}
/*!
* @brief This function is used to set the polarity of UART signal. The polarity
* of Tx and Rx can be set separately.
*
* @param base UART base pointer.
* @param direction UART transfer direction (see @ref _uart_direction_mode enumeration).
* @param invert Set true to invert the polarity of UART signal.
*/
void UART_SetInvertCmd(UART_Type* base, uint32_t direction, bool invert);
/*@}*/
/*!
* @name Low Power Mode functions.
* @{
*/
/*!
* @brief This function is used to set UART enable condition in the DOZE state.
*
* @param base UART base pointer.
* @param enable Enable/Disable UART module in doze mode.
* - true: Enable UART module in doze mode.
* - false: Disable UART module in doze mode.
*/
void UART_SetDozeMode(UART_Type* base, bool enable);
/*!
* @brief This function is used to set UART enable condition of the UART low power feature.
*
* @param base UART base pointer.
* @param enable Enable/Disable UART module low power feature.
* - true: Enable UART module low power feature.
* - false: Disable UART module low power feature.
*/
void UART_SetLowPowerMode(UART_Type* base, bool enable);
/*@}*/
/*!
* @name Data transfer functions.
* @{
*/
/*!
* @brief This function is used to send data in RS-232 and IrDA Mode.
* A independent 9 Bits RS-485 send data function is provided.
*
* @param base UART base pointer.
* @param data Data to be set through UART module.
*/
static inline void UART_Putchar(UART_Type* base, uint8_t data)
{
UART_UTXD_REG(base) = (data & UART_UTXD_TX_DATA_MASK);
}
/*!
* @brief This function is used to receive data in RS-232 and IrDA Mode.
* A independent 9 Bits RS-485 receive data function is provided.
*
* @param base UART base pointer.
* @return The data received from UART module.
*/
static inline uint8_t UART_Getchar(UART_Type* base)
{
return (uint8_t)(UART_URXD_REG(base) & UART_URXD_RX_DATA_MASK);
}
/*@}*/
/*!
* @name Interrupt and Flag control functions.
* @{
*/
/*!
* @brief This function is used to set the enable condition of
* specific UART interrupt source. The available interrupt
* source can be select from @ref _uart_interrupt enumeration.
*
* @param base UART base pointer.
* @param intSource Available interrupt source for this module.
* @param enable Enable/Disable corresponding interrupt.
* - true: Enable corresponding interrupt.
* - false: Disable corresponding interrupt.
*/
void UART_SetIntCmd(UART_Type* base, uint32_t intSource, bool enable);
/*!
* @brief This function is used to get the current status of specific
* UART status flag(including interrupt flag). The available
* status flag can be select from @ref _uart_status_flag enumeration.
*
* @param base UART base pointer.
* @param flag Status flag to check.
* @return current state of corresponding status flag.
*/
static inline bool UART_GetStatusFlag(UART_Type* base, uint32_t flag){
volatile uint32_t* uart_reg = 0;
uart_reg = (uint32_t *)((uint32_t)base + (flag >> 16));
return (bool)((*uart_reg >> (flag & 0x0000FFFF)) & 0x1);
}
/*!
* @brief This function is used to get the current status
* of specific UART status flag. The available status
* flag can be select from @ref _uart_status_flag enumeration.
*
* @param base UART base pointer.
* @param flag Status flag to clear.
*/
void UART_ClearStatusFlag(UART_Type* base, uint32_t flag);
/*@}*/
/*!
* @name DMA control functions.
* @{
*/
/*!
* @brief This function is used to set the enable condition of
* specific UART DMA source. The available DMA source
* can be select from @ref _uart_dma enumeration.
*
* @param base UART base pointer.
* @param dmaSource The Event that can generate DMA request.
* @param enable Enable/Disable corresponding DMA source.
* - true: Enable corresponding DMA source.
* - false: Disable corresponding DMA source.
*/
void UART_SetDmaCmd(UART_Type* base, uint32_t dmaSource, bool enable);
/*@}*/
/*!
* @name FIFO control functions.
* @{
*/
/*!
* @brief This function is used to set the watermark of UART Tx FIFO.
* A maskable interrupt is generated whenever the data level in
* the TxFIFO falls below the Tx FIFO watermark.
*
* @param base UART base pointer.
* @param watermark The Tx FIFO watermark.
*/
static inline void UART_SetTxFifoWatermark(UART_Type* base, uint8_t watermark)
{
assert((watermark >= 2) && (watermark <= 32));
UART_UFCR_REG(base) = (UART_UFCR_REG(base) & ~UART_UFCR_TXTL_MASK) | UART_UFCR_TXTL(watermark);
}
/*!
* @brief This function is used to set the watermark of UART Rx FIFO.
* A maskable interrupt is generated whenever the data level in
* the RxFIFO reaches the Rx FIFO watermark.
*
* @param base UART base pointer.
* @param watermark The Rx FIFO watermark.
*/
static inline void UART_SetRxFifoWatermark(UART_Type* base, uint8_t watermark)
{
assert(watermark <= 32);
UART_UFCR_REG(base) = (UART_UFCR_REG(base) & ~UART_UFCR_RXTL_MASK) | UART_UFCR_RXTL(watermark);
}
/*@}*/
/*!
* @name Hardware Flow control and Modem Signal functions.
* @{
*/
/*!
* @brief This function is used to set the enable condition of RTS
* Hardware flow control.
*
* @param base UART base pointer.
* @param enable Enable/Disbale RTS hardware flow control.
* - true: Enable RTS hardware flow control.
* - false: Disbale RTS hardware flow control.
*/
void UART_SetRtsFlowCtrlCmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to set the RTS interrupt trigger edge.
* The available trigger edge can be select from
* @ref _uart_rts_trigger_edge enumeration.
*
* @param base UART base pointer.
* @param triggerEdge Available RTS pin interrupt trigger edge.
*/
static inline void UART_SetRtsIntTriggerEdge(UART_Type* base, uint32_t triggerEdge)
{
assert((triggerEdge == uartRtsTriggerEdgeRising) || \
(triggerEdge == uartRtsTriggerEdgeFalling) || \
(triggerEdge == uartRtsTriggerEdgeBoth));
UART_UCR2_REG(base) = (UART_UCR2_REG(base) & ~UART_UCR2_RTEC_MASK) | triggerEdge;
}
/*!
* @brief This function is used to set the enable condition of CTS
* auto control. if CTS control is enabled, the CTS_B pin
* is controlled by the receiver, otherwise the CTS_B pin is
* controlled by UART_CTSPinCtrl function.
*
* @param base UART base pointer.
* @param enable Enable/Disable CTS auto control.
* - true: Enable CTS auto control.
* - false: Disable CTS auto control.
*/
void UART_SetCtsFlowCtrlCmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to control the CTS_B pin state when
* auto CTS control is disabled.
* The CTS_B pin is low(active)
* The CTS_B pin is high(inactive)
*
* @param base UART base pointer.
* @param active The CTS_B pin state to set.
* - true: the CTS_B pin active;
* - false: the CTS_B pin inactive.
*/
void UART_SetCtsPinLevel(UART_Type* base, bool active);
/*!
* @brief This function is used to set the auto CTS_B pin control
* trigger level. The CTS_B pin is de-asserted when
* Rx FIFO reach CTS trigger level.
*
* @param base UART base pointer.
* @param triggerLevel Auto CTS_B pin control trigger level.
*/
static inline void UART_SetCtsTriggerLevel(UART_Type* base, uint8_t triggerLevel)
{
assert(triggerLevel <= 32);
UART_UCR4_REG(base) = (UART_UCR4_REG(base) & ~UART_UCR4_CTSTL_MASK) | UART_UCR4_CTSTL(triggerLevel);
}
/*!
* @brief This function is used to set the role (DTE/DCE) of UART module
* in RS-232 communication.
*
* @param base UART base pointer.
* @param mode The role(DTE/DCE) of UART module (see @ref _uart_modem_mode enumeration).
*/
void UART_SetModemMode(UART_Type* base, uint32_t mode);
/*!
* @brief This function is used to set the edge of DTR_B (DCE) or
* DSR_B (DTE) on which an interrupt is generated.
*
* @param base UART base pointer.
* @param triggerEdge The trigger edge on which an interrupt is generated
* (see @ref _uart_dtr_trigger_edge enumeration above).
*/
static inline void UART_SetDtrIntTriggerEdge(UART_Type* base, uint32_t triggerEdge)
{
assert((triggerEdge == uartDtrTriggerEdgeRising) || \
(triggerEdge == uartDtrTriggerEdgeFalling) || \
(triggerEdge == uartDtrTriggerEdgeBoth));
UART_UCR3_REG(base) = (UART_UCR3_REG(base) & ~UART_UCR3_DPEC_MASK) | triggerEdge;
}
/*!
* @brief This function is used to set the pin state of DSR pin(for DCE mode)
* or DTR pin(for DTE mode) for the modem interface.
*
* @param base UART base pointer.
* @param active The state of DSR pin.
* - true: DSR/DTR pin is logic one.
* - false: DSR/DTR pin is logic zero.
*/
void UART_SetDtrPinLevel(UART_Type* base, bool active);
/*!
* @brief This function is used to set the pin state of
* DCD pin. THIS FUNCTION IS FOR DCE MODE ONLY.
*
* @param base UART base pointer.
* @param active The state of DCD pin.
* - true: DCD_B pin is logic one (DCE mode)
* - false: DCD_B pin is logic zero (DCE mode)
*/
void UART_SetDcdPinLevel(UART_Type* base, bool active);
/*!
* @brief This function is used to set the pin state of
* RI pin. THIS FUNCTION IS FOR DCE MODE ONLY.
*
* @param base UART base pointer.
* @param active The state of RI pin.
* - true: RI_B pin is logic one (DCE mode)
* - false: RI_B pin is logic zero (DCE mode)
*/
void UART_SetRiPinLevel(UART_Type* base, bool active);
/*@}*/
/*!
* @name Multiprocessor and RS-485 functions.
* @{
*/
/*!
* @brief This function is used to send 9 Bits length data in
* RS-485 Multidrop mode.
*
* @param base UART base pointer.
* @param data Data(9 bits) to be set through UART module.
*/
void UART_Putchar9(UART_Type* base, uint16_t data);
/*!
* @brief This functions is used to receive 9 Bits length data in
* RS-485 Multidrop mode.
*
* @param base UART base pointer.
* @return The data(9 bits) received from UART module.
*/
uint16_t UART_Getchar9(UART_Type* base);
/*!
* @brief This function is used to set the enable condition of
* 9-Bits data or Multidrop mode.
*
* @param base UART base pointer.
* @param enable Enable/Disable Multidrop mode.
* - true: Enable Multidrop mode.
* - false: Disable Multidrop mode.
*/
void UART_SetMultidropMode(UART_Type* base, bool enable);
/*!
* @brief This function is used to set the enable condition of
* Automatic Address Detect Mode.
*
* @param base UART base pointer.
* @param enable Enable/Disable Automatic Address Detect mode.
* - true: Enable Automatic Address Detect mode.
* - false: Disable Automatic Address Detect mode.
*/
void UART_SetSlaveAddressDetectCmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to set the slave address char
* that the receiver tries to detect.
*
* @param base UART base pointer.
* @param slaveAddress The slave to detect.
*/
static inline void UART_SetSlaveAddress(UART_Type* base, uint8_t slaveAddress)
{
UART_UMCR_REG(base) = (UART_UMCR_REG(base) & ~UART_UMCR_SLADDR_MASK) | \
UART_UMCR_SLADDR(slaveAddress);
}
/*@}*/
/*!
* @name IrDA control functions.
* @{
*/
/*!
* @brief This function is used to set the enable condition of
* IrDA Mode.
*
* @param base UART base pointer.
* @param enable Enable/Disable IrDA mode.
* - true: Enable IrDA mode.
* - false: Disable IrDA mode.
*/
void UART_SetIrDACmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to set the clock for the IR pulsed
* vote logic. The available clock can be select from
* @ref _uart_irda_vote_clock enumeration.
*
* @param base UART base pointer.
* @param voteClock The available IrDA vote clock selection.
*/
void UART_SetIrDAVoteClock(UART_Type* base, uint32_t voteClock);
/*@}*/
/*!
* @name Misc. functions.
* @{
*/
/*!
* @brief This function is used to set the enable condition of
* Automatic Baud Rate Detection feature.
*
* @param base UART base pointer.
* @param enable Enable/Disable Automatic Baud Rate Detection feature.
* - true: Enable Automatic Baud Rate Detection feature.
* - false: Disable Automatic Baud Rate Detection feature.
*/
void UART_SetAutoBaudRateCmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to read the current value of Baud Rate
* Count Register value. this counter is used by Auto Baud Rate
* Detect feature.
*
* @param base UART base pointer.
* @return Current Baud Rate Count Register value.
*/
static inline uint16_t UART_ReadBaudRateCount(UART_Type* base)
{
return (uint16_t)(UART_UBRC_REG(base) & UART_UBRC_BCNT_MASK);
}
/*!
* @brief This function is used to send BREAK character.It is
* important that SNDBRK is asserted high for a sufficient
* period of time to generate a valid BREAK.
*
* @param base UART base pointer.
* @param active Asserted high to generate BREAK.
* - true: Generate BREAK character.
* - false: Stop generate BREAK character.
*/
void UART_SendBreakChar(UART_Type* base, bool active);
/*!
* @brief This function is used to Enable/Disable the Escape
* Sequence Decection feature.
*
* @param base UART base pointer.
* @param enable Enable/Disable Escape Sequence Decection.
* - true: Enable Escape Sequence Decection.
* - false: Disable Escape Sequence Decection.
*/
void UART_SetEscapeDecectCmd(UART_Type* base, bool enable);
/*!
* @brief This function is used to set the enable condition of
* Escape Sequence Detection feature.
*
* @param base UART base pointer.
* @param escapeChar The Escape Character to detect.
*/
static inline void UART_SetEscapeChar(UART_Type* base, uint8_t escapeChar)
{
UART_UESC_REG(base) = (UART_UESC_REG(base) & ~UART_UESC_ESC_CHAR_MASK) | \
UART_UESC_ESC_CHAR(escapeChar);
}
/*!
* @brief This function is used to set the maximum time interval (in ms)
* allowed between escape characters.
*
* @param base UART base pointer.
* @param timerInterval Maximum time interval allowed between escape characters.
*/
static inline void UART_SetEscapeTimerInterval(UART_Type* base, uint16_t timerInterval)
{
assert(timerInterval <= 0xFFF);
UART_UTIM_REG(base) = (UART_UTIM_REG(base) & ~UART_UTIM_TIM_MASK) | \
UART_UTIM_TIM(timerInterval);
}
/*@}*/
#ifdef __cplusplus
}
#endif
/*! @}*/
#endif /* __UART_IMX_H__ */
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "wdog_imx.h"
/*******************************************************************************
* Code
******************************************************************************/
/*FUNCTION**********************************************************************
*
* Function Name : WDOG_Enable
* Description : Configure WDOG funtions, call once only
*
*END**************************************************************************/
void WDOG_Enable(WDOG_Type *base, uint8_t timeout)
{
uint16_t wcr = base->WCR & (~WDOG_WCR_WT_MASK);
base->WCR = wcr | WDOG_WCR_WT(timeout) | WDOG_WCR_WDE_MASK;
}
/*FUNCTION**********************************************************************
*
* Function Name : WDOG_Reset
* Description : Assert WDOG reset signal
*
*END**************************************************************************/
void WDOG_Reset(WDOG_Type *base, bool wda, bool srs)
{
uint16_t wcr = base->WCR;
if (wda)
wcr &= ~WDOG_WCR_WDA_MASK;
if (srs)
wcr &= ~WDOG_WCR_SRS_MASK;
base->WCR = wcr;
}
/*FUNCTION**********************************************************************
*
* Function Name : WDOG_Refresh
* Description : Refresh the WDOG to prevent timeout
*
*END**************************************************************************/
void WDOG_Refresh(WDOG_Type *base)
{
base->WSR = 0x5555;
base->WSR = 0xAAAA;
}
/*******************************************************************************
* EOF
******************************************************************************/

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WDOG_IMX_H__
#define __WDOG_IMX_H__
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "device_imx.h"
/*!
* @addtogroup wdog_imx_driver
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief The reset source of latest reset. */
enum _wdog_reset_source
{
wdogResetSourcePor = WDOG_WRSR_POR_MASK, /*!< Indicates the reset is the result of a power on reset.*/
wdogResetSourceTimeout = WDOG_WRSR_TOUT_MASK, /*!< Indicates the reset is the result of a WDOG timeout.*/
wdogResetSourceSwRst = WDOG_WRSR_SFTW_MASK, /*!< Indicates the reset is the result of a software reset.*/
};
/*! @brief Structure to configure the running mode. */
typedef struct _wdog_init_config
{
bool wdw; /*!< true: suspend in low power wait, false: not suspend */
bool wdt; /*!< true: assert WDOG_B when timeout, false: not assert WDOG_B */
bool wdbg; /*!< true: suspend in debug mode, false: not suspend */
bool wdzst; /*!< true: suspend in doze and stop mode, false: not suspend */
} wdog_init_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name WDOG State Control
* @{
*/
/*!
* @brief Configure WDOG functions, call once only
*
* @param base WDOG base pointer.
* @param initConfig WDOG mode configuration
*/
static inline void WDOG_Init(WDOG_Type *base, const wdog_init_config_t *initConfig)
{
base->WCR |= (initConfig->wdw ? WDOG_WCR_WDW_MASK : 0) |
(initConfig->wdt ? WDOG_WCR_WDT_MASK : 0) |
(initConfig->wdbg ? WDOG_WCR_WDBG_MASK : 0) |
(initConfig->wdzst ? WDOG_WCR_WDZST_MASK : 0);
}
/*!
* @brief Enable WDOG with timeout, call once only
*
* @param base WDOG base pointer.
* @param timeout WDOG timeout ((n+1)/2 second)
*/
void WDOG_Enable(WDOG_Type *base, uint8_t timeout);
/*!
* @brief Assert WDOG software reset signal
*
* @param base WDOG base pointer.
* @param wda WDOG reset.
* - true: Assert WDOG_B.
* - false: No impact on WDOG_B.
* @param srs System reset.
* - true: Assert system reset WDOG_RESET_B_DEB.
* - false: No impact on system reset.
*/
void WDOG_Reset(WDOG_Type *base, bool wda, bool srs);
/*!
* @brief Get the latest reset source generated due to
* WatchDog Timer.
*
* @param base WDOG base pointer.
* @return The latest reset source (see @ref _wdog_reset_source enumeration).
*/
static inline uint32_t WDOG_GetResetSource(WDOG_Type *base)
{
return base->WRSR;
}
/*!
* @brief Refresh the WDOG to prevent timeout
*
* @param base WDOG base pointer.
*/
void WDOG_Refresh(WDOG_Type *base);
/*!
* @brief Disable WDOG power down counter
*
* @param base WDOG base pointer.
*/
static inline void WDOG_DisablePowerdown(WDOG_Type *base)
{
base->WMCR &= ~WDOG_WMCR_PDE_MASK;
}
/*@}*/
/*!
* @name WDOG Interrupt Control
* @{
*/
/*!
* @brief Enable WDOG interrupt
*
* @param base WDOG base pointer.
* @param time how long before the timeout must the interrupt occur (n/2 seconds).
*/
static inline void WDOG_EnableInt(WDOG_Type *base, uint8_t time)
{
base->WICR = WDOG_WICR_WIE_MASK | WDOG_WICR_WICT(time);
}
/*!
* @brief Check whether WDOG interrupt is pending
*
* @param base WDOG base pointer.
* @return WDOG interrupt status.
* - true: Pending.
* - false: Not pending.
*/
static inline bool WDOG_IsIntPending(WDOG_Type *base)
{
return (bool)(base->WICR & WDOG_WICR_WTIS_MASK);
}
/*!
* @brief Clear WDOG interrupt status
*
* @param base WDOG base pointer.
*/
static inline void WDOG_ClearStatusFlag(WDOG_Type *base)
{
base->WICR |= WDOG_WICR_WTIS_MASK;
}
/*@}*/
#if defined(__cplusplus)
}
#endif
/*! @}*/
#endif /* __WDOG_IMX_H__ */
/*******************************************************************************
* EOF
******************************************************************************/