diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2016-01-12 14:06:54 -0800 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2016-01-12 14:06:54 -0800 |
commit | a57cc2c988482010061b9e68344fdf1969889763 (patch) | |
tree | 5c050337492ce27c09b47421b123980b5a79f8d9 /platform/drivers/src |
initial commit, FreeRTOS_BSP_1.0.0_iMX7D
Diffstat (limited to 'platform/drivers/src')
-rw-r--r-- | platform/drivers/src/adc_imx7d.c | 766 | ||||
-rw-r--r-- | platform/drivers/src/ccm_analog_imx7d.c | 75 | ||||
-rw-r--r-- | platform/drivers/src/ccm_imx7d.c | 85 | ||||
-rw-r--r-- | platform/drivers/src/ecspi.c | 205 | ||||
-rw-r--r-- | platform/drivers/src/flexcan.c | 1068 | ||||
-rw-r--r-- | platform/drivers/src/gpio_imx.c | 160 | ||||
-rw-r--r-- | platform/drivers/src/gpt.c | 91 | ||||
-rw-r--r-- | platform/drivers/src/i2c_imx.c | 167 | ||||
-rw-r--r-- | platform/drivers/src/mu_imx.c | 155 | ||||
-rw-r--r-- | platform/drivers/src/rdc.c | 89 | ||||
-rw-r--r-- | platform/drivers/src/rdc_semaphore.c | 187 | ||||
-rw-r--r-- | platform/drivers/src/sema4.c | 199 | ||||
-rw-r--r-- | platform/drivers/src/uart_imx.c | 601 | ||||
-rw-r--r-- | platform/drivers/src/wdog_imx.c | 81 |
14 files changed, 3929 insertions, 0 deletions
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 <assert.h> +#include "rdc_semaphore.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +/******************************************************************************* + * Private Functions + ******************************************************************************/ +static RDC_SEMAPHORE_Type *RDC_SEMAPHORE_GetGate(uint32_t *pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + + if (*pdap < 64) + semaphore = RDC_SEMAPHORE1; + else + { + semaphore = RDC_SEMAPHORE2; + *pdap -= 64; + } + + return semaphore; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_TryLock + * Description : Lock RDC semaphore for shared peripheral access + * + *END**************************************************************************/ +rdc_semaphore_status_t RDC_SEMAPHORE_TryLock(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1); + + return ((semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) == + RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1)) ? + statusRdcSemaphoreSuccess : statusRdcSemaphoreBusy; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_Lock + * Description : Lock RDC semaphore for shared peripheral access, polling until + * success. + * + *END**************************************************************************/ +void RDC_SEMAPHORE_Lock(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + do { + /* Wait gate status free */ + while (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) { } + semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1); + } while ((semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) != + RDC_SEMAPHORE_GATE_GTFSM(RDC_SEMAPHORE_MASTER_SELF + 1)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_Unlock + * Description : Unlock RDC semaphore + * + *END**************************************************************************/ +void RDC_SEMAPHORE_Unlock(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + semaphore->GATE[index] = RDC_SEMAPHORE_GATE_GTFSM(0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_GetLockDomainID + * Description : Get domain ID which locks the semaphore + * + *END**************************************************************************/ +uint32_t RDC_SEMAPHORE_GetLockDomainID(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + return (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_LDOM_MASK) >> RDC_SEMAPHORE_GATE_LDOM_SHIFT; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_GetLockMaster + * Description : Get master index which locks the semaphore + * + *END**************************************************************************/ +uint32_t RDC_SEMAPHORE_GetLockMaster(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + uint8_t master; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + master = (semaphore->GATE[index] & RDC_SEMAPHORE_GATE_GTFSM_MASK) >> RDC_SEMAPHORE_GATE_GTFSM_SHIFT; + + return master == 0 ? RDC_SEMAPHORE_MASTER_NONE : master - 1; +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_Reset + * Description : Reset RDC semaphore to unlocked status + * + *END**************************************************************************/ +void RDC_SEMAPHORE_Reset(uint32_t pdap) +{ + RDC_SEMAPHORE_Type *semaphore; + uint32_t index = pdap; + + semaphore = RDC_SEMAPHORE_GetGate(&index); + + /* The reset state machine must be in idle state */ + assert ((semaphore->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK) == 0); + + semaphore->RSTGT_W = 0xE2; + semaphore->RSTGT_W = 0x1D | RDC_SEMAPHORE_RSTGT_W_RSTGTN(index); +} + +/*FUNCTION********************************************************************** + * + * Function Name : RDC_SEMAPHORE_ResetAll + * Description : Reset all RDC semaphores to unlocked status for certain + * RDC_SEMAPHORE instance + * + *END**************************************************************************/ +void RDC_SEMAPHORE_ResetAll(RDC_SEMAPHORE_Type *base) +{ + /* The reset state machine must be in idle state */ + assert ((base->RSTGT_R & RDC_SEMAPHORE_RSTGT_R_RSTGSM_MASK) == 0); + + base->RSTGT_W = 0xE2; + base->RSTGT_W = 0x1D | RDC_SEMAPHORE_RSTGT_W_RSTGTN_MASK; +} + +/******************************************************************************* + * EOF + ******************************************************************************/ 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 <assert.h> +#include "sema4.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_TryLock + * Description : Lock SEMA4 gate for exclusive access between multicore + * + *END**************************************************************************/ +sema4_status_t SEMA4_TryLock(SEMA4_Type *base, uint32_t gateIndex) +{ + __IO uint8_t *gate; + + assert(gateIndex < 16); + + gate = &base->GATE00 + gateIndex; + + *gate = SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1); + + return ((*gate & SEMA4_GATE00_GTFSM_MASK) == SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1)) ? + statusSema4Success : statusSema4Busy; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_Lock + * Description : Lock SEMA4 gate for exclusive access between multicore, + * polling until success + * + *END**************************************************************************/ +void SEMA4_Lock(SEMA4_Type *base, uint32_t gateIndex) +{ + __IO uint8_t *gate; + + assert(gateIndex < 16); + + gate = &base->GATE00 + gateIndex; + + do { + /* Wait gate status free */ + while (*gate & SEMA4_GATE00_GTFSM_MASK) { } + *gate = SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1); + } while ((*gate & SEMA4_GATE00_GTFSM_MASK) != SEMA4_GATE00_GTFSM(SEMA4_PROCESSOR_SELF + 1)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_Unlock + * Description : Unlock SEMA4 gate + * + *END**************************************************************************/ +void SEMA4_Unlock(SEMA4_Type *base, uint32_t gateIndex) +{ + __IO uint8_t *gate; + + assert(gateIndex < 16); + + gate = &base->GATE00 + gateIndex; + + *gate = SEMA4_GATE00_GTFSM(0); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_GetLockProcessor + * Description : Get master index which locks the semaphore + * + *END**************************************************************************/ +uint32_t SEMA4_GetLockProcessor(SEMA4_Type *base, uint32_t gateIndex) +{ + __IO uint8_t *gate; + uint8_t proc; + + assert(gateIndex < 16); + + gate = &base->GATE00 + gateIndex; + + proc = (*gate & SEMA4_GATE00_GTFSM_MASK) >> SEMA4_GATE00_GTFSM_SHIFT; + + return proc == 0 ? SEMA4_PROCESSOR_NONE : proc - 1; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_ResetGate + * Description : Reset SEMA4 gate to unlocked status + * + *END**************************************************************************/ +void SEMA4_ResetGate(SEMA4_Type *base, uint32_t gateIndex) +{ + assert(gateIndex < 16); + + /* The reset state machine must be in idle state */ + assert ((base->RSTGT & 0x30) == 0); + + base->RSTGT = 0xE2; + base->RSTGT = 0x1D | SEMA4_RSTGT_RSTGTN(gateIndex); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_ResetAllGates + * Description : Reset all SEMA4 gates to unlocked status for certain + * SEMA4 instance + * + *END**************************************************************************/ +void SEMA4_ResetAllGates(SEMA4_Type *base) +{ + /* The reset state machine must be in idle state */ + assert ((base->RSTGT & 0x30) == 0); + + base->RSTGT = 0xE2; + base->RSTGT = 0x1D | SEMA4_RSTGT_RSTGTN_MASK; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_ResetNotification + * Description : Reset SEMA4 IRQ notifications + * + *END**************************************************************************/ +void SEMA4_ResetNotification(SEMA4_Type *base, uint32_t gateIndex) +{ + assert(gateIndex < 16); + + /* The reset state machine must be in idle state */ + assert ((base->RSTNTF & 0x30) == 0); + + base->RSTNTF = 0x47; + base->RSTNTF = 0xB8 | SEMA4_RSTNTF_RSTNTN(gateIndex); +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_ResetAllNotifications + * Description : Reset all SEMA4 gates to unlocked status for certain + * SEMA4 instance + * + *END**************************************************************************/ +void SEMA4_ResetAllNotifications(SEMA4_Type *base) +{ + /* The reset state machine must be in idle state */ + assert ((base->RSTNTF & 0x30) == 0); + + base->RSTNTF = 0x47; + base->RSTNTF = 0xB8 | SEMA4_RSTNTF_RSTNTN_MASK; +} + +/*FUNCTION********************************************************************** + * + * Function Name : SEMA4_SetIntCmd + * Description : Enable or disable SEMA4 IRQ notification. + * + *END**************************************************************************/ +void SEMA4_SetIntCmd(SEMA4_Type * base, uint16_t intMask, bool enable) +{ + if (enable) + base->CPnINE[SEMA4_PROCESSOR_SELF].INE |= intMask; + else + base->CPnINE[SEMA4_PROCESSOR_SELF].INE &= ~intMask; +} + +/******************************************************************************* + * EOF + ******************************************************************************/ 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 + ******************************************************************************/ |