From a57cc2c988482010061b9e68344fdf1969889763 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 12 Jan 2016 14:06:54 -0800 Subject: initial commit, FreeRTOS_BSP_1.0.0_iMX7D --- platform/drivers/inc/adc_imx7d.h | 549 ++++++++++++++++ platform/drivers/inc/ccm_analog_imx7d.h | 354 ++++++++++ platform/drivers/inc/ccm_imx7d.h | 483 ++++++++++++++ platform/drivers/inc/ecspi.h | 502 +++++++++++++++ platform/drivers/inc/flexcan.h | 661 +++++++++++++++++++ platform/drivers/inc/gpio_imx.h | 282 ++++++++ platform/drivers/inc/gpt.h | 410 ++++++++++++ platform/drivers/inc/i2c_imx.h | 284 ++++++++ platform/drivers/inc/mu_imx.h | 576 +++++++++++++++++ platform/drivers/inc/rdc.h | 257 ++++++++ platform/drivers/inc/rdc_defs_imx7d.h | 225 +++++++ platform/drivers/inc/rdc_semaphore.h | 142 ++++ platform/drivers/inc/sema4.h | 285 +++++++++ platform/drivers/inc/uart_imx.h | 769 ++++++++++++++++++++++ platform/drivers/inc/wdog_imx.h | 169 +++++ platform/drivers/src/adc_imx7d.c | 766 ++++++++++++++++++++++ platform/drivers/src/ccm_analog_imx7d.c | 75 +++ platform/drivers/src/ccm_imx7d.c | 85 +++ platform/drivers/src/ecspi.c | 205 ++++++ platform/drivers/src/flexcan.c | 1068 +++++++++++++++++++++++++++++++ platform/drivers/src/gpio_imx.c | 160 +++++ platform/drivers/src/gpt.c | 91 +++ platform/drivers/src/i2c_imx.c | 167 +++++ platform/drivers/src/mu_imx.c | 155 +++++ platform/drivers/src/rdc.c | 89 +++ platform/drivers/src/rdc_semaphore.c | 187 ++++++ platform/drivers/src/sema4.c | 199 ++++++ platform/drivers/src/uart_imx.c | 601 +++++++++++++++++ platform/drivers/src/wdog_imx.c | 81 +++ 29 files changed, 9877 insertions(+) create mode 100644 platform/drivers/inc/adc_imx7d.h create mode 100644 platform/drivers/inc/ccm_analog_imx7d.h create mode 100644 platform/drivers/inc/ccm_imx7d.h create mode 100644 platform/drivers/inc/ecspi.h create mode 100644 platform/drivers/inc/flexcan.h create mode 100644 platform/drivers/inc/gpio_imx.h create mode 100644 platform/drivers/inc/gpt.h create mode 100644 platform/drivers/inc/i2c_imx.h create mode 100644 platform/drivers/inc/mu_imx.h create mode 100644 platform/drivers/inc/rdc.h create mode 100644 platform/drivers/inc/rdc_defs_imx7d.h create mode 100644 platform/drivers/inc/rdc_semaphore.h create mode 100644 platform/drivers/inc/sema4.h create mode 100644 platform/drivers/inc/uart_imx.h create mode 100644 platform/drivers/inc/wdog_imx.h create mode 100644 platform/drivers/src/adc_imx7d.c create mode 100644 platform/drivers/src/ccm_analog_imx7d.c create mode 100644 platform/drivers/src/ccm_imx7d.c create mode 100644 platform/drivers/src/ecspi.c create mode 100644 platform/drivers/src/flexcan.c create mode 100644 platform/drivers/src/gpio_imx.c create mode 100644 platform/drivers/src/gpt.c create mode 100644 platform/drivers/src/i2c_imx.c create mode 100644 platform/drivers/src/mu_imx.c create mode 100644 platform/drivers/src/rdc.c create mode 100644 platform/drivers/src/rdc_semaphore.c create mode 100644 platform/drivers/src/sema4.c create mode 100644 platform/drivers/src/uart_imx.c create mode 100644 platform/drivers/src/wdog_imx.c (limited to 'platform/drivers') diff --git a/platform/drivers/inc/adc_imx7d.h b/platform/drivers/inc/adc_imx7d.h new file mode 100644 index 0000000..d163c3a --- /dev/null +++ b/platform/drivers/inc/adc_imx7d.h @@ -0,0 +1,549 @@ +/* + * 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 +#include +#include +#include "device_imx.h" + +/*! + * @addtogroup adc_imx7d_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief ADC module initialize 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 initialize structure. + */ +typedef struct _adc_logic_ch_init_config +{ + uint8_t inputChannel; /*!< The logic channel to be set.*/ + bool coutinuousEnable; /*!< Continuous sample mode enable configuration.*/ + uint32_t convertRate; /*!< The continuous rate when continuous sample enabled.*/ + bool averageEnable; /*!< Hardware average enable configuration.*/ + uint8_t averageNumber; /*!< The average number for hardware average function.*/ +} 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 will be triggered when sample value greater than low threshold.*/ + adcCmpModeLessThanLow = 0x2, /*!< ADC build-in comparator will be triggered when sample value less than low threshold.*/ + adcCmpModeInInterval = 0x3, /*!< ADC build-in comparator will be triggered when sample value in interval between low and high threshold.*/ + adcCmpModeGreaterThanHigh = 0x5, /*!< ADC build-in comparator will be triggered when sample value greater than high threshold.*/ + adcCmpModeLessThanHigh = 0x6, /*!< ADC build-in comparator will be triggered when sample value less than high threshold.*/ + adcCmpModeOutOffInterval = 0x7 /*!< ADC build-in comparator will be 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, + adcIntConvertTimeoutChSw = ADC_INT_EN_SW_CH_COV_TO_INT_EN_MASK, + adcIntConvertTimeoutChD = ADC_INT_EN_CHD_COV_TO_INT_EN_MASK, + adcIntConvertTimeoutChC = ADC_INT_EN_CHC_COV_TO_INT_EN_MASK, + adcIntConvertTimeoutChB = ADC_INT_EN_CHB_COV_TO_INT_EN_MASK, + adcIntConvertTimeoutChA = ADC_INT_EN_CHA_COV_TO_INT_EN_MASK, + adcIntConvertChSw = ADC_INT_EN_SW_CH_COV_INT_EN_MASK, + adcIntConvertChD = ADC_INT_EN_CHD_COV_INT_EN_MASK, + adcIntConvertChC = ADC_INT_EN_CHC_COV_INT_EN_MASK, + adcIntConvertChB = ADC_INT_EN_CHB_COV_INT_EN_MASK, + adcIntConvertChA = ADC_INT_EN_CHA_COV_INT_EN_MASK, + adcIntFifoOverrun = ADC_INT_EN_FIFO_OVERRUN_INT_EN_MASK, + adcIntFifoUnderrun = ADC_INT_EN_FIFO_UNDERRUN_INT_EN_MASK, + adcIntDmaReachWatermark = ADC_INT_EN_DMA_REACH_WM_INT_EN_MASK, + adcIntCmpChD = ADC_INT_EN_CHD_CMP_INT_EN_MASK, + adcIntCmpChC = ADC_INT_EN_CHC_CMP_INT_EN_MASK, + adcIntCmpChB = ADC_INT_EN_CHB_CMP_INT_EN_MASK, + adcIntCmpChA = ADC_INT_EN_CHA_CMP_INT_EN_MASK +}; + +/*! + * @brief Flag for ADC interrupt/DMA status check or polling status. + */ +enum _adc_status_flag +{ + adcStatusLastFifoDataRead = ADC_INT_STATUS_LAST_FIFO_DATA_READ_MASK, + adcStatusConvertTimeoutChSw = ADC_INT_STATUS_SW_CH_COV_TO_MASK, + adcStatusConvertTimeoutChD = ADC_INT_STATUS_CHD_COV_TO_MASK, + adcStatusConvertTimeoutChC = ADC_INT_STATUS_CHC_COV_TO_MASK, + adcStatusConvertTimeoutChB = ADC_INT_STATUS_CHB_COV_TO_MASK, + adcStatusConvertTimeoutChA = ADC_INT_STATUS_CHA_COV_TO_MASK, + adcStatusConvertChSw = ADC_INT_STATUS_SW_CH_COV_MASK, + adcStatusConvertChD = ADC_INT_STATUS_CHD_COV_MASK, + adcStatusConvertChC = ADC_INT_STATUS_CHC_COV_MASK, + adcStatusConvertChB = ADC_INT_STATUS_CHB_COV_MASK, + adcStatusConvertChA = ADC_INT_STATUS_CHA_COV_MASK, + adcStatusFifoOverrun = ADC_INT_STATUS_FIFO_OVERRUN_MASK, + adcStatusFifoUnderrun = ADC_INT_STATUS_FIFO_UNDERRUN_MASK, + adcStatusDmaReachWatermark = ADC_INT_STATUS_DMA_REACH_WM_MASK, + adcStatusCmpChD = ADC_INT_STATUS_CHD_CMP_MASK, + adcStatusCmpChC = ADC_INT_STATUS_CHC_CMP_MASK, + adcStatusCmpChB = ADC_INT_STATUS_CHB_CMP_MASK, + adcStatusCmpChA = ADC_INT_STATUS_CHA_CMP_MASK +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name ADC Module Initialization and Configuration functions. + * @{ + */ + +/*! + * @brief Initialize ADC to reset state and initialize with initialize structure. + * + * @param base ADC base pointer. + * @param initConfig ADC initialize structure. + */ +void ADC_Init(ADC_Type* base, 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 iMX7D, 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 - 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 - 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 initialize structure. + * + * @param base ADC base pointer. + * @param logicCh ADC module logic channel selection(refer to _adc_logic_ch_selection enumeration). + * @param chInitConfig ADC logic channel initialize structure. + */ +void ADC_LogicChInit(ADC_Type* base, uint8_t logicCh, 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(refer to _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(refer to _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(refer to _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(refer to _adc_logic_ch_selection enumeration). + * @param enable - true: Enable hardware average. + * - faluse: Disable hardware average. + */ +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(refer to _adc_logic_ch_selection enumeration). + * @param avgNum hardware average number(should select from _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(refer to _adc_logic_ch_selection enumeration). + * @param enable - true: Enable continuous convert. + * - false: Disable continuous convert. + */ +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(refer to _adc_logic_ch_selection enumeration). + */ +void ADC_TriggerSingleConvert(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(refer to _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(refer to _adc_logic_ch_selection enumeration). + * @param cmpMode Comparer work mode selected from _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(refer to _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(refer to _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(refer to _adc_logic_ch_selection enumeration). + * @param enable - 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 config. + * @param enable Pass true to enable interrupt, false to disable. + */ +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 config. + * @param intSignal Should be select from _adc_interrupt enumeration. + */ +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 _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 _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 - true :Reset the DMA and DMA FIFO return to its reset value. + * - false :de-active DMA reset. + */ +void ADC_SetDmaReset(ADC_Type* base, bool active); + +/*! + * @brief Set the work mode of ADC DMA part. + * + * @param base ADC base pointer. + * @param enable - 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 - true :Enable DMA FIFO. + * - false :Disable DMA FIFO. + */ +void ADC_SetDmaFifoCmd(ADC_Type* base, bool enable); + +/*! + * @brief Select the logic channel that will use DMA transfer. + * + * @param base ADC base pointer. + * @param logicCh ADC module logic channel selection(refer to _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. + * @return - true: DMA FIFO full + * - 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. + * @return - true: DMA FIFO empty + * - false: DMA FIFO 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 + ******************************************************************************/ diff --git a/platform/drivers/inc/ccm_analog_imx7d.h b/platform/drivers/inc/ccm_analog_imx7d.h new file mode 100644 index 0000000..675ae1d --- /dev/null +++ b/platform/drivers/inc/ccm_analog_imx7d.h @@ -0,0 +1,354 @@ +/* + * 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 +#include +#include +#include +#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\n + * 16:20 : Powerdown bit shift + */ +enum _ccm_analog_pll_control { + ccmAnalogPllArmControl = CCM_ANALOG_TUPLE(PLL_ARM, CCM_ANALOG_PLL_ARM_POWERDOWN_SHIFT), + ccmAnalogPllDdrControl = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_POWERDOWN_SHIFT), + ccmAnalogPll480Control = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_POWERDOWN_SHIFT), + ccmAnalogPllEnetControl = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_POWERDOWN_SHIFT), + ccmAnalogPllAudioControl = CCM_ANALOG_TUPLE(PLL_AUDIO, CCM_ANALOG_PLL_AUDIO_POWERDOWN_SHIFT), + ccmAnalogPllVideoControl = CCM_ANALOG_TUPLE(PLL_VIDEO, CCM_ANALOG_PLL_VIDEO_POWERDOWN_SHIFT) +}; + +/*! + * @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\n + * 16:20 : Clock enable bit shift + */ +enum _ccm_analog_pll_clock { + ccmAnalogPllArmClock = CCM_ANALOG_TUPLE(PLL_ARM, CCM_ANALOG_PLL_ARM_ENABLE_CLK_SHIFT), + + ccmAnalogPllDdrClock = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_ENABLE_CLK_SHIFT), + ccmAnalogPllDdrDiv2Clock = CCM_ANALOG_TUPLE(PLL_DDR, CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK_SHIFT), + + ccmAnalogPll480Clock = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_ENABLE_CLK_SHIFT), + + ccmAnalogPllEnet25MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_SHIFT), + ccmAnalogPllEnet40MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_SHIFT), + ccmAnalogPllEnet50MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_SHIFT), + ccmAnalogPllEnet100MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_SHIFT), + ccmAnalogPllEnet125MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_SHIFT), + ccmAnalogPllEnet250MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_SHIFT), + ccmAnalogPllEnet500MhzClock = CCM_ANALOG_TUPLE(PLL_ENET, CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_SHIFT), + + ccmAnalogPllAudioClock = CCM_ANALOG_TUPLE(PLL_AUDIO, CCM_ANALOG_PLL_AUDIO_ENABLE_CLK_SHIFT), + ccmAnalogPllVideoClock = CCM_ANALOG_TUPLE(PLL_VIDEO, CCM_ANALOG_PLL_VIDEO_ENABLE_CLK_SHIFT) +}; + +/*! + * @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\n + * 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), + ccmAnalogMainDiv2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_MAIN_DIV2_CLKGATE_SHIFT), + ccmAnalogMainDiv4ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_MAIN_DIV4_CLKGATE_SHIFT), + + ccmAnalogPfd0Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD0_DIV2_CLKGATE_SHIFT), + ccmAnalogPfd1Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD1_DIV2_CLKGATE_SHIFT), + ccmAnalogPfd2Div2ClkGate = CCM_ANALOG_TUPLE(PLL_480, CCM_ANALOG_PLL_480_PFD2_DIV2_CLKGATE_SHIFT), + + ccmAnalogPfd0Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd1Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd2Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd3Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_DIV1_CLKGATE_SHIFT), + + ccmAnalogPfd4Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd5Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd6Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_DIV1_CLKGATE_SHIFT), + ccmAnalogPfd7Div1ClkGate = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_DIV1_CLKGATE_SHIFT) +}; + +/*! + * @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\n + * 16:20 : Fraction bits shift + */ +enum _ccm_analog_pfd_frac { + ccmAnalogPfd0Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT), + ccmAnalogPfd1Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT), + ccmAnalogPfd2Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT), + ccmAnalogPfd3Frac = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_FRAC_SHIFT), + + ccmAnalogPfd4Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_FRAC_SHIFT), + ccmAnalogPfd5Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_FRAC_SHIFT), + ccmAnalogPfd6Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_FRAC_SHIFT), + ccmAnalogPfd7Frac = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_FRAC_SHIFT) +}; + +/*! + * @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\n + * 16:20 : Stable bit shift + */ +enum _ccm_analog_pfd_stable { + ccmAnalogPfd0Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD0_STABLE_SHIFT), + ccmAnalogPfd1Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD1_STABLE_SHIFT), + ccmAnalogPfd2Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD2_STABLE_SHIFT), + ccmAnalogPfd3Stable = CCM_ANALOG_TUPLE(PFD_480A, CCM_ANALOG_PFD_480A_PFD3_STABLE_SHIFT), + + ccmAnalogPfd4Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD4_STABLE_SHIFT), + ccmAnalogPfd5Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD5_STABLE_SHIFT), + ccmAnalogPfd6Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD6_STABLE_SHIFT), + ccmAnalogPfd7Stable = CCM_ANALOG_TUPLE(PFD_480B, CCM_ANALOG_PFD_480B_PFD7_STABLE_SHIFT) +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name CCM Analog PLL Operations + * @{ + */ + +/*! + * @brief Power up PLL + * + * @param base CCM_ANALOG base pointer. + * @param pllControl PLL control name (see _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 _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 _ccm_analog_pll_control enumeration) + * @param bypass Bypass the PLL (true: bypass, false: not bypass) + */ +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 _ccm_analog_pll_control enumeration) + * @return PLL bypass status (true: bypassed, false: 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 _ccm_analog_pll_control enumeration) + * @return PLL lock status (true: locked, false: 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 _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 _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 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); + +/*@}*/ + +/*! + * @name CCM Analog PFD Operations + * @{ + */ + +/*! + * @brief Enable PFD clock + * + * @param base CCM_ANALOG base pointer. + * @param pfdClkGate PFD clock gate (see _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 _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 _ccm_analog_pfd_stable enumeration) + * @return PFD clock stable status (true: stable, false: 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 _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 _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 _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 + ******************************************************************************/ diff --git a/platform/drivers/inc/ccm_imx7d.h b/platform/drivers/inc/ccm_imx7d.h new file mode 100644 index 0000000..0d8b326 --- /dev/null +++ b/platform/drivers/inc/ccm_imx7d.h @@ -0,0 +1,483 @@ +/* + * 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_IMX7D_H__ +#define __CCM_IMX7D_H__ + +#include +#include +#include +#include +#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), + ccmRootAxi = (uint32_t)(&CCM_TARGET_ROOT16), + ccmRootAhb = (uint32_t)(&CCM_TARGET_ROOT32), + ccmRootIpg = (uint32_t)(&CCM_TARGET_ROOT33), + ccmRootQspi = (uint32_t)(&CCM_TARGET_ROOT85), + ccmRootCan1 = (uint32_t)(&CCM_TARGET_ROOT89), + ccmRootCan2 = (uint32_t)(&CCM_TARGET_ROOT90), + ccmRootI2c1 = (uint32_t)(&CCM_TARGET_ROOT91), + ccmRootI2c2 = (uint32_t)(&CCM_TARGET_ROOT92), + ccmRootI2c3 = (uint32_t)(&CCM_TARGET_ROOT93), + ccmRootI2c4 = (uint32_t)(&CCM_TARGET_ROOT94), + ccmRootUart1 = (uint32_t)(&CCM_TARGET_ROOT95), + ccmRootUart2 = (uint32_t)(&CCM_TARGET_ROOT96), + ccmRootUart3 = (uint32_t)(&CCM_TARGET_ROOT97), + ccmRootUart4 = (uint32_t)(&CCM_TARGET_ROOT98), + ccmRootUart5 = (uint32_t)(&CCM_TARGET_ROOT99), + ccmRootUart6 = (uint32_t)(&CCM_TARGET_ROOT100), + ccmRootUart7 = (uint32_t)(&CCM_TARGET_ROOT101), + ccmRootEcspi1 = (uint32_t)(&CCM_TARGET_ROOT102), + ccmRootEcspi2 = (uint32_t)(&CCM_TARGET_ROOT103), + ccmRootEcspi3 = (uint32_t)(&CCM_TARGET_ROOT104), + ccmRootEcspi4 = (uint32_t)(&CCM_TARGET_ROOT105), + ccmRootFtm1 = (uint32_t)(&CCM_TARGET_ROOT110), + ccmRootFtm2 = (uint32_t)(&CCM_TARGET_ROOT111), + ccmRootGpt1 = (uint32_t)(&CCM_TARGET_ROOT114), + ccmRootGpt2 = (uint32_t)(&CCM_TARGET_ROOT115), + ccmRootGpt3 = (uint32_t)(&CCM_TARGET_ROOT116), + ccmRootGpt4 = (uint32_t)(&CCM_TARGET_ROOT117), + ccmRootWdog = (uint32_t)(&CCM_TARGET_ROOT119) +}; + +/*! + * @brief Clock source enumeration for M4 core. + */ +enum _ccm_rootmux_m4 { + ccmRootmuxM4Osc24m = 0U, + ccmRootmuxM4SysPllDiv2 = 1U, + ccmRootmuxM4EnetPll250m = 2U, + ccmRootmuxM4SysPllPfd2 = 3U, + ccmRootmuxM4DdrPllDiv2 = 4U, + ccmRootmuxM4AudioPll = 5U, + ccmRootmuxM4VideoPll = 6U, + ccmRootmuxM4UsbPll = 7U +}; + +/*! + * @brief Clock source enumeration for AXI bus. + */ +enum _ccm_rootmux_axi { + ccmRootmuxAxiOsc24m = 0U, + ccmRootmuxAxiSysPllPfd1 = 1U, + ccmRootmuxAxiDdrPllDiv2 = 2U, + ccmRootmuxAxiEnetPll250m = 3U, + ccmRootmuxAxiSysPllPfd5 = 4U, + ccmRootmuxAxiAudioPll = 5U, + ccmRootmuxAxiVideoPll = 6U, + ccmRootmuxAxiSysPllPfd7 = 7U +}; + +/*! + * @brief Clock source enumeration for AHB bus. + */ +enum _ccm_rootmux_ahb { + ccmRootmuxAhbOsc24m = 0U, + ccmRootmuxAhbSysPllPfd2 = 1U, + ccmRootmuxAhbDdrPllDiv2 = 2U, + ccmRootmuxAhbSysPllPfd0 = 3U, + ccmRootmuxAhbEnetPll125m = 4U, + ccmRootmuxAhbUsbPll = 5U, + ccmRootmuxAhbAudioPll = 6U, + ccmRootmuxAhbVideoPll = 7U +}; + +/*! + * @brief Clock source enumeration for IPG bus. + */ +enum _ccm_rootmux_ipg { + ccmRootmuxIpgAHB = 0U +}; + +/*! + * @brief Clock source enumeration for QSPI peripheral. + */ +enum _ccm_rootmux_qspi { + ccmRootmuxQspiOsc24m = 0U, + ccmRootmuxQspiSysPllPfd4 = 1U, + ccmRootmuxQspiDdrPllDiv2 = 2U, + ccmRootmuxQspiEnetPll500m = 3U, + ccmRootmuxQspiSysPllPfd3 = 4U, + ccmRootmuxQspiSysPllPfd2 = 5U, + ccmRootmuxQspiSysPllPfd6 = 6U, + ccmRootmuxQspiSysPllPfd7 = 7U +}; + +/*! + * @brief Clock source enumeration for CAN peripheral. + */ +enum _ccm_rootmux_can { + ccmRootmuxCanOsc24m = 0U, + ccmRootmuxCanSysPllDiv4 = 1U, + ccmRootmuxCanDdrPllDiv2 = 2U, + ccmRootmuxCanSysPllDiv1 = 3U, + ccmRootmuxCanEnetPll40m = 4U, + ccmRootmuxCanUsbPll = 5U, + ccmRootmuxCanExtClk1 = 6U, + ccmRootmuxCanExtClk34 = 7U +}; + +/*! + * @brief Clock source enumeration for ECSPI peripheral. + */ +enum _ccm_rootmux_ecspi { + ccmRootmuxEcspiOsc24m = 0U, + ccmRootmuxEcspiSysPllDiv2 = 1U, + ccmRootmuxEcspiEnetPll40m = 2U, + ccmRootmuxEcspiSysPllDiv4 = 3U, + ccmRootmuxEcspiSysPllDiv1 = 4U, + ccmRootmuxEcspiSysPllPfd4 = 5U, + ccmRootmuxEcspiEnetPll250m = 6U, + ccmRootmuxEcspiUsbPll = 7U +}; + +/*! + * @brief Clock source enumeration for I2C peripheral. + */ +enum _ccm_rootmux_i2c { + ccmRootmuxI2cOsc24m = 0U, + ccmRootmuxI2cSysPllDiv4 = 1U, + ccmRootmuxI2cEnetPll50m = 2U, + ccmRootmuxI2cDdrPllDiv2 = 3U, + ccmRootmuxI2cAudioPll = 4U, + ccmRootmuxI2cVideoPll = 5U, + ccmRootmuxI2cUsbPll = 6U, + ccmRootmuxI2cSysPllPfd2Div2 = 7U +}; + +/*! + * @brief Clock source enumeration for UART peripheral. + */ +enum _ccm_rootmux_uart { + ccmRootmuxUartOsc24m = 0U, + ccmRootmuxUartSysPllDiv2 = 1U, + ccmRootmuxUartEnetPll40m = 2U, + ccmRootmuxUartEnetPll100m = 3U, + ccmRootmuxUartSysPllDiv1 = 4U, + ccmRootmuxUartExtClk2 = 5U, + ccmRootmuxUartExtClk34 = 6U, + ccmRootmuxUartUsbPll = 7U +}; + +/*! + * @brief Clock source enumeration for FlexTimer peripheral. + */ +enum _ccm_rootmux_ftm { + ccmRootmuxFtmOsc24m = 0U, + ccmRootmuxFtmEnetPll100m = 1U, + ccmRootmuxFtmSysPllDiv4 = 2U, + ccmRootmuxFtmEnetPll40m = 3U, + ccmRootmuxFtmAudioPll = 4U, + ccmRootmuxFtmExtClk3 = 5U, + ccmRootmuxFtmRef1m = 6U, + ccmRootmuxFtmVideoPll = 7U +}; + +/*! + * @brief Clock source enumeration for GPT peripheral. + */ +enum _ccm_rootmux_gpt { + ccmRootmuxGptOsc24m = 0U, + ccmRootmuxGptEnetPll100m = 1U, + ccmRootmuxGptSysPllPfd0 = 2U, + ccmRootmuxGptEnetPll40m = 3U, + ccmRootmuxGptVideoPll = 4U, + ccmRootmuxGptRef1m = 5U, + ccmRootmuxGptAudioPll = 6U, + ccmRootmuxGptExtClk = 7U +}; + +/*! + * @brief Clock source enumeration for WDOG peripheral. + */ +enum _ccm_rootmux_wdog { + ccmRootmuxWdogOsc24m = 0U, + ccmRootmuxWdogSysPllPfd2Div2 = 1U, + ccmRootmuxWdogSysPllDiv4 = 2U, + ccmRootmuxWdogDdrPllDiv2 = 3U, + ccmRootmuxWdogEnetPll125m = 4U, + ccmRootmuxWdogUsbPll = 5U, + ccmRootmuxWdogRef1m = 6U, + ccmRootmuxWdogSysPllPfd1Div2 = 7U +}; + +/*! + * @brief CCM PLL gate control + */ +enum _ccm_pll_gate { + ccmPllGateCkil = (uint32_t)(&CCM_PLL_CTRL0_REG(CCM_BASE_PTR)), + ccmPllGateArm = (uint32_t)(&CCM_PLL_CTRL1_REG(CCM_BASE_PTR)), + ccmPllGateArmDiv1 = (uint32_t)(&CCM_PLL_CTRL2_REG(CCM_BASE_PTR)), + ccmPllGateDdr = (uint32_t)(&CCM_PLL_CTRL3_REG(CCM_BASE_PTR)), + ccmPllGateDdrDiv1 = (uint32_t)(&CCM_PLL_CTRL4_REG(CCM_BASE_PTR)), + ccmPllGateDdrDiv2 = (uint32_t)(&CCM_PLL_CTRL5_REG(CCM_BASE_PTR)), + ccmPllGateSys = (uint32_t)(&CCM_PLL_CTRL6_REG(CCM_BASE_PTR)), + ccmPllGateSysDiv1 = (uint32_t)(&CCM_PLL_CTRL7_REG(CCM_BASE_PTR)), + ccmPllGateSysDiv2 = (uint32_t)(&CCM_PLL_CTRL8_REG(CCM_BASE_PTR)), + ccmPllGateSysDiv4 = (uint32_t)(&CCM_PLL_CTRL9_REG(CCM_BASE_PTR)), + ccmPllGatePfd0 = (uint32_t)(&CCM_PLL_CTRL10_REG(CCM_BASE_PTR)), + ccmPllGatePfd0Div2 = (uint32_t)(&CCM_PLL_CTRL11_REG(CCM_BASE_PTR)), + ccmPllGatePfd1 = (uint32_t)(&CCM_PLL_CTRL12_REG(CCM_BASE_PTR)), + ccmPllGatePfd1Div2 = (uint32_t)(&CCM_PLL_CTRL13_REG(CCM_BASE_PTR)), + ccmPllGatePfd2 = (uint32_t)(&CCM_PLL_CTRL14_REG(CCM_BASE_PTR)), + ccmPllGatePfd2Div2 = (uint32_t)(&CCM_PLL_CTRL15_REG(CCM_BASE_PTR)), + ccmPllGatePfd3 = (uint32_t)(&CCM_PLL_CTRL16_REG(CCM_BASE_PTR)), + ccmPllGatePfd4 = (uint32_t)(&CCM_PLL_CTRL17_REG(CCM_BASE_PTR)), + ccmPllGatePfd5 = (uint32_t)(&CCM_PLL_CTRL18_REG(CCM_BASE_PTR)), + ccmPllGatePfd6 = (uint32_t)(&CCM_PLL_CTRL19_REG(CCM_BASE_PTR)), + ccmPllGatePfd7 = (uint32_t)(&CCM_PLL_CTRL20_REG(CCM_BASE_PTR)), + ccmPllGateEnet = (uint32_t)(&CCM_PLL_CTRL21_REG(CCM_BASE_PTR)), + ccmPllGateEnet500m = (uint32_t)(&CCM_PLL_CTRL22_REG(CCM_BASE_PTR)), + ccmPllGateEnet250m = (uint32_t)(&CCM_PLL_CTRL23_REG(CCM_BASE_PTR)), + ccmPllGateEnet125m = (uint32_t)(&CCM_PLL_CTRL24_REG(CCM_BASE_PTR)), + ccmPllGateEnet100m = (uint32_t)(&CCM_PLL_CTRL25_REG(CCM_BASE_PTR)), + ccmPllGateEnet50m = (uint32_t)(&CCM_PLL_CTRL26_REG(CCM_BASE_PTR)), + ccmPllGateEnet40m = (uint32_t)(&CCM_PLL_CTRL27_REG(CCM_BASE_PTR)), + ccmPllGateEnet25m = (uint32_t)(&CCM_PLL_CTRL28_REG(CCM_BASE_PTR)), + ccmPllGateAudio = (uint32_t)(&CCM_PLL_CTRL29_REG(CCM_BASE_PTR)), + ccmPllGateAudioDiv1 = (uint32_t)(&CCM_PLL_CTRL30_REG(CCM_BASE_PTR)), + ccmPllGateVideo = (uint32_t)(&CCM_PLL_CTRL31_REG(CCM_BASE_PTR)), + ccmPllGateVideoDiv1 = (uint32_t)(&CCM_PLL_CTRL32_REG(CCM_BASE_PTR)) +}; + +/*! + * @brief CCM CCGR gate control + */ +enum _ccm_ccgr_gate { + ccmCcgrGateIpmux1 = (uint32_t)(&CCM_CCGR10), + ccmCcgrGateIpmux2 = (uint32_t)(&CCM_CCGR11), + ccmCcgrGateIpmux3 = (uint32_t)(&CCM_CCGR12), + ccmCcgrGateOcram = (uint32_t)(&CCM_CCGR17), + ccmCcgrGateOcramS = (uint32_t)(&CCM_CCGR18), + ccmCcgrGateQspi = (uint32_t)(&CCM_CCGR21), + ccmCcgrGateAdc = (uint32_t)(&CCM_CCGR32), + ccmCcgrGateRdc = (uint32_t)(&CCM_CCGR38), + ccmCcgrGateMu = (uint32_t)(&CCM_CCGR39), + ccmCcgrGateSemaHs = (uint32_t)(&CCM_CCGR40), + ccmCcgrGateSema1 = (uint32_t)(&CCM_CCGR64), + ccmCcgrGateSema2 = (uint32_t)(&CCM_CCGR65), + ccmCcgrGateCan1 = (uint32_t)(&CCM_CCGR116), + ccmCcgrGateCan2 = (uint32_t)(&CCM_CCGR117), + ccmCcgrGateEcspi1 = (uint32_t)(&CCM_CCGR120), + ccmCcgrGateEcspi2 = (uint32_t)(&CCM_CCGR121), + ccmCcgrGateEcspi3 = (uint32_t)(&CCM_CCGR122), + ccmCcgrGateEcspi4 = (uint32_t)(&CCM_CCGR123), + ccmCcgrGateGpt1 = (uint32_t)(&CCM_CCGR124), + ccmCcgrGateGpt2 = (uint32_t)(&CCM_CCGR125), + ccmCcgrGateGpt3 = (uint32_t)(&CCM_CCGR126), + ccmCcgrGateGpt4 = (uint32_t)(&CCM_CCGR127), + ccmCcgrGateI2c1 = (uint32_t)(&CCM_CCGR136), + ccmCcgrGateI2c2 = (uint32_t)(&CCM_CCGR137), + ccmCcgrGateI2c3 = (uint32_t)(&CCM_CCGR138), + ccmCcgrGateI2c4 = (uint32_t)(&CCM_CCGR139), + ccmCcgrGateUart1 = (uint32_t)(&CCM_CCGR148), + ccmCcgrGateUart2 = (uint32_t)(&CCM_CCGR149), + ccmCcgrGateUart3 = (uint32_t)(&CCM_CCGR150), + ccmCcgrGateUart4 = (uint32_t)(&CCM_CCGR151), + ccmCcgrGateUart5 = (uint32_t)(&CCM_CCGR152), + ccmCcgrGateUart6 = (uint32_t)(&CCM_CCGR153), + ccmCcgrGateUart7 = (uint32_t)(&CCM_CCGR154), + ccmCcgrGateWdog1 = (uint32_t)(&CCM_CCGR156), + ccmCcgrGateWdog2 = (uint32_t)(&CCM_CCGR157), + ccmCcgrGateWdog3 = (uint32_t)(&CCM_CCGR158), + ccmCcgrGateWdog4 = (uint32_t)(&CCM_CCGR159), + ccmCcgrGateGpio1 = (uint32_t)(&CCM_CCGR160), + ccmCcgrGateGpio2 = (uint32_t)(&CCM_CCGR161), + ccmCcgrGateGpio3 = (uint32_t)(&CCM_CCGR162), + ccmCcgrGateGpio4 = (uint32_t)(&CCM_CCGR163), + ccmCcgrGateGpio5 = (uint32_t)(&CCM_CCGR164), + ccmCcgrGateGpio6 = (uint32_t)(&CCM_CCGR165), + ccmCcgrGateGpio7 = (uint32_t)(&CCM_CCGR166), + ccmCcgrGateIomux = (uint32_t)(&CCM_CCGR168), + ccmCcgrGateIomuxLpsr = (uint32_t)(&CCM_CCGR169) +}; + +/*! + * @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 _ccm_root_control enumeration) + * @param mux Root mux value (see _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_ROOT0_MUX_MASK)) | + CCM_TARGET_ROOT0_MUX(mux); +} + +/*! + * @brief Get clock root mux + * + * @param base CCM base pointer. + * @param ccmRoot Root control (see _ccm_root_control enumeration) + * @return root mux value (see _ccm_rootmux_xxx enumeration) + */ +static inline uint32_t CCM_GetRootMux(CCM_Type * base, uint32_t ccmRoot) +{ + return (CCM_REG(ccmRoot) & CCM_TARGET_ROOT0_MUX_MASK) >> CCM_TARGET_ROOT0_MUX_SHIFT; +} + +/*! + * @brief Enable clock root + * + * @param base CCM base pointer. + * @param ccmRoot Root control (see _ccm_root_control enumeration) + */ +static inline void CCM_EnableRoot(CCM_Type * base, uint32_t ccmRoot) +{ + CCM_REG_SET(ccmRoot) = CCM_TARGET_ROOT0_SET_ENABLE_MASK; +} + +/*! + * @brief Disable clock root + * + * @param base CCM base pointer. + * @param ccmRoot Root control (see _ccm_root_control enumeration) + */ +static inline void CCM_DisableRoot(CCM_Type * base, uint32_t ccmRoot) +{ + CCM_REG_CLR(ccmRoot) = CCM_TARGET_ROOT0_CLR_ENABLE_MASK; +} + +/*! + * @brief Check whether clock root is enabled + * + * @param base CCM base pointer. + * @param ccmRoot Root control (see _ccm_root_control enumeration) + * @return CCM root enabled or not (true: enabled, false: disabled) + */ +static inline bool CCM_IsRootEnabled(CCM_Type * base, uint32_t ccmRoot) +{ + return (bool)(CCM_REG(ccmRoot) & CCM_TARGET_ROOT0_ENABLE_MASK); +} + +/*! + * @brief Set root clock divider + * + * @param base CCM base pointer. + * @param ccmRoot Root control (see _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 _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 _ccm_root_control enumeration) + * @param root mux value (see _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 _ccm_pll_gate and _ccm_ccgr_gate enumeration) + * @param control Gate control value (see _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 + ******************************************************************************/ diff --git a/platform/drivers/inc/ecspi.h b/platform/drivers/inc/ecspi.h new file mode 100644 index 0000000..2e11401 --- /dev/null +++ b/platform/drivers/inc/ecspi.h @@ -0,0 +1,502 @@ +/* + * 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 +#include +#include +#include "device_imx.h" + +/*! + * @addtogroup ecspi_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Channel select. + */ +enum _ecspi_channel_select { + ecspiSelectChannel0 = 0U, /*!< Selecte Channel 0. Chip Select 0 (SS0) will be asserted.*/ + ecspiSelectChannel1 = 1U, /*!< Selecte Channel 1. Chip Select 1 (SS1) will be asserted.*/ + ecspiSelectChannel2 = 2U, /*!< Selecte Channel 2. Chip Select 2 (SS2) will be asserted.*/ + ecspiSelectChannel3 = 3U /*!< Selecte Channel 3. Chip Select 3 (SS3) will be 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, /*!< SCLK */ + ecspiLowFreq32K = 1U /*!< Low-Frequency Reference Clock (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 a don't care */ + ecspiRdyFallEdgeTrig = 1U, /*!< Burst will be triggered by the falling edge of the SPI_RDY signal (edge-triggered) */ + ecspiRdyLowLevelTrig = 2U, /*!< Burst will be triggered by a low level of the SPI_RDY signal (level-triggered) */ + ecspiRdyReserved = 3U, /*!< Reserved */ +}; + +/*! + * @brief Init structure. + */ +typedef struct EcspiInit +{ + 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 */ + bool ecspiAutoStart; /*!< Specifies the start 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 */ +} ecspi_init_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 initStruct: pointer to a ecspi_init_t structure. + */ +void ECSPI_Init(ECSPI_Type* base, ecspi_init_t* initStruct); + + /*! + * @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 _ecspi_sampleperiod_clocksource). + */ +void ECSPI_SetSampClockSource(ECSPI_Type* base, uint32_t source); + +/*! + * @brief Set the ECSPI clocks inserte between the chip select's 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 inserte */ + 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 _ecspi_channel_select). + * @param state SCLK inactive state (see _ecspi_sclk_inactivestate). + */ +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 _ecspi_channel_select). + * @param state Data line inactive state (see _ecspi_dataline_inactivestate). + */ +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 _ecspi_channel_select). + * @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 _ecspi_channel_select). + * @param polarity set SS signal active logic (see _ecspi_ss_polarity). + */ +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 _ecspi_data_ready). + */ +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 _ecspi_dma_source). + * @param enable True or False. + */ +void ECSPPI_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 _ecspi_fifothreshold) + * @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 _ecspi_status_flag for bit definition). + * @param enable Interrupt enable (true: enable, false: disable). + */ +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 _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 _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 + ******************************************************************************/ diff --git a/platform/drivers/inc/flexcan.h b/platform/drivers/inc/flexcan.h new file mode 100644 index 0000000..8f27315 --- /dev/null +++ b/platform/drivers/inc/flexcan.h @@ -0,0 +1,661 @@ +/* + * 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 +#include +#include +#include "device_imx.h" + +/*! + * @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, + flexcanIntTxWarning = 0x02, + flexcanIntWakeUp = 0x04, + flexcanIntBusOff = 0x08, + flexcanIntError = 0x10, +}; + +/*! @brief Flexcan error interrupt flags. */ +enum _flexcan_status_flag { + flexcanStatusSynch = CAN_ESR1_SYNCH_MASK, + flexcanStatusTxWarningInt = CAN_ESR1_TWRN_INT_MASK, + flexcanStatusRxWarningInt = CAN_ESR1_RWRN_INT_MASK, + flexcanStatusBit1Err = CAN_ESR1_BIT1_ERR_MASK, + flexcanStatusBit0Err = CAN_ESR1_BIT0_ERR_MASK, + flexcanStatusAckErr = CAN_ESR1_ACK_ERR_MASK, + flexcanStatusCrcErr = CAN_ESR1_CRC_ERR_MASK, + flexcanStatusFrameErr = CAN_ESR1_FRM_ERR_MASK, + flexcanStatusStuffingErr = CAN_ESR1_FRM_ERR_MASK, + flexcanStatusTxWarning = CAN_ESR1_TX_WRN_MASK, + flexcanStatusRxWarning = CAN_ESR1_RX_WRN_MASK, + flexcanStatusIdle = CAN_ESR1_IDLE_MASK, + flexcanStatusTransmitting = CAN_ESR1_TX_MASK, + flexcanStatusFltConf = CAN_ESR1_FLT_CONF_MASK, + flexcanStatusReceiving = CAN_ESR1_RX_MASK, + flexcanStatusBusOff = CAN_ESR1_BOFF_INT_MASK, + flexcanStatusError = CAN_ESR1_ERR_INT_MASK, + flexcanStatusWake = CAN_ESR1_WAK_INT_MASK +}; + +/*! @brief The id filter element type selection. */ +enum _flexcan_rx_fifo_id_element_format { + flexcanFxFifoIdElementFormatA = 0x0, /*!< One full ID (standard and extended) per ID Filter Table*/ + /*! element.*/ + flexcanFxFifoIdElementFormatB = 0x1, /*!< Two full standard IDs or two partial 14-bit (standard and*/ + /*! extended) IDs per ID Filter Table element.*/ + flexcanFxFifoIdElementFormatC = 0x2, /*!< Four partial 8-bit Standard IDs per ID Filter Table*/ + /*! element.*/ + flexcanFxFifoIdElementFormatD = 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 FLEXCANIdTable { + bool isRemoteFrame; /*!< Remote frame*/ + bool isExtendedFrame; /*!< Extended frame*/ + uint32_t *idFilter; /*!< Rx FIFO ID filter elements*/ +} 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 reverse1 : 1; + uint32_t code : 4; + uint32_t reverse2 : 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 1*/ + uint32_t propSeg; /*!< Propagation segment*/ +} flexcan_timing_t; + +/*! @brief Flexcan module initialize 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 initialize structure. + * + * @param base CAN base pointer. + * @param initConfig CAN initialize structure(see flexcan_init_config_t above). + */ +void FLEXCAN_Init(CAN_Type* base, 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 CAN 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. + */ +void FLEXCAN_SetTiming(CAN_Type* base, 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 - 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 - 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 - 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 msgBuffIdx Index of the message buffer + * @return true : if successful; + * false : 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 msgBuffIdx Index of the message buffer. + * @param enable Choose enable or disable. + */ +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 msgBuffIdx Index of the message buffer. + * @return the individual Message Buffer interrupt flag (true and false are the flag value). + */ +bool FLEXCAN_GetMsgBufStatusFlag(CAN_Type* base, uint8_t msgBufIdx); + +/*! + * @brief Clears the interrupt flag of the message buffers. + * + * @param base FlexCAN base pointer. + * @param msgBuffIdx 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. + * @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. + * @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. + */ +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 number 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: can be set to global mode and individual mode. + */ +void FLEXCAN_SetRxMaskMode(CAN_Type* base, uint32_t mode); + +/*! + * @brief Set the remote trasmit request mask enablement. + * + * @param base FlexCAN base pointer. + * @param enable - true : Enable RTR matching judgement. + * false : Disable RTR matching judgement. + */ +void FLEXCAN_SetRxMaskRtrCmd(CAN_Type* base, uint32_t 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 - 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 - 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 - 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 - 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 - 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, please refer to RM. + * + * @param base FlexCAN base pointer. + * @return 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 + +/*! @}*/ + +#endif /* __FLEXCAN_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/drivers/inc/gpio_imx.h b/platform/drivers/inc/gpio_imx.h new file mode 100644 index 0000000..1cf60e7 --- /dev/null +++ b/platform/drivers/inc/gpio_imx.h @@ -0,0 +1,282 @@ +/* + * 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 +#include +#include +#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, + gpioPinSet = 1U +} gpio_pin_action_t; + +/*! @brief GPIO Init structure definition */ +typedef struct GpioInit +{ + 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_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 initStruct. + * + * @param base GPIO base pointer (GPIO1, GPIO2, GPIO3, etc.). + * @param initStruct pointer to a gpio_init_t structure that + * contains the configuration information. + */ +void GPIO_Init(GPIO_Type* base, gpio_init_t* initStruct); + +/*@}*/ + +/*! + * @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 (GPIO1, GPIO2, GPIO3, etc.). + * @param pin GPIO port pin number. + * @return GPIO pin input value. + * - 0: Pin logic level is 0, or is not configured for use by digital function. + * - 1: Pin logic level is 1. + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @return GPIO port input data. Each bit represents one pin. For each bit: + * - 0: Pin logic level is 0, or is not configured for use by digital function. + * - 1: Pin logic level is 1. + * - LSB: pin 0 + * - MSB: pin 31 + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @param pin GPIO port pin number. + * @return current pin output value, 0 - Low logic, 1 - High logic. + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @return current port output status. Each bit represents one pin. For each bit: + * - 0: corresponding pin is outputting logic level 0 + * - 1: corresponding pin is outputting logic level 1 + * - LSB: pin 0 + * - MSB: pin 31 + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @param pin GPIO port pin number. + * @param pinVal pin output value, one of the follow. + * -gpioPinClear: logic 0; + * -gpioPinSet: logic 1. + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @param portVal data to configure the GPIO output. Each bit represents one pin. For each bit: + * - 0: set logic level 0 to pin + * - 1: set logic level 1 to pin + * - LSB: pin 0 + * - MSB: pin 31 + */ +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 (GPIO1, GPIO2, GPIO3, etc.). + * @param pin GPIO port pin number. + * @return GPIO pin pad status value. + * - 0: Pin pad status logic level is 0. + * - 1: Pin pad status logic level is 1. + */ +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 Disable or enable the specific pin interrupt. + * + * @param base GPIO base pointer(GPIO1, GPIO2, GPIO3, etc.). + * @param pin GPIO pin number. + * @param enable enable or disable interrupt. + */ +void GPIO_SetPinIntMode(GPIO_Type* base, uint32_t pin, bool enable); + +/*! + * @brief Check individual pin interrupt status. + * + * @param base GPIO base pointer(GPIO1, GPIO2, GPIO3, etc.) + * @param pin GPIO port pin number. + * @return current pin interrupt status flag. + * - 0: interrupt is not detected. + * - 1: interrupt is detected. + */ +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(GPIO1, GPIO2, GPIO3, etc.) + * @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 Disable or enable the edge select bit to override + * the ICR register's configuration. + * + * @param base GPIO base pointer(GPIO1, GPIO2, GPIO3, etc.). + * @param pin GPIO port pin number. + * @param enable enable or disable. + */ +void GPIO_SetIntEdgeSelect(GPIO_Type* base, uint32_t pin, bool enable); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* __GPIO_IMX_H__*/ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/drivers/inc/gpt.h b/platform/drivers/inc/gpt.h new file mode 100644 index 0000000..14c3b9e --- /dev/null +++ b/platform/drivers/inc/gpt.h @@ -0,0 +1,410 @@ +/* + * 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 +#include +#include +#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 32K clock.*/ + gptClockSourceOsc = 5U /*!< Use 24M OSC clock.*/ +}; + +/*! + * @brief Input capture channel number + */ +enum _gpt_input_capture_channel { + gptInputCaptureChannel1 = 0U, + gptInputCaptureChannel2 = 1U +}; + +/*! + * @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, + gptOutputCompareChannel2 = 1U, + gptOutputCompareChannel3 = 2U +}; + +/*! + * @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 evevnt.*/ + gptStatusFlagOutputCompare2 = 1U << 1, /*!< Output compare channel 2 evevnt.*/ + gptStatusFlagOutputCompare3 = 1U << 2, /*!< Output compare channel 3 evevnt.*/ + gptStatusFlagInputCapture1 = 1U << 3, /*!< Capture channel 1 evevnt.*/ + gptStatusFlagInputCapture2 = 1U << 4, /*!< Capture channel 2 evevnt.*/ + gptStatusFlagRollOver = 1U << 5 /*!< Counter reaches maximum value and rolled over to 0 evevnt.*/ +}; + +/*! + * @brief Structure to configure the running mode. + */ +typedef struct GptModeConfig +{ + 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_mode_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 config GPT mode setting configuration. + */ +void GPT_Init(GPT_Type * base, gpt_mode_config_t *config); + +/*! + * @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 _gpt_clock_source) + */ +void GPT_SetClockSource(GPT_Type * base, uint32_t source); + +/*! + * @brief Get clock source of GPT + * + * @param base GPT base pointer. + * @return clock source (see _gpt_clock_source) + */ +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 _gpt_input_capture_channel). + * @param mode GPT input capture operation mode (see _gpt_input_operation_mode). + */ +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 _gpt_input_capture_channel). + * @return GPT input capture operation mode (see _gpt_input_operation_mode). + */ +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 _gpt_input_capture_channel). + * @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 _gpt_output_compare_channel). + * @param mode GPT output operation mode (see _gpt_output_operation_mode). + */ +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 _gpt_output_compare_channel). + * @return GPT output operation mode (see _gpt_output_operation_mode). + */ +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 _gpt_output_compare_channel). + * @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 _gpt_output_compare_channel). + * @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 _gpt_output_compare_channel). + */ +static inline void GPT_ForceOutput(GPT_Type * base, uint32_t channel) +{ + assert (channel <= gptOutputCompareChannel3); + base->CR |= (GPT_CR_FO1_MASK << channel); +} + +/*@}*/ + +/*! + * @name GPT Interupt and Status Control + * @{ + */ + +/*! + * @brief Get GPT status flag. + * + * @param base GPT base pointer. + * @param flags GPT status flag mask (see _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 _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 _gpt_status_flag for bit definition). + * @param enable Interrupt enable (true: enable, false: disable). + */ +void GPT_SetIntCmd(GPT_Type * base, uint32_t flags, bool enable); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* __GPT_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/drivers/inc/i2c_imx.h b/platform/drivers/inc/i2c_imx.h new file mode 100644 index 0000000..3d93112 --- /dev/null +++ b/platform/drivers/inc/i2c_imx.h @@ -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 +#include +#include +#include "device_imx.h" + +/*! + * @addtogroup i2c_imx_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief I2C module initialize 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, + i2cStatusAddressedAsSlave = I2C_I2SR_IAAS_MASK, + i2cStatusBusBusy = I2C_I2SR_IBB_MASK, + i2cStatusArbitrationLost = I2C_I2SR_IAL_MASK, + i2cStatusSlaveReadWrite = I2C_I2SR_SRW_MASK, + i2cStatusInterrupt = I2C_I2SR_IIF_MASK, + i2cStatusReceivedAck = I2C_I2SR_RXAK_MASK +}; + +/*! + * @brief I2C Bus role of this module. + */ +enum _i2c_work_mode +{ + i2cModeSlave = 0x0, + i2cModeMaster = I2C_I2CR_MSTA_MASK +}; + +/*! + * @brief Data transfer direction. + */ +enum _i2c_direction_mode +{ + i2cDirectionReceive = 0x0, + i2cDirectionTransmit = I2C_I2CR_MTX_MASK +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name I2C Initialization and Configuration functions + * @{ + */ + +/*! + * @brief Initialize I2C module with given initialize structure. + * + * @param base I2C base pointer. + * @param initConfig I2C initialize structure(see i2c_init_config_t above). + */ +void I2C_Init(I2C_Type* base, 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 _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 _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 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 The I2C peripheral 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 The I2C peripheral 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 Enables or disables I2C interrupt requests. + * + * @param base The I2C peripheral base pointer + * @param enable Pass true to enable interrupt, false to disable. + */ +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 defined in _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 defined in _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 + ******************************************************************************/ diff --git a/platform/drivers/inc/mu_imx.h b/platform/drivers/inc/mu_imx.h new file mode 100644 index 0000000..40bacc7 --- /dev/null +++ b/platform/drivers/inc/mu_imx.h @@ -0,0 +1,576 @@ +/* + * 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 +#include +#include +#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 tramsmit 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, please make sure the correspond general purpose + * interrupt triggerd previously has been accepted by the other core. The + * function MU_IsGeneralIntAccepted could be used for this check. If the + * previous general interrupt has not been accepted by the other core, this + * function does not trigger interrupt acctually and returns 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 will block and poll 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 untill internally + * acknowledged. During the pending period, it is not allowed to set flags again. + * This function is used to check the pending status, it could be used together + * with function MU_TrySetFlags. + * + * @param base Register base address for the module. + * @return True if pending, faulse 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, please 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 + *****************************************************************************/ diff --git a/platform/drivers/inc/rdc.h b/platform/drivers/inc/rdc.h new file mode 100644 index 0000000..6259e78 --- /dev/null +++ b/platform/drivers/inc/rdc.h @@ -0,0 +1,257 @@ +/* + * 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 +#include +#include +#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, false: disable) + */ +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 _rdc_mda in rdc_defs_.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 _rdc_mda in rdc_defs_.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 _rdc_pdap in rdc_defs_.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 _rdc_pdap in rdc_defs_.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 _rdc_pdap in rdc_defs_.h) + * @return RDC semaphore required or not (true: required, false: 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 _rdc_mr in rdc_defs_.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 _rdc_mr in rdc_defs_.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_.h) + * @return Memory region enabled or not (true: enabled, false: 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 _rdc_mr in rdc_defs_.h) + * @param violationAddr Pointer to store violation address, NULL allowed + * @param violationDomain Pointer to store domain ID causing violation, NULL allowed + * @return Memory violation occured 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 _rdc_mr in rdc_defs_.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 + ******************************************************************************/ diff --git a/platform/drivers/inc/rdc_defs_imx7d.h b/platform/drivers/inc/rdc_defs_imx7d.h new file mode 100644 index 0000000..20bff89 --- /dev/null +++ b/platform/drivers/inc/rdc_defs_imx7d.h @@ -0,0 +1,225 @@ +/* + * 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, + rdcMdaM4 = 1U, + rdcMdaPcie = 2U, + rdcMdaCsi = 3U, + rdcMdaEpdc = 4U, + rdcMdaLcdif = 5U, + rdcMdaDisplayPort = 6U, + rdcMdaPxp = 7U, + rdcMdaCoresight = 8U, + rdcMdaDap = 9U, + rdcMdaCaam = 10U, + rdcMdaSdmaPeriph = 11U, + rdcMdaSdmaBurst = 12U, + rdcMdaApbhdma = 13U, + rdcMdaRawnand = 14U, + rdcMdaUsdhc1 = 15U, + rdcMdaUsdhc2 = 16U, + rdcMdaUsdhc3 = 17U, + rdcMdaNc1 = 18U, + rdcMdaUsb = 19U, + rdcMdaNc2 = 20U, + rdcMdaTest = 21U, + rdcMdaEnet1Tx = 22U, + rdcMdaEnet1Rx = 23U, + rdcMdaEnet2Tx = 24U, + rdcMdaEnet2Rx = 25U, + rdcMdaSdmaPort = 26U +}; + +/*! + * @brief RDC peripheral assignment + */ +enum _rdc_pdap { + rdcPdapGpio1 = 0U, + rdcPdapGpio2 = 1U, + rdcPdapGpio3 = 2U, + rdcPdapGpio4 = 3U, + rdcPdapGpio5 = 4U, + rdcPdapGpio6 = 5U, + rdcPdapGpio7 = 6U, + rdcPdapIomuxcLpsrGpr = 7U, + rdcPdapWdog1 = 8U, + rdcPdapWdog2 = 9U, + rdcPdapWdog3 = 10U, + rdcPdapWdog4 = 11U, + rdcPdapIomuxcLpsr = 12U, + rdcPdapGpt1 = 13U, + rdcPdapGpt2 = 14U, + rdcPdapGpt3 = 15U, + rdcPdapGpt4 = 16U, + rdcPdapRomcp = 17U, + rdcPdapKpp = 18U, + rdcPdapIomuxc = 19U, + rdcPdapIomuxcGpr = 20U, + rdcPdapOcotpCtrl = 21U, + rdcPdapAnatopDig = 22U, + rdcPdapSnvs = 23U, + rdcPdapCcm = 24U, + rdcPdapSrc = 25U, + rdcPdapGpc = 26U, + rdcPdapSemaphore1 = 27U, + rdcPdapSemaphore2 = 28U, + rdcPdapRdc = 29U, + rdcPdapCsu = 30U, + rdcPdapReserved1 = 31U, + rdcPdapReserved2 = 32U, + rdcPdapAdc1 = 33U, + rdcPdapAdc2 = 34U, + rdcPdapEcspi4 = 35U, + rdcPdapFlexTimer1 = 36U, + rdcPdapFlexTimer2 = 37U, + rdcPdapPwm1 = 38U, + rdcPdapPwm2 = 39U, + rdcPdapPwm3 = 40U, + rdcPdapPwm4 = 41U, + rdcPdapSystemCounterRead = 42U, + rdcPdapSystemCounterCompare = 43U, + rdcPdapSystemCounterControl = 44U, + rdcPdapPcie = 45U, + rdcPdapReserved3 = 46U, + rdcPdapEpdc = 47U, + rdcPdapPxp = 48U, + rdcPdapCsi = 49U, + rdcPdapReserved4 = 50U, + rdcPdapLcdif = 51U, + rdcPdapReserved5 = 52U, + rdcPdapMipiCsi = 53U, + rdcPdapMipiDsi = 54U, + rdcPdapReserved6 = 55U, + rdcPdapTzasc = 56U, + rdcPdapDdrPhy = 57U, + rdcPdapDdrc = 58U, + rdcPdapReserved7 = 59U, + rdcPdapPerfMon1 = 60U, + rdcPdapPerfMon2 = 61U, + rdcPdapAxi = 62U, + rdcPdapQosc = 63U, + rdcPdapFlexCan1 = 64U, + rdcPdapFlexCan2 = 65U, + rdcPdapI2c1 = 66U, + rdcPdapI2c2 = 67U, + rdcPdapI2c3 = 68U, + rdcPdapI2c4 = 69U, + rdcPdapUart4 = 70U, + rdcPdapUart5 = 71U, + rdcPdapUart6 = 72U, + rdcPdapUart7 = 73U, + rdcPdapMuA = 74U, + rdcPdapMuB = 75U, + rdcPdapSemaphoreHs = 76U, + rdcPdapUsbPl301 = 77U, + rdcPdapReserved8 = 78U, + rdcPdapReserved9 = 79U, + rdcPdapReserved10 = 80U, + rdcPdapUSB1Otg1 = 81U, + rdcPdapUSB2Otg2 = 82U, + rdcPdapUSB3Host = 83U, + rdcPdapUsdhc1 = 84U, + rdcPdapUsdhc2 = 85U, + rdcPdapUsdhc3 = 86U, + rdcPdapReserved11 = 87U, + rdcPdapReserved12 = 88U, + rdcPdapSim1 = 89U, + rdcPdapSim2 = 90U, + rdcPdapQspi = 91U, + rdcPdapWeim = 92U, + rdcPdapSdma = 93U, + rdcPdapEnet1 = 94U, + rdcPdapEnet2 = 95U, + rdcPdapReserved13 = 96U, + rdcPdapReserved14 = 97U, + rdcPdapEcspi1 = 98U, + rdcPdapEcspi2 = 99U, + rdcPdapEcspi3 = 100U, + rdcPdapReserved15 = 101U, + rdcPdapUart1 = 102U, + rdcPdapReserved16 = 103U, + rdcPdapUart3 = 104U, + rdcPdapUart2 = 105U, + rdcPdapSai1 = 106U, + rdcPdapSai2 = 107U, + rdcPdapSai3 = 108U, + rdcPdapReserved17 = 109U, + rdcPdapReserved18 = 110U, + rdcPdapSpba = 111U, + rdcPdapDap = 112U, + rdcPdapReserved19 = 113U, + rdcPdapReserved20 = 114U, + rdcPdapReserved21 = 115U, + rdcPdapCaam = 116U, + rdcPdapReserved22 = 117U +}; + +/*! + * @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 + ******************************************************************************/ diff --git a/platform/drivers/inc/rdc_semaphore.h b/platform/drivers/inc/rdc_semaphore.h new file mode 100644 index 0000000..7e67e6d --- /dev/null +++ b/platform/drivers/inc/rdc_semaphore.h @@ -0,0 +1,142 @@ +/* + * 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 +#include +#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 _rdc_pdap in rdc_defs_.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 _rdc_pdap in rdc_defs_.h) + */ +void RDC_SEMAPHORE_Lock(uint32_t pdap); + +/*! + * @brief Unlock RDC semaphore + * + * @param pdap RDC peripheral assignment (see _rdc_pdap in rdc_defs_.h) + */ +void RDC_SEMAPHORE_Unlock(uint32_t pdap); + +/*! + * @brief Get domain ID which locks the semaphore + * + * @param pdap RDC peripheral assignment (see _rdc_pdap in rdc_defs_.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 _rdc_pdap in rdc_defs_.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 _rdc_pdap in rdc_defs_.h) + */ +void RDC_SEMAPHORE_Reset(uint32_t pdap); + +/*! + * @brief Reset all RDC semaphors 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 + ******************************************************************************/ diff --git a/platform/drivers/inc/sema4.h b/platform/drivers/inc/sema4.h new file mode 100644 index 0000000..55ed0e0 --- /dev/null +++ b/platform/drivers/inc/sema4.h @@ -0,0 +1,285 @@ +/* + * 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 +#include +#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, + sema4StatusFlagGate1 = 1U << 6, + sema4StatusFlagGate2 = 1U << 5, + sema4StatusFlagGate3 = 1U << 4, + sema4StatusFlagGate4 = 1U << 3, + sema4StatusFlagGate5 = 1U << 2, + sema4StatusFlagGate6 = 1U << 1, + sema4StatusFlagGate7 = 1U << 0, + sema4StatusFlagGate8 = 1U << 15, + sema4StatusFlagGate9 = 1U << 14, + sema4StatusFlagGate10 = 1U << 13, + sema4StatusFlagGate11 = 1U << 12, + sema4StatusFlagGate12 = 1U << 11, + sema4StatusFlagGate13 = 1U << 10, + sema4StatusFlagGate14 = 1U << 9, + sema4StatusFlagGate15 = 1U << 8 +}; + +/*! + * @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 could not 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 address + * @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 address + * @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 _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 _sema4_reset_state. + */ +static inline uint8_t SEMA4_GetNotificationResetState(SEMA4_Type *base) +{ + return (uint8_t)((base->RSTNTF & 0x30) >> 4); +} + +/*@}*/ + +/*! + * @name SEMA4 Interupt and Status Control + * @{ + */ + +/*! + * @brief Get SEMA4 notification status. + * + * @param base SEMA4 base pointer. + * @param flags SEMA4 gate status mask (see _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 _sema4_status_flag) + * @param enable Interrupt enable (true: enable, false: disable), only those gates + * whose intMask is set will be affected. + */ +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 _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 + ******************************************************************************/ diff --git a/platform/drivers/inc/uart_imx.h b/platform/drivers/inc/uart_imx.h new file mode 100644 index 0000000..eae3f07 --- /dev/null +++ b/platform/drivers/inc/uart_imx.h @@ -0,0 +1,769 @@ +/* + * 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 +#include +#include +#include "device_imx.h" + +/*! + * @addtogroup uart_imx_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Uart module initialize 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, + uartWordLength8Bits = UART_UCR2_WS_MASK, +}; + +/*! + * @brief UART number of stop bits. + */ +enum _uart_stop_bit_num +{ + uartStopBitNumOne = 0x0, + uartStopBitNumTwo = UART_UCR2_STPB_MASK, +}; + +/*! + * @brief UART parity mode. + */ +enum _uart_partity_mode +{ + uartParityDisable = 0x0, + uartParityEven = UART_UCR2_PREN_MASK, + uartParityOdd = UART_UCR2_PREN_MASK | UART_UCR2_PROE_MASK +}; + +/*! + * @brief Data transfer direction. + */ +enum _uart_direction_mode +{ + uartDirectionDisable = 0x0, + uartDirectionTx = UART_UCR2_TXEN_MASK, + uartDirectionRx = UART_UCR2_RXEN_MASK, + uartDirectionTxRx = UART_UCR2_TXEN_MASK | UART_UCR2_RXEN_MASK +}; + +/*! + * @brief This enumeration contains the settings for all of the UART + * interrupt configurations. + */ +enum _uart_interrupt +{ + uartIntAutoBaud = 0x0080000F, + uartIntTxReady = 0x0080000D, + uartIntIdle = 0x0080000C, + uartIntRxReady = 0x00800009, + uartIntTxEmpty = 0x00800006, + uartIntRtsDelta = 0x00800005, + uartIntEscape = 0x0084000F, + uartIntRts = 0x00840004, + uartIntAgingTimer = 0x00840003, + uartIntDtr = 0x0088000D, + uartIntParityError = 0x0088000C, + uartIntFrameError = 0x0088000B, + uartIntDcd = 0x00880009, + uartIntRi = 0x00880008, + uartIntRxDs = 0x00880006, + uartInttAirWake = 0x00880005, + uartIntAwake = 0x00880004, + uartIntDtrDelta = 0x00880003, + uartIntAutoBaudCnt = 0x00880000, + uartIntIr = 0x008C0008, + uartIntWake = 0x008C0007, + uartIntTxComplete = 0x008C0003, + uartIntBreakDetect = 0x008C0002, + uartIntRxOverrun = 0x008C0001, + uartIntRxDataReady = 0x008C0000, + uartIntRs485SlaveAddrMatch = 0x00B80003 +}; + +/*! + * @brief Flag for UART interrupt/DMA status check or polling status. + */ +enum _uart_status_flag +{ + uartStatusRxCharReady = 0x0000000F, + uartStatusRxError = 0x0000000E, + uartStatusRxOverrunError = 0x0000000D, + uartStatusRxFrameError = 0x0000000C, + uartStatusRxBreakDetect = 0x0000000B, + uartStatusRxParityError = 0x0000000A, + uartStatusParityError = 0x0094000F, + uartStatusRtsStatus = 0x0094000E, + uartStatusTxReady = 0x0094000D, + uartStatusRtsDelta = 0x0094000C, + uartStatusEscape = 0x0094000B, + uartStatusFrameError = 0x0094000A, + uartStatusRxReady = 0x00940009, + uartStatusAgingTimer = 0x00940008, + uartStatusDtrDelta = 0x00940007, + uartStatusRxDs = 0x00940006, + uartStatustAirWake = 0x00940005, + uartStatusAwake = 0x00940004, + uartStatusRs485SlaveAddrMatch = 0x00940003, + uartStatusAutoBaud = 0x0098000F, + uartStatusTxEmpty = 0x0098000E, + uartStatusDtr = 0x0098000D, + uartStatusIdle = 0x0098000C, + uartStatusAutoBaudCntStop = 0x0098000B, + uartStatusRiDelta = 0x0098000A, + uartStatusRi = 0x00980009, + uartStatusIr = 0x00980008, + uartStatusWake = 0x00980007, + uartStatusDcdDelta = 0x00980006, + uartStatusDcd = 0x00980005, + uartStatusRts = 0x00980004, + uartStatusTxComplete = 0x00980003, + uartStatusBreakDetect = 0x00980002, + uartStatusRxOverrun = 0x00980001, + uartStatusRxDataReady = 0x00980000 +}; + +/*! + * @brief The events will generate DMA Request. + */ +enum _uart_dma +{ + uartDmaRxReady = 0x00800008, + uartDmaTxReady = 0x00800003, + uartDmaAgingTimer = 0x00800002, + uartDmaIdle = 0x008C0006 +}; + +/*! + * @brief RTS pin interrupt trigger edge. + */ +enum _uart_rts_int_trigger_edge +{ + uartRtsTriggerEdgeRising = UART_UCR2_RTEC(0), + uartRtsTriggerEdgeFalling = UART_UCR2_RTEC(1), + uartRtsTriggerEdgeBoth = UART_UCR2_RTEC(2) +}; + +/*! + * @brief UART module modem role selections. + */ +enum _uart_modem_mode +{ + uartModemModeDce = 0, + uartModemModeDte = UART_UFCR_DCEDTE_MASK +}; + +/*! + * @brief DTR pin interrupt trigger edge. + */ +enum _uart_dtr_int_trigger_edge +{ + uartDtrTriggerEdgeRising = UART_UCR3_DPEC(0), + uartDtrTriggerEdgeFalling = UART_UCR3_DPEC(1), + uartDtrTriggerEdgeBoth = UART_UCR3_DPEC(2) +}; + +/*! + * @brief IrDA vote clock selections. + */ +enum _uart_irda_vote_clock +{ + uartIrdaVoteClockSampling = 0x0, + uartIrdaVoteClockReference = UART_UCR4_IRSC_MASK +}; + +/*! + * @brief UART module Rx Idle condition selections. + */ +enum _uart_rx_idle_condition +{ + uartRxIdleMoreThan4Frames = UART_UCR1_ICD(0), + uartRxIdleMoreThan8Frames = UART_UCR1_ICD(1), + uartRxIdleMoreThan16Frames = UART_UCR1_ICD(2), + uartRxIdleMoreThan32Frames = UART_UCR1_ICD(3), +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name UART Initialization and Configuration functions + * @{ + */ + +/*! + * @brief Initialize UART module with given initialize structure. + * + * @param base UART base pointer. + * @param initConfig UART initialize structure(see uart_init_config_t above). + */ +void UART_Init(UART_Type* base, 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 _uart_direction_mode enumeration above). + */ +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 _uart_idle_condition enumeration. + * + * @param base UART base pointer. + * @param idleCondition The condition that an idle condition is reported + * (see _uart_idle_condition enumeration above). + */ +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 _uart_direction_mode enumeration above). + * @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 Set true to enable 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 Set true to enable 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 uart_interrupt enumeration. + * + * @param base UART base pointer. + * @param intSource Available interrupt source for this module. + * @param enable Set true to enable 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 _uart_status_flag enumeration. + * + * @param base UART base pointer. + * @param flag Status flag to check. + * @return current state of corresponding status flag. + */ +bool UART_GetStatusFlag(UART_Type* base, uint32_t flag); + +/*! + * @brief 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 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 _uart_dma enumeration. + * + * @param base UART base pointer. + * @param dmaSource The Event that can generate DMA request. + * @param enable Set true to enable 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 Set true to enable 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 + * _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 will + * be controlled by the receiver, otherwise the CTS_B pin will + * controlled by UART_CTSPinCtrl function. + * + * @param base UART base pointer. + * @param enable Set true to enable 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 Set true: the CTS_B pin active; + * Set 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 will be 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 _uart_modem_mode enumeration above). + */ +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 will be generated. + * + * @param base UART base pointer. + * @param triggerEdge The trigger edge on which an interrupt will be generated. + * (see _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 Set true: DSR/DTR pin is logic one. + * Set 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 Set true: DCD_B pin is logic one (DCE mode) + * Set 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 Set true: RI_B pin is logic one (DCE mode) + * Set false: RI_B pin is logic zero (DCE mode) + */ +void UART_SetRiPinLevel(UART_Type* base, bool active); + +/*@}*/ + +/*! + * @name Multi-processor 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 UAER_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 UAER_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 Set true to enable 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 Set true to enable 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 will try 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 Set true to enable 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 + * _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 Set true to enable 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. + */ +void UART_SendBreakChar(UART_Type* base, bool active); + +/*! + * @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. + */ +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 + ******************************************************************************/ diff --git a/platform/drivers/inc/wdog_imx.h b/platform/drivers/inc/wdog_imx.h new file mode 100644 index 0000000..42b982e --- /dev/null +++ b/platform/drivers/inc/wdog_imx.h @@ -0,0 +1,169 @@ +/* + * 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 +#include +#include +#include "device_imx.h" + +/*! + * @addtogroup wdog_imx_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! + * @brief Structure to configure the running mode. + */ +typedef struct WdogModeConfig +{ + 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_mode_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name WDOG State Control + * @{ + */ + +/*! + * @brief Configure WDOG funtions, call once only + * + * @param base WDOG base pointer. + * @param config WDOG mode configuration + */ +static inline void WDOG_Init(WDOG_Type *base, wdog_mode_config_t *config) +{ + base->WCR |= config->wdw ? WDOG_WCR_WDW_MASK : 0 | + config->wdt ? WDOG_WCR_WDT_MASK : 0 | + config->wdbg ? WDOG_WCR_WDBG_MASK : 0 | + config->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 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 + ******************************************************************************/ diff --git a/platform/drivers/src/adc_imx7d.c b/platform/drivers/src/adc_imx7d.c new file mode 100644 index 0000000..37d98d3 --- /dev/null +++ b/platform/drivers/src/adc_imx7d.c @@ -0,0 +1,766 @@ +/* + * 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, 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) = 0x8000; + ADC_CH_B_CFG1_REG(base) = 0x0; + ADC_CH_B_CFG2_REG(base) = 0x8000; + ADC_CH_C_CFG1_REG(base) = 0x0; + ADC_CH_C_CFG2_REG(base) = 0x8000; + ADC_CH_D_CFG1_REG(base) = 0x0; + ADC_CH_D_CFG2_REG(base) = 0x8000; + ADC_CH_SW_CFG_REG(base) = 0x0; + ADC_TIMER_UNIT_REG(base) = 0x0; + ADC_DMA_FIFO_REG(base) = 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) = 0x1; +} + +/*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 initialize structure. + * + *END**************************************************************************/ +void ADC_LogicChInit(ADC_Type* base, uint8_t logicCh, 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_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; + } + } + 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 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; + break; + case adcLogicChB: + ADC_CH_B_CFG1_REG(base) |= ADC_CH_B_CFG1_CHB_SINGLE_MASK; + break; + case adcLogicChC: + ADC_CH_C_CFG1_REG(base) |= ADC_CH_C_CFG1_CHC_SINGLE_MASK; + break; + case adcLogicChD: + ADC_CH_D_CFG1_REG(base) |= ADC_CH_D_CFG1_CHD_SINGLE_MASK; + break; + case adcLogicChSW: + 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 + ******************************************************************************/ diff --git a/platform/drivers/src/ccm_analog_imx7d.c b/platform/drivers/src/ccm_analog_imx7d.c new file mode 100644 index 0000000..3493690 --- /dev/null +++ b/platform/drivers/src/ccm_analog_imx7d.c @@ -0,0 +1,75 @@ +/* + * 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_GetSysPllFreq + * Description : Get system PLL frequency + * + *END**************************************************************************/ +uint32_t CCM_ANALOG_GetSysPllFreq(CCM_ANALOG_Type * base) +{ + if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPll480Control)) + return 24000000; + + if (CCM_ANALOG_PLL_480 & CCM_ANALOG_PLL_480_DIV_SELECT_MASK) + return 528000000; + else + return 480000000; +} + +/*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 + ******************************************************************************/ diff --git a/platform/drivers/src/ccm_imx7d.c b/platform/drivers/src/ccm_imx7d.c new file mode 100644 index 0000000..55015d3 --- /dev/null +++ b/platform/drivers/src/ccm_imx7d.c @@ -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_ROOT0_PRE_PODF_MASK | CCM_TARGET_ROOT0_POST_PODF_MASK))) | + CCM_TARGET_ROOT0_PRE_PODF(pre) | CCM_TARGET_ROOT0_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_ROOT0_PRE_PODF_MASK) >> CCM_TARGET_ROOT0_PRE_PODF_SHIFT; + *post = (CCM_REG(ccmRoot) & CCM_TARGET_ROOT0_POST_PODF_MASK) >> CCM_TARGET_ROOT0_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_ROOT0_MUX_MASK | CCM_TARGET_ROOT0_PRE_PODF_MASK | CCM_TARGET_ROOT0_POST_PODF_MASK))) | + CCM_TARGET_ROOT0_MUX(mux) | CCM_TARGET_ROOT0_PRE_PODF(pre) | CCM_TARGET_ROOT0_POST_PODF(post); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/drivers/src/ecspi.c b/platform/drivers/src/ecspi.c new file mode 100644 index 0000000..bdf4aa8 --- /dev/null +++ b/platform/drivers/src/ecspi.c @@ -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 initStruct. + * + *END**************************************************************************/ +void ECSPI_Init(ECSPI_Type* base, ecspi_init_t* initStruct) +{ + /* 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(initStruct->burstLength) | + ECSPI_CONREG_CHANNEL_SELECT(initStruct->channelSelect); + ECSPI_CONREG_REG(base) |= initStruct->ecspiAutoStart ? ECSPI_CONREG_SMC_MASK : 0; + + /* ECSPI CONFIGREG Configuration */ + ECSPI_CONFIGREG_REG(base) = ECSPI_CONFIGREG_SCLK_PHA(((initStruct->clockPhase) & 1) << (initStruct->channelSelect)) | + ECSPI_CONFIGREG_SCLK_POL(((initStruct->clockPolarity) & 1) << (initStruct->channelSelect)); + + /* Master or Slave mode Configuration */ + if(initStruct->mode == ecspiMasterMode) + { + /* Set baud rate in bits per second */ + ECSPI_CONREG_REG(base) |= ECSPI_CONREG_CHANNEL_MODE(1 << (initStruct->channelSelect)); + ECSPI_SetBaudRate(base, initStruct->clockRate, initStruct->baudRate); + } + else + ECSPI_CONREG_REG(base) &= ~ECSPI_CONREG_CHANNEL_MODE(1 << (initStruct->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 : ECSPPI_SetDMACmd + * Description : Enable or disable the specified DMA Source. + * + *END**************************************************************************/ +void ECSPPI_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 + ******************************************************************************/ diff --git a/platform/drivers/src/flexcan.c b/platform/drivers/src/flexcan.c new file mode 100644 index 0000000..25177ad --- /dev/null +++ b/platform/drivers/src/flexcan.c @@ -0,0 +1,1068 @@ +/* + * 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 "flexcan.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT (31U) /*! format A&B RTR mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT (30U) /*! format A&B IDE mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_RTR_SHIFT (15U) /*! format B RTR-2 mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_IDE_SHIFT (14U) /*! format B IDE-2 mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK (0x3FFFFFFFU) /*! format A extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT (1U) /*! format A extended shift.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK (0x3FF80000U) /*! format A standard mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT (19U) /*! format A standard shift.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK (0x3FFFU) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1 (16U) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2 (0U) /*! format B extended mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK (0x7FFU) /*! format B standard mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1 (19U) /*! format B standard shift1.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2 (3U) /*! format B standard shift2.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK (0xFFU) /*! format C mask.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1 (24U) /*! format C shift1.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2 (16U) /*! format C shift2.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3 (8U) /*! format C shift3.*/ +#define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4 (0U) /*! format C shift4.*/ +#define FLEXCAN_BYTE_DATA_FIELD_MASK (0xFFU) /*! masks for byte data field.*/ +#define RxFifoFilterElementNum(x) ((x + 1) * 8) + +/******************************************************************************* + * Code + ******************************************************************************/ + +/******************************************************************************* + * FLEXCAN Freeze control function + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_EnterFreezeMode + * Description : Set FlexCAN module enter freeze mode. + * + *END**************************************************************************/ +static void FLEXCAN_EnterFreezeMode(CAN_Type* base) +{ + /* Set Freeze, Halt */ + CAN_MCR_REG(base) |= CAN_MCR_FRZ_MASK; + CAN_MCR_REG(base) |= CAN_MCR_HALT_MASK; + /* Wait for entering the freeze mode */ + while (!(CAN_MCR_REG(base) & CAN_MCR_FRZ_ACK_MASK)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ExitFreezeMode + * Description : Set FlexCAN module exit freeze mode. + * + *END**************************************************************************/ +static void FLEXCAN_ExitFreezeMode(CAN_Type* base) +{ + /* De-assert Freeze Mode */ + CAN_MCR_REG(base) &= ~CAN_MCR_HALT_MASK; + CAN_MCR_REG(base) &= ~CAN_MCR_FRZ_MASK; + /* Wait for entering the freeze mode */ + while (CAN_MCR_REG(base) & CAN_MCR_FRZ_ACK_MASK); +} + +/******************************************************************************* + * FlexCAN Initialization and Configuration functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Init + * Description : Initialize Flexcan module with given initialize structure. + * + *END**************************************************************************/ +void FLEXCAN_Init(CAN_Type* base, flexcan_init_config_t* initConfig) +{ + assert(initConfig); + + /* Enable Flexcan module */ + FLEXCAN_Enable(base); + + /* Reset Flexcan module register content to default value */ + FLEXCAN_Deinit(base); + + /* Set maximum MessageBox numbers and + * Initialize all message buffers as inactive + */ + FLEXCAN_SetMaxMsgBufNum(base, initConfig->maxMsgBufNum); + + /* Initialize Flexcan module timing character */ + FLEXCAN_SetTiming(base, &initConfig->timing); + + /* Set desired operating mode */ + FLEXCAN_SetOperatingMode(base, initConfig->operatingMode); + + /* Disable Flexcan module */ + FLEXCAN_Disable(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Deinit + * Description : This function reset Flexcan module register content to its + * default value. + * + *END**************************************************************************/ +void FLEXCAN_Deinit(CAN_Type* base) +{ + /* Reset the FLEXCAN module */ + CAN_MCR_REG(base) |= CAN_MCR_SOFT_RST_MASK; + /* Wait for reset cycle to complete */ + while (CAN_MCR_REG(base) & CAN_MCR_SOFT_RST_MASK); + + /* Assert Flexcan module Freeze */ + FLEXCAN_EnterFreezeMode(base); + + /* Reset CTRL1 Register */ + CAN_CTRL1_REG(base) = 0x0; + + /* Reset CTRL2 Register */ + CAN_CTRL2_REG(base) = 0x0; + + /* Reset Rx Individual Mask */ + for (uint8_t i=0; i < CAN_RXIMR_COUNT; i++) + CAN_RXIMR_REG(base, i) = 0x0; + + /* Reset Rx Mailboxes Global Mask */ + CAN_RXMGMASK_REG(base) = 0xFFFFFFFF; + + /* Reset Rx Buffer 14 Mask */ + CAN_RX14MASK_REG(base) = 0xFFFFFFFF; + + /* Reset Rx Buffer 15 Mask */ + CAN_RX15MASK_REG(base) = 0xFFFFFFFF; + + /* Rx FIFO Global Mask */ + CAN_RXFGMASK_REG(base) = 0xFFFFFFFF; + + /* Disable all MB interrupts */ + CAN_IMASK1_REG(base) = 0X0; + CAN_IMASK2_REG(base) = 0X0; + + // Clear all MB interrupt flags + CAN_IFLAG1_REG(base) = 0xFFFFFFFF; + CAN_IFLAG2_REG(base) = 0xFFFFFFFF; + + // Clear all Error interrupt flags + CAN_ESR1_REG(base) = 0xFFFFFFFF; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Enable + * Description : This function is used to Enable the Flexcan Module. + * + *END**************************************************************************/ +void FLEXCAN_Enable(CAN_Type* base) +{ + /* Enable clock */ + CAN_MCR_REG(base) &= ~CAN_MCR_MDIS_MASK; + /* Wait until enabled */ + while (CAN_MCR_REG(base) & CAN_MCR_LPM_ACK_MASK); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_Disable + * Description : This function is used to Disable the CAN Module. + * + *END**************************************************************************/ +void FLEXCAN_Disable(CAN_Type* base) +{ + /* Disable clock*/ + CAN_MCR_REG(base) |= CAN_MCR_MDIS_MASK; + /* Wait until disabled */ + while (!(CAN_MCR_REG(base) & CAN_MCR_LPM_ACK_MASK)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetTiming + * Description : Sets the FlexCAN time segments for setting up bit rate. + * + *END**************************************************************************/ +void FLEXCAN_SetTiming(CAN_Type* base, flexcan_timing_t* timing) +{ + assert(timing); + + /* Assert Flexcan module Freeze */ + FLEXCAN_EnterFreezeMode(base); + + /* Set Flexcan module Timing Character */ + CAN_CTRL1_REG(base) &= ~(CAN_CTRL1_PRESDIV_MASK | \ + CAN_CTRL1_RJW_MASK | \ + CAN_CTRL1_PSEG1_MASK | \ + CAN_CTRL1_PSEG2_MASK | \ + CAN_CTRL1_PROP_SEG_MASK); + CAN_CTRL1_REG(base) |= (CAN_CTRL1_PRESDIV(timing->preDiv) | \ + CAN_CTRL1_RJW(timing->rJumpwidth) | \ + CAN_CTRL1_PSEG1(timing->phaseSeg1) | \ + CAN_CTRL1_PSEG2(timing->phaseSeg2) | \ + CAN_CTRL1_PROP_SEG(timing->propSeg)); + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetOperatingMode + * Description : Set operation mode. + * + *END**************************************************************************/ +void FLEXCAN_SetOperatingMode(CAN_Type* base, uint8_t mode) +{ + assert((mode & flexCanNormalMode) || + (mode & flexcanListenOnlyMode) || + (mode & flexcanLoopBackMode)); + + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (mode & flexCanNormalMode) + CAN_MCR_REG(base) &= ~CAN_MCR_SUPV_MASK; + else + CAN_MCR_REG(base) |= CAN_MCR_SUPV_MASK; + + if (mode & flexcanListenOnlyMode) + CAN_CTRL1_REG(base) |= CAN_CTRL1_LOM_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LOM_MASK; + + if (mode & flexcanLoopBackMode) + CAN_CTRL1_REG(base) |= CAN_CTRL1_LPB_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LPB_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMaxMsgBufNum + * Description : Set the maximum number of Message Buffers. + * + *END**************************************************************************/ +void FLEXCAN_SetMaxMsgBufNum(CAN_Type* base, uint32_t bufNum) +{ + assert((bufNum <= CAN_CS_COUNT) && (bufNum > 0)); + + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the maximum number of MBs*/ + CAN_MCR_REG(base) = (CAN_MCR_REG(base) & (~CAN_MCR_MAXMB_MASK)) | CAN_MCR_MAXMB(bufNum-1); + + /* Clean MBs content to default value */ + for (uint8_t i = 0; i < bufNum; i++) + { + base->MB[i].CS = 0x0; + base->MB[i].ID = 0x0; + base->MB[i].WORD0 = 0x0; + base->MB[i].WORD1 = 0x0; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAbortCmd + * Description : Set the Transmit abort feature enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetAbortCmd(CAN_Type* base, bool enable) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_MCR_REG(base) |= CAN_MCR_AEN_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_AEN_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetLocalPrioCmd + * Description : Set the local transmit priority enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetLocalPrioCmd(CAN_Type* base, bool enable) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + { + CAN_MCR_REG(base) |= CAN_MCR_LPRIO_EN_MASK; + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_LBUF_MASK; + } + else + { + CAN_CTRL1_REG(base) |= CAN_CTRL1_LBUF_MASK; + CAN_MCR_REG(base) &= ~CAN_MCR_LPRIO_EN_MASK; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMatchPrioCmd + * Description : Set the Rx matching process priority. + * + *END**************************************************************************/ +void FLEXCAN_SetMatchPrioCmd(CAN_Type* base, bool priority) +{ + /* Assert Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + if (priority) + CAN_CTRL2_REG(base) |= CAN_CTRL2_MRP_MASK; + else + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_MRP_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * FlexCAN Message buffer control functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetMsgBufPtr + * Description : Get message buffer pointer for transition. + * + *END**************************************************************************/ +flexcan_msgbuf_t* FLEXCAN_GetMsgBufPtr(CAN_Type* base, uint8_t msgBufIdx) +{ + assert(msgBufIdx < CAN_CS_COUNT); + + return (flexcan_msgbuf_t*) &base->MB[msgBufIdx]; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_LockRxMsgBuf + * Description : Locks the FlexCAN Rx message buffer. + * + *END**************************************************************************/ +bool FLEXCAN_LockRxMsgBuf(CAN_Type* base, uint8_t msgBufIdx) +{ + volatile uint32_t temp; + + /* Check if the MB to be Locked is enabled */ + if (msgBufIdx > (CAN_MCR_REG(base) & CAN_MCR_MAXMB_MASK)) + return false; + + /* ARM Core read MB's CS to lock MB */ + temp = base->MB[msgBufIdx].CS; + + /* Read temp itself to avoid ARMGCC warning */ + temp++; + + return true; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_UnlockAllRxMsgBuf + * Description : Unlocks the FlexCAN Rx message buffer. + * + *END**************************************************************************/ +uint16_t FLEXCAN_UnlockAllRxMsgBuf(CAN_Type* base) +{ + /* Read Free Running Timer to unlock all MessageBox */ + return CAN_TIMER_REG(base); +} + +/******************************************************************************* + * FlexCAN Interrupts and flags management functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetMsgBufIntCmd + * Description : Enables/Disables the FlexCAN Message Buffer interrupt. + * + *END**************************************************************************/ +void FLEXCAN_SetMsgBufIntCmd(CAN_Type* base, uint8_t msgBufIdx, bool enable) +{ + volatile uint32_t* interruptMaskPtr; + uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + { + index = msgBufIdx - 32; + interruptMaskPtr = &base->IMASK2; + } + else + { + index = msgBufIdx; + interruptMaskPtr = &base->IMASK1; + } + + if (enable) + *interruptMaskPtr |= 0x1 << index; + else + *interruptMaskPtr &= ~(0x1 << index); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetMsgBufStatusFlag + * Description : Gets the individual FlexCAN MB interrupt flag. + * + *END**************************************************************************/ +bool FLEXCAN_GetMsgBufStatusFlag(CAN_Type* base, uint8_t msgBufIdx) +{ + volatile uint32_t* interruptFlagPtr; + volatile uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + { + index = msgBufIdx - 32; + interruptFlagPtr = &base->IFLAG2; + } + else + { + index = msgBufIdx; + interruptFlagPtr = &base->IFLAG1; + } + + return (bool)((*interruptFlagPtr >> index) & 0x1); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ClearMsgBufStatusFlag + * Description : Clears the interrupt flag of the message buffers. + * + *END**************************************************************************/ +void FLEXCAN_ClearMsgBufStatusFlag(CAN_Type* base, uint32_t msgBufIdx) +{ + volatile uint8_t index; + + assert(msgBufIdx < CAN_CS_COUNT); + + if (msgBufIdx > 0x31) + index = msgBufIdx - 32; + else + index = msgBufIdx; + + /* The Interrupt flag must be cleared by writing it to '1'. + * Writing '0' has no effect. + */ + base->IFLAG1 = 0x1 << index; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetErrIntCmd + * Description : Enables error interrupt of the FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_SetErrIntCmd(CAN_Type* base, uint32_t errorType, bool enable) +{ + assert((errorType & flexcanIntRxWarning) || + (errorType & flexcanIntTxWarning) || + (errorType & flexcanIntWakeUp) || + (errorType & flexcanIntBusOff) || + (errorType & flexcanIntError)); + + if (enable) + { + if (errorType & flexcanIntRxWarning) + { + CAN_MCR_REG(base) |= CAN_MCR_WRN_EN_MASK; + CAN_CTRL1_REG(base) |= CAN_CTRL1_RWRN_MSK_MASK; + } + + if (errorType & flexcanIntTxWarning) + { + CAN_MCR_REG(base) |= CAN_MCR_WRN_EN_MASK; + CAN_CTRL1_REG(base) |= CAN_CTRL1_TWRN_MSK_MASK; + } + + if (errorType & flexcanIntWakeUp) + CAN_MCR_REG(base) |= CAN_MCR_WAK_MSK_MASK; + + if (errorType & flexcanIntBusOff) + CAN_CTRL1_REG(base) |= CAN_CTRL1_BOFF_MSK_MASK; + + if (errorType & flexcanIntError) + CAN_CTRL1_REG(base) |= CAN_CTRL1_ERR_MSK_MASK; + } + else + { + if (errorType & flexcanIntRxWarning) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_RWRN_MSK_MASK; + + if (errorType & flexcanIntTxWarning) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_TWRN_MSK_MASK; + + if (errorType & flexcanIntWakeUp) + CAN_MCR_REG(base) &= ~CAN_MCR_WAK_MSK_MASK; + + if (errorType & flexcanIntBusOff) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_BOFF_MSK_MASK; + + if (errorType & flexcanIntError) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_ERR_MSK_MASK; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetErrStatusFlag + * Description : Gets the FlexCAN module interrupt flag. + * + *END**************************************************************************/ +uint32_t FLEXCAN_GetErrStatusFlag(CAN_Type* base, uint32_t errFlags) +{ + return CAN_ESR1_REG(base) & errFlags; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_ClearErrStatusFlag + * Description : Clears the interrupt flag of the FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_ClearErrStatusFlag(CAN_Type* base, uint32_t errorType) +{ + /* The Interrupt flag must be cleared by writing it to '1'. + * Writing '0' has no effect. + */ + CAN_ESR1_REG(base) = errorType; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetErrCounter + * Description : Get the error counter of FlexCAN module. + * + *END**************************************************************************/ +void FLEXCAN_GetErrCounter(CAN_Type* base, uint8_t* txError, uint8_t* rxError) +{ + *txError = CAN_ECR_REG(base) & CAN_ECR_Tx_Err_Counter_MASK; + *rxError = (CAN_ECR_REG(base) & CAN_ECR_Rx_Err_Counter_MASK) >> \ + CAN_ECR_Rx_Err_Counter_SHIFT; +} + +/******************************************************************************* + * Rx FIFO management functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_EnableRxFifo + * Description : Enables the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_EnableRxFifo(CAN_Type* base, uint8_t numOfFilters) +{ + uint8_t maxNumMb; + + assert(numOfFilters <= 0xF); + + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the number of the RX FIFO filters needed*/ + CAN_CTRL2_REG(base) = (CAN_CTRL2_REG(base) & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(numOfFilters); + + /* Enable RX FIFO*/ + CAN_MCR_REG(base) |= CAN_MCR_RFEN_MASK; + + /* RX FIFO global mask*/ + CAN_RXFGMASK_REG(base) = CAN_RXFGMASK_FGM31_FGM0_MASK; + + maxNumMb = (CAN_MCR_REG(base) & CAN_MCR_MAXMB_MASK) + 1; + + for (uint8_t i = 0; i < maxNumMb; i++) + { + /* RX individual mask*/ + CAN_RXIMR_REG(base,i) = CAN_RXIMR0_RXIMR63_MI31_MI0_MASK; + } + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_DisableRxFifo + * Description : Disables the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_DisableRxFifo(CAN_Type* base) +{ + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Disable RX FIFO*/ + CAN_MCR_REG(base) &= ~CAN_MCR_RFEN_MASK; + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoFilterNum + * Description : Set the number of the Rx FIFO filters. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoFilterNum(CAN_Type* base, uint32_t numOfFilters) +{ + assert(numOfFilters <= 0xF); + + /* Set Freeze mode*/ + FLEXCAN_EnterFreezeMode(base); + + /* Set the number of RX FIFO ID filters*/ + CAN_CTRL2_REG(base) = (CAN_CTRL2_REG(base) & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(numOfFilters); + + /* De-assert Freeze Mode*/ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoFilter + * Description : Set the FlexCAN Rx FIFO fields. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoFilter(CAN_Type* base, uint32_t idFormat, flexcan_id_table_t *idFilterTable) +{ + /* Set RX FIFO ID filter table elements*/ + uint32_t i, j, numOfFilters; + uint32_t val1 = 0, val2 = 0, val = 0; + volatile uint32_t *filterTable; + + numOfFilters = (CAN_CTRL2_REG(base) & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT; + /* Rx FIFO Ocuppied First Message Box is MB6 */ + filterTable = (volatile uint32_t *)&(base->MB[6]); + + CAN_MCR_REG(base) |= CAN_MCR_IDAM(idFormat); + + switch (idFormat) + { + case flexcanFxFifoIdElementFormatA: + /* One full ID (standard and extended) per ID Filter Table element.*/ + if (idFilterTable->isRemoteFrame) + { + val = (uint32_t)0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT; + } + if (idFilterTable->isExtendedFrame) + { + val |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT; + } + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + if(idFilterTable->isExtendedFrame) + { + filterTable[i] = val + ((*(idFilterTable->idFilter + i)) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK); + }else + { + filterTable[i] = val + ((*(idFilterTable->idFilter + i)) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK); + } + } + break; + case flexcanFxFifoIdElementFormatB: + /* Two full standard IDs or two partial 14-bit (standard and extended) IDs*/ + /* per ID Filter Table element.*/ + if (idFilterTable->isRemoteFrame) + { + val1 = (uint32_t)0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_RTR_SHIFT; + val2 = 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_RTR_SHIFT; + } + if (idFilterTable->isExtendedFrame) + { + val1 |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATAB_IDE_SHIFT; + val2 |= 0x1 << FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_IDE_SHIFT; + } + j = 0; + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + if (idFilterTable->isExtendedFrame) + { + filterTable[i] = val1 + (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1); + filterTable[i] |= val2 + (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2); + }else + { + filterTable[i] = val1 + (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1); + filterTable[i] |= val2 + (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2); + } + j = j + 2; + } + break; + case flexcanFxFifoIdElementFormatC: + /* Four partial 8-bit Standard IDs per ID Filter Table element.*/ + j = 0; + for (i = 0; i < RxFifoFilterElementNum(numOfFilters); i++) + { + filterTable[i] = (((*(idFilterTable->idFilter + j)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1); + filterTable[i] = (((*(idFilterTable->idFilter + j + 1)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2); + filterTable[i] = (((*(idFilterTable->idFilter + j + 2)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3); + filterTable[i] = (((*(idFilterTable->idFilter + j + 3)) & + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK) << + FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4); + j = j + 4; + } + break; + case flexcanFxFifoIdElementFormatD: + /* All frames rejected.*/ + break; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetRxFifoPtr + * Description : Gets the FlexCAN Rx FIFO data pointer. + * + *END**************************************************************************/ +flexcan_msgbuf_t* FLEXCAN_GetRxFifoPtr(CAN_Type* base) +{ + /* Rx-Fifo occupy MB0 ~ MB5 */ + return (flexcan_msgbuf_t*)&base->MB; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_GetRxFifoInfo + * Description : Set the FlexCAN RX Fifo global mask. + * + *END**************************************************************************/ +uint16_t FLEXCAN_GetRxFifoInfo(CAN_Type* base) +{ + return CAN_RXFIR_REG(base) & CAN_RXFIR_IDHIT_MASK; +} + +/******************************************************************************* + * Rx Mask Setting functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMaskMode + * Description : Set the Rx masking mode. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMaskMode(CAN_Type* base, uint32_t mode) +{ + assert((mode == flexcanRxMaskGlobal) || + (mode == flexcanRxMaskIndividual)); + + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (mode == flexcanRxMaskIndividual) + CAN_MCR_REG(base) |= CAN_MCR_IRMQ_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_IRMQ_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMaskRtrCmd + * Description : Set the remote trasmit request mask enablement. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMaskRtrCmd(CAN_Type* base, uint32_t enable) +{ + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL2_REG(base) |= CAN_CTRL2_EACEN_MASK; + else + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_EACEN_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxGlobalMask + * Description : Set the FlexCAN RX global mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxGlobalMask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RXMGMASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxIndividualMask + * Description : Set the FlexCAN Rx individual mask for ID filtering in + * the Rx MBs and the Rx FIFO. + * + *END**************************************************************************/ +void FLEXCAN_SetRxIndividualMask(CAN_Type* base, uint32_t msgBufIdx, uint32_t mask) +{ + assert(msgBufIdx < CAN_RXIMR_COUNT); + + /* Assert Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + CAN_RXIMR_REG(base,msgBufIdx) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMsgBuff14Mask + * Description : Set the FlexCAN RX Message Buffer BUF14 mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMsgBuff14Mask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RX14MASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxMsgBuff15Mask + * Description : Set the FlexCAN RX Message Buffer BUF15 mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxMsgBuff15Mask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RX15MASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxFifoGlobalMask + * Description : Set the FlexCAN RX Fifo global mask. + * + *END**************************************************************************/ +void FLEXCAN_SetRxFifoGlobalMask(CAN_Type* base, uint32_t mask) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + /* load mask */ + CAN_RXFGMASK_REG(base) = mask; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * Misc. Functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetSelfWakeUpCmd + * Description : Enable/disable the FlexCAN self wakeup feature. + * + *END**************************************************************************/ +void FLEXCAN_SetSelfWakeUpCmd(CAN_Type* base, bool lpfEnable, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (lpfEnable) + CAN_MCR_REG(base) |= CAN_MCR_WAK_SRC_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_WAK_SRC_MASK; + + if (enable) + CAN_MCR_REG(base) |= CAN_MCR_SLF_WAK_MASK; + else + CAN_MCR_REG(base) &= ~CAN_MCR_SLF_WAK_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetSelfReceptionCmd + * Description : Enable/disable the FlexCAN self reception feature. + * + *END**************************************************************************/ +void FLEXCAN_SetSelfReceptionCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_MCR_REG(base) &= ~CAN_MCR_SRX_DIS_MASK; + else + CAN_MCR_REG(base) |= CAN_MCR_SRX_DIS_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetRxVoteCmd + * Description : Enable/disable the enhance FlexCAN Rx vote. + * + *END**************************************************************************/ +void FLEXCAN_SetRxVoteCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL1_REG(base) |= CAN_CTRL1_SMP_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_SMP_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAutoBusOffRecoverCmd + * Description : Enable/disable the Auto Busoff recover feature. + * + *END**************************************************************************/ +void FLEXCAN_SetAutoBusOffRecoverCmd(CAN_Type* base, bool enable) +{ + if (enable) + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_BOFF_MSK_MASK; + else + CAN_CTRL1_REG(base) |= CAN_CTRL1_BOFF_MSK_MASK; +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetTimeSyncCmd + * Description : Enable/disable the Time Sync feature. + * + *END**************************************************************************/ +void FLEXCAN_SetTimeSyncCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL1_REG(base) |= CAN_CTRL1_TSYN_MASK; + else + CAN_CTRL1_REG(base) &= ~CAN_CTRL1_TSYN_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/*FUNCTION********************************************************************** + * + * Function Name : FLEXCAN_SetAutoRemoteResponseCmd + * Description : Enable/disable the Auto Remote Response feature. + * + *END**************************************************************************/ +void FLEXCAN_SetAutoRemoteResponseCmd(CAN_Type* base, bool enable) +{ + /* Set Freeze mode */ + FLEXCAN_EnterFreezeMode(base); + + if (enable) + CAN_CTRL2_REG(base) &= ~CAN_CTRL2_RRS_MASK; + else + CAN_CTRL2_REG(base) |= CAN_CTRL2_RRS_MASK; + + /* De-assert Freeze Mode */ + FLEXCAN_ExitFreezeMode(base); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/drivers/src/gpio_imx.c b/platform/drivers/src/gpio_imx.c new file mode 100644 index 0000000..9029876 --- /dev/null +++ b/platform/drivers/src/gpio_imx.c @@ -0,0 +1,160 @@ +/* + * 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 initStruct. + * + *END**************************************************************************/ +void GPIO_Init(GPIO_Type* base, gpio_init_t* initStruct) +{ + 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 = initStruct->pin; + + /* Configure GPIO pin direction */ + if (initStruct->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(initStruct->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 : Disable or enable 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 : Disable or enable 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 + ******************************************************************************/ diff --git a/platform/drivers/src/gpt.c b/platform/drivers/src/gpt.c new file mode 100644 index 0000000..a9c8a21 --- /dev/null +++ b/platform/drivers/src/gpt.c @@ -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, gpt_mode_config_t *config) +{ + assert(config); + + base->CR = 0; + + GPT_SoftReset(base); + + base->CR = (config->freeRun ? GPT_CR_FRR_MASK : 0) | + (config->waitEnable ? GPT_CR_WAITEN_MASK : 0) | + (config->stopEnable ? GPT_CR_STOPEN_MASK : 0) | + (config->dozeEnable ? GPT_CR_DOZEEN_MASK : 0) | + (config->dbgEnable ? GPT_CR_DBGEN_MASK : 0) | + (config->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_ENABLE_24MHZ_MASK | GPT_CR_CLKSRC(source); + else + base->CR = (base->CR & ~(GPT_CR_CLKSRC_MASK | GPT_CR_ENABLE_24MHZ_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 + ******************************************************************************/ diff --git a/platform/drivers/src/i2c_imx.c b/platform/drivers/src/i2c_imx.c new file mode 100644 index 0000000..9475c15 --- /dev/null +++ b/platform/drivers/src/i2c_imx.c @@ -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, 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 + ******************************************************************************/ diff --git a/platform/drivers/src/mu_imx.c b/platform/drivers/src/mu_imx.c new file mode 100644 index 0000000..7a142fe --- /dev/null +++ b/platform/drivers/src/mu_imx.c @@ -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 + ******************************************************************************/ diff --git a/platform/drivers/src/rdc.c b/platform/drivers/src/rdc.c new file mode 100644 index 0000000..30cba44 --- /dev/null +++ b/platform/drivers/src/rdc.c @@ -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 + ******************************************************************************/ diff --git a/platform/drivers/src/rdc_semaphore.c b/platform/drivers/src/rdc_semaphore.c new file mode 100644 index 0000000..3f97d90 --- /dev/null +++ b/platform/drivers/src/rdc_semaphore.c @@ -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 +#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 + ******************************************************************************/ diff --git a/platform/drivers/src/sema4.c b/platform/drivers/src/sema4.c new file mode 100644 index 0000000..aabdfec --- /dev/null +++ b/platform/drivers/src/sema4.c @@ -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 +#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 + ******************************************************************************/ diff --git a/platform/drivers/src/uart_imx.c b/platform/drivers/src/uart_imx.c new file mode 100644 index 0000000..3c5149d --- /dev/null +++ b/platform/drivers/src/uart_imx.c @@ -0,0 +1,601 @@ +/* + * 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, 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) = 0x00000000; + UART_UCR2_REG(base) = 0x00000001; + UART_UCR3_REG(base) = 0x00000700; + UART_UCR4_REG(base) = 0x00008000; + UART_UFCR_REG(base) = 0x00000801; + UART_UESC_REG(base) = 0x0000002B; + UART_UTIM_REG(base) = 0x00000000; + UART_ONEMS_REG(base) = 0x00000000; + UART_UTS_REG(base) = 0x00000060; + UART_UMCR_REG(base) = 0x00000000; + + /* 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 * refFreqDiv)); +} + +/*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((uartModemModeDce & uartModemModeDce) || (uartModemModeDce & 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; +} + +/******************************************************************************* + * Multi-processor and RS-485 functions + ******************************************************************************/ +/*FUNCTION********************************************************************** + * + * Function Name : UAER_Putchar9 + * Description : This function is used to send 9 Bits length data in + * RS-485 Multidrop mode. + * + *END**************************************************************************/ +void UAER_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 : UAER_Getchar9 + * Description : This functions is used to receive 9 Bits length data in + * RS-485 Multidrop mode. + * + *END**************************************************************************/ +uint16_t UAER_Getchar9(UART_Type* base) +{ + uint16_t rxData = 0; + + if (UART_URXD_REG(base) & UART_URXD_PRERR_MASK) + rxData |= 0x0100; + rxData |= (UART_URXD_REG(base) & UART_URXD_RX_DATA_MASK); + 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 + ******************************************************************************/ diff --git a/platform/drivers/src/wdog_imx.c b/platform/drivers/src/wdog_imx.c new file mode 100644 index 0000000..c8c62d2 --- /dev/null +++ b/platform/drivers/src/wdog_imx.c @@ -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 + ******************************************************************************/ -- cgit v1.2.3