diff options
Diffstat (limited to 'bsps/arm/imxrt/nxp/devices')
67 files changed, 0 insertions, 54398 deletions
diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c deleted file mode 100644 index d93de620c0..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc.c +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_adc.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.adc_12b1msps_sar" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for ADC module. - * - * @param base ADC peripheral base address - */ -static uint32_t ADC_GetInstance(ADC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to ADC bases for each instance. */ -static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to ADC clocks for each instance. */ -static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t ADC_GetInstance(ADC_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++) - { - if (s_adcBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_adcBases)); - - return instance; -} - -/*! - * brief Initialize the ADC module. - * - * param base ADC peripheral base address. - * param config Pointer to "adc_config_t" structure. - */ -void ADC_Init(ADC_Type *base, const adc_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock. */ - CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - /* ADCx_CFG */ - tmp32 = base->CFG & (ADC_CFG_AVGS_MASK | ADC_CFG_ADTRG_MASK); /* Reserve AVGS and ADTRG bits. */ - tmp32 |= ADC_CFG_REFSEL(config->referenceVoltageSource) | ADC_CFG_ADSTS(config->samplePeriodMode) | - ADC_CFG_ADICLK(config->clockSource) | ADC_CFG_ADIV(config->clockDriver) | ADC_CFG_MODE(config->resolution); - if (config->enableOverWrite) - { - tmp32 |= ADC_CFG_OVWREN_MASK; - } - if (config->enableLongSample) - { - tmp32 |= ADC_CFG_ADLSMP_MASK; - } - if (config->enableLowPower) - { - tmp32 |= ADC_CFG_ADLPC_MASK; - } - if (config->enableHighSpeed) - { - tmp32 |= ADC_CFG_ADHSC_MASK; - } - base->CFG = tmp32; - - /* ADCx_GC */ - tmp32 = base->GC & ~(ADC_GC_ADCO_MASK | ADC_GC_ADACKEN_MASK); - if (config->enableContinuousConversion) - { - tmp32 |= ADC_GC_ADCO_MASK; - } - if (config->enableAsynchronousClockOutput) - { - tmp32 |= ADC_GC_ADACKEN_MASK; - } - base->GC = tmp32; -} - -/*! - * brief De-initializes the ADC module. - * - * param base ADC peripheral base address. - */ -void ADC_Deinit(ADC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the clock. */ - CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets an available pre-defined settings for the converter's configuration. - * - * This function initializes the converter configuration structure with available settings. The default values are: - * code - * config->enableAsynchronousClockOutput = true; - * config->enableOverWrite = false; - * config->enableContinuousConversion = false; - * config->enableHighSpeed = false; - * config->enableLowPower = false; - * config->enableLongSample = false; - * config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0; - * config->samplePeriodMode = kADC_SamplePeriod2or12Clocks; - * config->clockSource = kADC_ClockSourceAD; - * config->clockDriver = kADC_ClockDriver1; - * config->resolution = kADC_Resolution12Bit; - * endcode - * param base ADC peripheral base address. - * param config Pointer to the configuration structure. - */ -void ADC_GetDefaultConfig(adc_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableAsynchronousClockOutput = true; - config->enableOverWrite = false; - config->enableContinuousConversion = false; - config->enableHighSpeed = false; - config->enableLowPower = false; - config->enableLongSample = false; - config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0; - config->samplePeriodMode = kADC_SamplePeriod2or12Clocks; - config->clockSource = kADC_ClockSourceAD; - config->clockDriver = kADC_ClockDriver1; - config->resolution = kADC_Resolution12Bit; -} - -/*! - * brief Configures the conversion channel. - * - * This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API - * configures the channel while the external trigger source helps to trigger the conversion. - * - * Note that the "Channel Group" has a detailed description. - * To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one - * group of status and control registers, one for each conversion. The channel group parameter indicates which group of - * registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B - * registers. The - * channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of - * the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and - * hardware - * trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for - * use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual - * about the - * number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used - * for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion. - * Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and - * vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a - * conversion aborts the current conversion. - * - * param base ADC peripheral base address. - * param channelGroup Channel group index. - * param config Pointer to the "adc_channel_config_t" structure for the conversion channel. - */ -void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config) -{ - assert(NULL != config); - assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT); - - uint32_t tmp32; - - tmp32 = ADC_HC_ADCH(config->channelNumber); - if (config->enableInterruptOnConversionCompleted) - { - tmp32 |= ADC_HC_AIEN_MASK; - } - base->HC[channelGroup] = tmp32; -} - -/* - *To complete calibration, the user must follow the below procedure: - * 1. Configure ADC_CFG with actual operating values for maximum accuracy. - * 2. Configure the ADC_GC values along with CAL bit. - * 3. Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. - * 4. When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. - */ -/*! - * brief Automates the hardware calibration. - * - * This auto calibration helps to adjust the plus/minus side gain automatically. - * Execute the calibration before using the converter. Note that the software trigger should be used - * during calibration. - * - * param base ADC peripheral base address. - * - * return Execution status. - * retval kStatus_Success Calibration is done successfully. - * retval kStatus_Fail Calibration has failed. - */ -status_t ADC_DoAutoCalibration(ADC_Type *base) -{ - status_t status = kStatus_Success; -#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) - bool bHWTrigger = false; - - /* The calibration would be failed when in hardwar mode. - * Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/ - if (0U != (ADC_CFG_ADTRG_MASK & base->CFG)) - { - bHWTrigger = true; - ADC_EnableHardwareTrigger(base, false); - } -#endif - - /* Clear the CALF and launch the calibration. */ - base->GS = ADC_GS_CALF_MASK; /* Clear the CALF. */ - base->GC |= ADC_GC_CAL_MASK; /* Launch the calibration. */ - - /* Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. */ - while (0U != (base->GC & ADC_GC_CAL_MASK)) - { - /* Check the CALF when the calibration is active. */ - if (0U != (ADC_GetStatusFlags(base) & (uint32_t)kADC_CalibrationFailedFlag)) - { - status = kStatus_Fail; - break; - } - } - - /* When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. */ - if (0U == ADC_GetChannelStatusFlags(base, 0U)) /* Check the COCO[0] bit status. */ - { - status = kStatus_Fail; - } - if (0U != (ADC_GetStatusFlags(base) & (uint32_t)kADC_CalibrationFailedFlag)) /* Check the CALF status. */ - { - status = kStatus_Fail; - } - - /* Clear conversion done flag. */ - (void)ADC_GetChannelConversionValue(base, 0U); - -#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) - /* Restore original trigger mode. */ - if (true == bHWTrigger) - { - ADC_EnableHardwareTrigger(base, true); - } -#endif - - return status; -} - -/*! - * brief Set user defined offset. - * - * param base ADC peripheral base address. - * param config Pointer to "adc_offest_config_t" structure. - */ -void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - - tmp32 = ADC_OFS_OFS(config->offsetValue); - if (config->enableSigned) - { - tmp32 |= ADC_OFS_SIGN_MASK; - } - base->OFS = tmp32; -} - -/*! - * brief Configures the hardware compare mode. - * - * The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the - * result - * in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate - * reference - * manual for more information. - * - * param base ADC peripheral base address. - * param Pointer to "adc_hardware_compare_config_t" structure. - * - */ -void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config) -{ - uint32_t tmp32; - - tmp32 = base->GC & ~(ADC_GC_ACFE_MASK | ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK); - if (NULL == config) /* Pass "NULL" to disable the feature. */ - { - base->GC = tmp32; - return; - } - /* Enable the feature. */ - tmp32 |= ADC_GC_ACFE_MASK; - - /* Select the hardware compare working mode. */ - switch (config->hardwareCompareMode) - { - case kADC_HardwareCompareMode0: - break; - case kADC_HardwareCompareMode1: - tmp32 |= ADC_GC_ACFGT_MASK; - break; - case kADC_HardwareCompareMode2: - tmp32 |= ADC_GC_ACREN_MASK; - break; - case kADC_HardwareCompareMode3: - tmp32 |= ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK; - break; - default: - assert(false); - break; - } - base->GC = tmp32; - - /* Load the compare values. */ - tmp32 = ADC_CV_CV1(config->value1) | ADC_CV_CV2(config->value2); - base->CV = tmp32; -} - -/*! - * brief Configures the hardware average mode. - * - * The hardware average mode provides a way to process the conversion result automatically by using hardware. The - * multiple - * conversion results are accumulated and averaged internally making them easier to read. - * - * param base ADC peripheral base address. - * param mode Setting the hardware average mode. See "adc_hardware_average_mode_t". - */ -void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode) -{ - uint32_t tmp32; - - if (mode == kADC_HardwareAverageDiasable) - { - base->GC &= ~ADC_GC_AVGE_MASK; - } - else - { - tmp32 = base->CFG & ~ADC_CFG_AVGS_MASK; - tmp32 |= ADC_CFG_AVGS(mode); - base->CFG = tmp32; - base->GC |= ADC_GC_AVGE_MASK; /* Enable the hardware compare. */ - } -} - -/*! - * brief Clears the converter's status falgs. - * - * param base ADC peripheral base address. - * param mask Mask value for the cleared flags. See "adc_status_flags_t". - */ -void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask) -{ - uint32_t tmp32 = 0; - - if (0U != (mask & (uint32_t)kADC_CalibrationFailedFlag)) - { - tmp32 |= ADC_GS_CALF_MASK; - } - if (0U != (mask & (uint32_t)kADC_ConversionActiveFlag)) - { - tmp32 |= ADC_GS_ADACT_MASK; - } - base->GS = tmp32; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c deleted file mode 100644 index d912b7045c..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_adc_etc.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_adc_etc.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.adc_etc" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -#if defined(ADC_ETC_CLOCKS) -/*! - * @brief Get instance number for ADC_ETC module. - * - * @param base ADC_ETC peripheral base address - */ -static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to ADC_ETC bases for each instance. */ -static ADC_ETC_Type *const s_adcetcBases[] = ADC_ETC_BASE_PTRS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to ADC_ETC clocks for each instance. */ -static const clock_ip_name_t s_adcetcClocks[] = ADC_ETC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t ADC_ETC_GetInstance(ADC_ETC_Type *base) -{ - uint32_t instance = 0U; - uint32_t adcetcArrayCount = (sizeof(s_adcetcBases) / sizeof(s_adcetcBases[0])); - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < adcetcArrayCount; instance++) - { - if (s_adcetcBases[instance] == base) - { - break; - } - } - - return instance; -} -#endif /* ADC_ETC_CLOCKS */ - -/*! - * brief Initialize the ADC_ETC module. - * - * param base ADC_ETC peripheral base address. - * param config Pointer to "adc_etc_config_t" structure. - */ -void ADC_ETC_Init(ADC_ETC_Type *base, const adc_etc_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32 = 0U; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -#if defined(ADC_ETC_CLOCKS) - /* Open clock gate. */ - CLOCK_EnableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]); -#endif /* ADC_ETC_CLOCKS */ -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Disable software reset. */ - ADC_ETC_DoSoftwareReset(base, false); - - /* Set ADC_ETC_CTRL register. */ - tmp32 = ADC_ETC_CTRL_EXT0_TRIG_PRIORITY(config->TSC0triggerPriority) | - ADC_ETC_CTRL_EXT1_TRIG_PRIORITY(config->TSC1triggerPriority) | - ADC_ETC_CTRL_PRE_DIVIDER(config->clockPreDivider) | ADC_ETC_CTRL_TRIG_ENABLE(config->XBARtriggerMask) -#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL - | ADC_ETC_CTRL_DMA_MODE_SEL(config->dmaMode) -#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/ - ; - if (config->enableTSCBypass) - { - tmp32 |= ADC_ETC_CTRL_TSC_BYPASS_MASK; - } - if (config->enableTSC0Trigger) - { - tmp32 |= ADC_ETC_CTRL_EXT0_TRIG_ENABLE_MASK; - } - if (config->enableTSC1Trigger) - { - tmp32 |= ADC_ETC_CTRL_EXT1_TRIG_ENABLE_MASK; - } - base->CTRL = tmp32; -} - -/*! - * brief De-Initialize the ADC_ETC module. - * - * param base ADC_ETC peripheral base address. - */ -void ADC_ETC_Deinit(ADC_ETC_Type *base) -{ - /* Do software reset to clear all logical. */ - ADC_ETC_DoSoftwareReset(base, true); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -#if defined(ADC_ETC_CLOCKS) - /* Close clock gate. */ - CLOCK_DisableClock(s_adcetcClocks[ADC_ETC_GetInstance(base)]); -#endif /* ADC_ETC_CLOCKS */ -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets an available pre-defined settings for the ADC_ETC's configuration. - * This function initializes the ADC_ETC's configuration structure with available settings. The default values are: - * code - * config->enableTSCBypass = true; - * config->enableTSC0Trigger = false; - * config->enableTSC1Trigger = false; - * config->TSC0triggerPriority = 0U; - * config->TSC1triggerPriority = 0U; - * config->clockPreDivider = 0U; - * config->XBARtriggerMask = 0U; - * endCode - * - * param config Pointer to "adc_etc_config_t" structure. - */ -void ADC_ETC_GetDefaultConfig(adc_etc_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableTSCBypass = true; - config->enableTSC0Trigger = false; - config->enableTSC1Trigger = false; -#if defined(FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL) && FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL - config->dmaMode = kADC_ETC_TrigDMAWithLatchedSignal; -#endif /*FSL_FEATURE_ADC_ETC_HAS_CTRL_DMA_MODE_SEL*/ - config->TSC0triggerPriority = 0U; - config->TSC1triggerPriority = 0U; - config->clockPreDivider = 0U; - config->XBARtriggerMask = 0U; -} - -/*! - * brief Set the external XBAR trigger configuration. - * - * param base ADC_ETC peripheral base address. - * param triggerGroup Trigger group index. - * param config Pointer to "adc_etc_trigger_config_t" structure. - */ -void ADC_ETC_SetTriggerConfig(ADC_ETC_Type *base, uint32_t triggerGroup, const adc_etc_trigger_config_t *config) -{ - assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT); - assert(ADC_ETC_TRIGn_COUNTER_COUNT > triggerGroup); - - uint32_t tmp32 = 0U; - - /* Set ADC_ETC_TRGn_CTRL register. */ - tmp32 = ADC_ETC_TRIGn_CTRL_TRIG_CHAIN(config->triggerChainLength) | - ADC_ETC_TRIGn_CTRL_TRIG_PRIORITY(config->triggerPriority); - if (config->enableSyncMode) - { - tmp32 |= ADC_ETC_TRIGn_CTRL_SYNC_MODE_MASK; - } - if (config->enableSWTriggerMode) - { - tmp32 |= ADC_ETC_TRIGn_CTRL_TRIG_MODE_MASK; - } - base->TRIG[triggerGroup].TRIGn_CTRL = tmp32; - - /* Set ADC_ETC_TRGn_COUNTER register. */ - tmp32 = ADC_ETC_TRIGn_COUNTER_INIT_DELAY(config->initialDelay) | - ADC_ETC_TRIGn_COUNTER_SAMPLE_INTERVAL(config->sampleIntervalDelay); - base->TRIG[triggerGroup].TRIGn_COUNTER = tmp32; -} - -/*! - * brief Set the external XBAR trigger chain configuration. - * For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means Trigger0 source's chain1 would be - * configurated. - * - * param base ADC_ETC peripheral base address. - * param triggerGroup Trigger group index. Available number is 0~7. - * param chainGroup Trigger chain group index. Available number is 0~7. - * param config Pointer to "adc_etc_trigger_chain_config_t" structure. - */ -void ADC_ETC_SetTriggerChainConfig(ADC_ETC_Type *base, - uint32_t triggerGroup, - uint32_t chainGroup, - const adc_etc_trigger_chain_config_t *config) -{ - assert(triggerGroup < ADC_ETC_TRIGn_CTRL_COUNT); - - uint32_t tmp32 = 0U; - uint32_t tmpReg = 0U; - uint8_t mRemainder = (uint8_t)(chainGroup % 2U); - - /* Set ADC_ETC_TRIGn_CHAINm register. */ - tmp32 = ADC_ETC_TRIGn_CHAIN_1_0_HWTS0(config->ADCHCRegisterSelect) | - ADC_ETC_TRIGn_CHAIN_1_0_CSEL0(config->ADCChannelSelect) | - ADC_ETC_TRIGn_CHAIN_1_0_IE0(config->InterruptEnable); - if (true == config->enableB2BMode) - { - tmp32 |= ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK; - } -#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN - if (true == config->enableIrq) - { - tmp32 |= ADC_ETC_TRIGn_CHAIN_1_0_IE0_EN_MASK; - } -#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */ - switch (chainGroup / 2U) - { - case 0U: /* Configurate trigger chain0 and chain 1. */ - tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_1_0; - if (mRemainder == 0U) /* Chain 0. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS0_MASK | - ADC_ETC_TRIGn_CHAIN_1_0_B2B0_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE0_MASK); - tmpReg |= tmp32; - } - else /* Chain 1. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_HWTS1_MASK | - ADC_ETC_TRIGn_CHAIN_1_0_B2B1_MASK | ADC_ETC_TRIGn_CHAIN_1_0_IE1_MASK); - tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_1_0_CSEL1_SHIFT); - } - base->TRIG[triggerGroup].TRIGn_CHAIN_1_0 = tmpReg; - break; - case 1U: /* Configurate trigger chain2 and chain 3. */ - tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_3_2; - if (mRemainder == 0U) /* Chain 2. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS2_MASK | - ADC_ETC_TRIGn_CHAIN_3_2_B2B2_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE2_MASK); - tmpReg |= tmp32; - } - else /* Chain 3. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_HWTS3_MASK | - ADC_ETC_TRIGn_CHAIN_3_2_B2B3_MASK | ADC_ETC_TRIGn_CHAIN_3_2_IE3_MASK); - tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_3_2_CSEL3_SHIFT); - } - base->TRIG[triggerGroup].TRIGn_CHAIN_3_2 = tmpReg; - break; - case 2U: /* Configurate trigger chain4 and chain 5. */ - tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_5_4; - if (mRemainder == 0U) /* Chain 4. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS4_MASK | - ADC_ETC_TRIGn_CHAIN_5_4_B2B4_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE4_MASK); - tmpReg |= tmp32; - } - else /* Chain 5. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_HWTS5_MASK | - ADC_ETC_TRIGn_CHAIN_5_4_B2B5_MASK | ADC_ETC_TRIGn_CHAIN_5_4_IE5_MASK); - tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_5_4_CSEL5_SHIFT); - } - base->TRIG[triggerGroup].TRIGn_CHAIN_5_4 = tmpReg; - break; - case 3U: /* Configurate trigger chain6 and chain 7. */ - tmpReg = base->TRIG[triggerGroup].TRIGn_CHAIN_7_6; - if (mRemainder == 0U) /* Chain 6. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS6_MASK | - ADC_ETC_TRIGn_CHAIN_7_6_B2B6_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE6_MASK); - tmpReg |= tmp32; - } - else /* Chain 7. */ - { - tmpReg &= ~(ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_HWTS7_MASK | - ADC_ETC_TRIGn_CHAIN_7_6_B2B7_MASK | ADC_ETC_TRIGn_CHAIN_7_6_IE7_MASK); - tmpReg |= (tmp32 << ADC_ETC_TRIGn_CHAIN_7_6_CSEL7_SHIFT); - } - base->TRIG[triggerGroup].TRIGn_CHAIN_7_6 = tmpReg; - break; - default: - assert(false); - break; - } -} - -/*! - * brief Gets the interrupt status flags of external XBAR and TSC triggers. - * - * param base ADC_ETC peripheral base address. - * param sourceIndex trigger source index. - * - * return Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask". - */ -uint32_t ADC_ETC_GetInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex) -{ - uint32_t tmp32 = 0U; - - if (((base->DONE0_1_IRQ) & ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << (uint32_t)sourceIndex)) != 0U) - { - tmp32 |= (uint32_t)kADC_ETC_Done0StatusFlagMask; /* Customized DONE0 status flags mask, which is defined in - fsl_adc_etc.h file. */ - } - if (((base->DONE0_1_IRQ) & ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << (uint32_t)sourceIndex)) != 0U) - { - tmp32 |= (uint32_t)kADC_ETC_Done1StatusFlagMask; /* Customized DONE1 status flags mask, which is defined in - fsl_adc_etc.h file. */ - } - if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << (uint32_t)sourceIndex)) != 0U) - { - tmp32 |= (uint32_t)kADC_ETC_Done2StatusFlagMask; /* Customized DONE2 status flags mask, which is defined in - fsl_adc_etc.h file. */ - } -#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN - if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE3_MASK << (uint32_t)sourceIndex)) != 0U) - { - tmp32 |= (uint32_t)kADC_ETC_Done3StatusFlagMask; /* Customized DONE3 status flags mask, which is defined in - fsl_adc_etc.h file. */ - } -#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */ - if (((base->DONE2_ERR_IRQ) & ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << (uint32_t)sourceIndex)) != 0U) - { - tmp32 |= (uint32_t)kADC_ETC_ErrorStatusFlagMask; /* Customized ERROR status flags mask, which is defined in - fsl_adc_etc.h file. */ - } - return tmp32; -} - -/*! - * brief Clears the ADC_ETC's interrupt status falgs. - * - * param base ADC_ETC peripheral base address. - * param sourceIndex trigger source index. - * param mask Status flags mask of trigger. Refer to "_adc_etc_status_flag_mask". - */ -void ADC_ETC_ClearInterruptStatusFlags(ADC_ETC_Type *base, adc_etc_external_trigger_source_t sourceIndex, uint32_t mask) -{ - if (0U != (mask & (uint32_t)kADC_ETC_Done0StatusFlagMask)) /* Write 1 to clear DONE0 status flags. */ - { - base->DONE0_1_IRQ = ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE0_MASK << (uint32_t)sourceIndex); - } - if (0U != (mask & (uint32_t)kADC_ETC_Done1StatusFlagMask)) /* Write 1 to clear DONE1 status flags. */ - { - base->DONE0_1_IRQ = ((uint32_t)ADC_ETC_DONE0_1_IRQ_TRIG0_DONE1_MASK << (uint32_t)sourceIndex); - } - if (0U != (mask & (uint32_t)kADC_ETC_Done2StatusFlagMask)) /* Write 1 to clear DONE2 status flags. */ - { - base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE2_MASK << (uint32_t)sourceIndex); - } -#if defined(FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN) && FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN - if (0U != (mask & (uint32_t)kADC_ETC_Done3StatusFlagMask)) /* Write 1 to clear DONE3 status flags. */ - { - base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_DONE3_MASK << (uint32_t)sourceIndex); - } -#endif /* FSL_FEATURE_ADC_ETC_HAS_TRIGm_CHAIN_a_b_IEn_EN */ - if (0U != (mask & (uint32_t)kADC_ETC_ErrorStatusFlagMask)) /* Write 1 to clear ERROR status flags. */ - { - base->DONE2_ERR_IRQ = ((uint32_t)ADC_ETC_DONE2_ERR_IRQ_TRIG0_ERR_MASK << (uint32_t)sourceIndex); - } -} - -/*! - * brief Get ADC conversion result from external XBAR sources. - * For example, if triggerGroup is set to 0U and chainGroup is set to 1U, which means the API would - * return Trigger0 source's chain1 conversion result. - * - * param base ADC_ETC peripheral base address. - * param triggerGroup Trigger group index. Available number is 0~7. - * param chainGroup Trigger chain group index. Available number is 0~7. - * return ADC conversion result value. - */ -uint32_t ADC_ETC_GetADCConversionValue(ADC_ETC_Type *base, uint32_t triggerGroup, uint32_t chainGroup) -{ - assert(triggerGroup < ADC_ETC_TRIGn_RESULT_1_0_COUNT); - - uint32_t mADCResult; - uint8_t mRemainder = (uint8_t)(chainGroup % 2U); - - switch (chainGroup / 2U) - { - case 0U: - if (0U == mRemainder) - { - mADCResult = ADC_ETC_TRIGn_RESULT_1_0_DATA0_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_1_0); - } - else - { - mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_1_0) >> ADC_ETC_TRIGn_RESULT_1_0_DATA1_SHIFT; - } - break; - case 1U: - if (0U == mRemainder) - { - mADCResult = ADC_ETC_TRIGn_RESULT_3_2_DATA2_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_3_2); - } - else - { - mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_3_2) >> ADC_ETC_TRIGn_RESULT_3_2_DATA3_SHIFT; - } - break; - case 2U: - if (0U == mRemainder) - { - mADCResult = ADC_ETC_TRIGn_RESULT_5_4_DATA4_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_5_4); - } - else - { - mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_5_4) >> ADC_ETC_TRIGn_RESULT_5_4_DATA5_SHIFT; - } - break; - case 3U: - if (0U == mRemainder) - { - mADCResult = ADC_ETC_TRIGn_RESULT_7_6_DATA6_MASK & (base->TRIG[triggerGroup].TRIGn_RESULT_7_6); - } - else - { - mADCResult = (base->TRIG[triggerGroup].TRIGn_RESULT_7_6) >> ADC_ETC_TRIGn_RESULT_7_6_DATA7_SHIFT; - } - break; - default: - mADCResult = 0U; - assert(false); - break; - } - return mADCResult; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c deleted file mode 100644 index 077b4e01e2..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aipstz.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_aipstz.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.aipstz" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * brief Configure the privilege level for master. - * - * param base AIPSTZ peripheral base pointer - * param master Masters for AIPSTZ. - * param privilegeConfig Configuration is ORed from aipstz_master_privilege_level_t. - */ -void AIPSTZ_SetMasterPriviledgeLevel(AIPSTZ_Type *base, aipstz_master_t master, uint32_t privilegeConfig) -{ - uint32_t mask = ((uint32_t)master >> 8U) - 1U; - uint32_t shift = (uint32_t)master & 0xFFU; - base->MPR = (base->MPR & (~(mask << shift))) | (privilegeConfig << shift); -} - -/*! - * brief Configure the access for peripheral. - * - * param base AIPSTZ peripheral base pointer - * param master Peripheral for AIPSTZ. - * param accessControl Configuration is ORed from aipstz_peripheral_access_control_t. - */ -void AIPSTZ_SetPeripheralAccessControl(AIPSTZ_Type *base, aipstz_peripheral_t peripheral, uint32_t accessControl) -{ - volatile uint32_t *reg = (uint32_t *)((uint32_t)base + ((uint32_t)peripheral >> 16U)); - uint32_t mask = (((uint32_t)peripheral & 0xFF00U) >> 8U) - 1U; - uint32_t shift = (uint32_t)peripheral & 0xFFU; - - *reg = (*reg & (~(mask << shift))) | ((accessControl & mask) << shift); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c deleted file mode 100644 index a8f1f29ddb..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_aoi.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include "fsl_aoi.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.aoi" -#endif - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to aoi bases for each instance. */ -static AOI_Type *const s_aoiBases[] = AOI_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to aoi clocks for each instance. */ -static const clock_ip_name_t s_aoiClocks[] = AOI_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - /******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for AOI module. - * - * @param base AOI peripheral base address - * - * @return The AOI instance - */ -static uint32_t AOI_GetInstance(AOI_Type *base); -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t AOI_GetInstance(AOI_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_aoiBases); instance++) - { - if (s_aoiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_aoiBases)); - - return instance; -} - -/*! - * brief Initializes an AOI instance for operation. - * - * This function un-gates the AOI clock. - * - * param base AOI peripheral address. - */ -void AOI_Init(AOI_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock gate from clock manager. */ - CLOCK_EnableClock(s_aoiClocks[AOI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Deinitializes an AOI instance for operation. - * - * This function shutdowns AOI module. - * - * param base AOI peripheral address. - */ -void AOI_Deinit(AOI_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the clock gate from clock manager */ - CLOCK_DisableClock(s_aoiClocks[AOI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the Boolean evaluation associated. - * - * This function returns the Boolean evaluation associated. - * - * Example: - code - aoi_event_config_t demoEventLogicStruct; - - AOI_GetEventLogicConfig(AOI, kAOI_Event0, &demoEventLogicStruct); - endcode - * - * param base AOI peripheral address. - * param event Index of the event which will be set of type aoi_event_t. - * param config Selected input configuration . - */ -void AOI_GetEventLogicConfig(AOI_Type *base, aoi_event_t event, aoi_event_config_t *config) -{ - assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT); - assert(config != NULL); - - uint16_t value; - uint16_t temp; - /* Read BFCRT01 register at event index. */ - value = base->BFCRT[event].BFCRT01; - - temp = (value & AOI_BFCRT01_PT0_AC_MASK) >> AOI_BFCRT01_PT0_AC_SHIFT; - config->PT0AC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT0_BC_MASK) >> AOI_BFCRT01_PT0_BC_SHIFT; - config->PT0BC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT0_CC_MASK) >> AOI_BFCRT01_PT0_CC_SHIFT; - config->PT0CC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT0_DC_MASK) >> AOI_BFCRT01_PT0_DC_SHIFT; - config->PT0DC = (aoi_input_config_t)temp; - - temp = (value & AOI_BFCRT01_PT1_AC_MASK) >> AOI_BFCRT01_PT1_AC_SHIFT; - config->PT1AC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT1_BC_MASK) >> AOI_BFCRT01_PT1_BC_SHIFT; - config->PT1BC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT1_CC_MASK) >> AOI_BFCRT01_PT1_CC_SHIFT; - config->PT1CC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT01_PT1_DC_MASK) >> AOI_BFCRT01_PT1_DC_SHIFT; - config->PT1DC = (aoi_input_config_t)temp; - - /* Read BFCRT23 register at event index. */ - value = base->BFCRT[event].BFCRT23; - - temp = (value & AOI_BFCRT23_PT2_AC_MASK) >> AOI_BFCRT23_PT2_AC_SHIFT; - config->PT2AC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT2_BC_MASK) >> AOI_BFCRT23_PT2_BC_SHIFT; - config->PT2BC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT2_CC_MASK) >> AOI_BFCRT23_PT2_CC_SHIFT; - config->PT2CC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT2_DC_MASK) >> AOI_BFCRT23_PT2_DC_SHIFT; - config->PT2DC = (aoi_input_config_t)temp; - - temp = (value & AOI_BFCRT23_PT3_AC_MASK) >> AOI_BFCRT23_PT3_AC_SHIFT; - config->PT3AC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT3_BC_MASK) >> AOI_BFCRT23_PT3_BC_SHIFT; - config->PT3BC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT3_CC_MASK) >> AOI_BFCRT23_PT3_CC_SHIFT; - config->PT3CC = (aoi_input_config_t)temp; - temp = (value & AOI_BFCRT23_PT3_DC_MASK) >> AOI_BFCRT23_PT3_DC_SHIFT; - config->PT3DC = (aoi_input_config_t)temp; -} - -/*! - * brief Configures an AOI event. - * - * This function configures an AOI event according - * to the aoiEventConfig structure. This function configures all inputs (A, B, C, and D) - * of all product terms (0, 1, 2, and 3) of a desired event. - * - * Example: - code - aoi_event_config_t demoEventLogicStruct; - - demoEventLogicStruct.PT0AC = kAOI_InvInputSignal; - demoEventLogicStruct.PT0BC = kAOI_InputSignal; - demoEventLogicStruct.PT0CC = kAOI_LogicOne; - demoEventLogicStruct.PT0DC = kAOI_LogicOne; - - demoEventLogicStruct.PT1AC = kAOI_LogicZero; - demoEventLogicStruct.PT1BC = kAOI_LogicOne; - demoEventLogicStruct.PT1CC = kAOI_LogicOne; - demoEventLogicStruct.PT1DC = kAOI_LogicOne; - - demoEventLogicStruct.PT2AC = kAOI_LogicZero; - demoEventLogicStruct.PT2BC = kAOI_LogicOne; - demoEventLogicStruct.PT2CC = kAOI_LogicOne; - demoEventLogicStruct.PT2DC = kAOI_LogicOne; - - demoEventLogicStruct.PT3AC = kAOI_LogicZero; - demoEventLogicStruct.PT3BC = kAOI_LogicOne; - demoEventLogicStruct.PT3CC = kAOI_LogicOne; - demoEventLogicStruct.PT3DC = kAOI_LogicOne; - - AOI_SetEventLogicConfig(AOI, kAOI_Event0, demoEventLogicStruct); - endcode - * - * param base AOI peripheral address. - * param event Event which will be configured of type aoi_event_t. - * param eventConfig Pointer to type aoi_event_config_t structure. The user is responsible for - * filling out the members of this structure and passing the pointer to this function. - */ -void AOI_SetEventLogicConfig(AOI_Type *base, aoi_event_t event, const aoi_event_config_t *eventConfig) -{ - assert(eventConfig != NULL); - assert((uint32_t)event < (uint32_t)FSL_FEATURE_AOI_EVENT_COUNT); - - uint16_t value; - /* Calculate value to configure product term 0, 1 */ - value = AOI_BFCRT01_PT0_AC(eventConfig->PT0AC) | AOI_BFCRT01_PT0_BC(eventConfig->PT0BC) | - AOI_BFCRT01_PT0_CC(eventConfig->PT0CC) | AOI_BFCRT01_PT0_DC(eventConfig->PT0DC) | - AOI_BFCRT01_PT1_AC(eventConfig->PT1AC) | AOI_BFCRT01_PT1_BC(eventConfig->PT1BC) | - AOI_BFCRT01_PT1_CC(eventConfig->PT1CC) | AOI_BFCRT01_PT1_DC(eventConfig->PT1DC); - /* Write value to register */ - base->BFCRT[event].BFCRT01 = value; - - /* Reset and calculate value to configure product term 2, 3 */ - value = AOI_BFCRT23_PT2_AC(eventConfig->PT2AC) | AOI_BFCRT23_PT2_BC(eventConfig->PT2BC) | - AOI_BFCRT23_PT2_CC(eventConfig->PT2CC) | AOI_BFCRT23_PT2_DC(eventConfig->PT2DC) | - AOI_BFCRT23_PT3_AC(eventConfig->PT3AC) | AOI_BFCRT23_PT3_BC(eventConfig->PT3BC) | - AOI_BFCRT23_PT3_CC(eventConfig->PT3CC) | AOI_BFCRT23_PT3_DC(eventConfig->PT3DC); - /* Write value to register */ - base->BFCRT[event].BFCRT23 = value; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c deleted file mode 100644 index d4ffdacfb9..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_bee.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Copyright 2017, 2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_bee.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.bee" -#endif - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void aligned_memcpy(void *dst, const void *src, size_t size) -{ - register uint32_t *to32 = (uint32_t *)(uint32_t *)dst; - register const uint32_t *from32 = (const uint32_t *)(const uint32_t *)src; - - while (size >= sizeof(uint32_t)) - { - *to32 = *from32; - size -= sizeof(uint32_t); - to32++; - from32++; - } -} - -/*! - * brief Resets BEE module to factory default values. - * - * This function performs hardware reset of BEE module. Attributes and keys from software for both regions are cleared. - * - * param base BEE peripheral address. - */ -void BEE_Init(BEE_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_EnableClock(kCLOCK_Bee); -#endif - - base->CTRL = BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK; -} - -/*! - * brief Resets BEE module, clears keys for both regions and disables clock to the BEE. - * - * This function performs hardware reset of BEE module and disables clocks. Attributes and keys from software for both - * regions are cleared. - * - * param base BEE peripheral address. - */ -void BEE_Deinit(BEE_Type *base) -{ - base->CTRL &= - ~(BEE_CTRL_BEE_ENABLE_MASK | BEE_CTRL_CTRL_SFTRST_N_MASK | BEE_CTRL_CTRL_CLK_EN_MASK | BEE_CTRL_KEY_VALID_MASK); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(kCLOCK_Bee); -#endif -} - -/*! - * brief Loads default values to the BEE region configuration structure. - * - * Loads default values to the BEE region configuration structure. The default values are as follows: - * code - * config->region0Mode = kBEE_AesCtrMode; - * config->region1Mode = kBEE_AesCtrMode; - * config->region0AddrOffset = 0U; - * config->region1AddrOffset = 0U; - * config->region0SecLevel = kBEE_SecurityLevel3; - * config->region1SecLevel = kBEE_SecurityLevel3; - * config->region1Bot = 0U; - * config->region1Top = 0U; - * config->accessPermission = kBEE_AccessProtDisabled; - * config->endianSwapEn = kBEE_EndianSwapEnabled; - * endcode - * - * param config Configuration structure for BEE peripheral. - */ -void BEE_GetDefaultConfig(bee_region_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->region0Mode = kBEE_AesCtrMode; - config->region1Mode = kBEE_AesCtrMode; - config->region0AddrOffset = 0U; - config->region1AddrOffset = 0U; - config->region0SecLevel = kBEE_SecurityLevel3; - config->region1SecLevel = kBEE_SecurityLevel3; - config->region1Bot = 0U; - config->region1Top = 0U; - config->accessPermission = kBEE_AccessProtDisabled; - config->endianSwapEn = kBEE_EndianSwapEnabled; -} - -/*! - * brief Sets BEE configuration. - * - * This function sets BEE peripheral and BEE region settings accorging to given configuration structure. - * - * param base BEE peripheral address. - * param config Configuration structure for BEE. - */ -void BEE_SetConfig(BEE_Type *base, const bee_region_config_t *config) -{ - uint32_t beeCtrlVal; - bool reenable = false; - - /* Wait until BEE is in idle state */ - while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag)) - { - } - - /* Disable BEE before region configuration in case it is enabled. */ - if ((base->CTRL & BEE_CTRL_BEE_ENABLE_MASK) != 0U) - { - BEE_Disable(base); - reenable = true; - } - - /* Preserve CTRL bit values that are not set by this function */ - beeCtrlVal = base->CTRL & 0xFFFF0037U; - - /* Set variable according to configuration */ - beeCtrlVal |= BEE_CTRL_AC_PROT_EN(config->accessPermission) | BEE_CTRL_LITTLE_ENDIAN(config->endianSwapEn) | - BEE_CTRL_SECURITY_LEVEL_R0(config->region0SecLevel) | BEE_CTRL_CTRL_AES_MODE_R0(config->region0Mode) | - BEE_CTRL_SECURITY_LEVEL_R1(config->region1SecLevel) | BEE_CTRL_CTRL_AES_MODE_R1(config->region1Mode); - - /* Load values to registers */ - base->CTRL = beeCtrlVal; - base->ADDR_OFFSET0 = config->region0AddrOffset; - base->ADDR_OFFSET1 = config->region1AddrOffset; - base->REGION1_BOT = config->region1Bot; - base->REGION1_TOP = config->region1Top; - - /* Reenable BEE if it was enabled before. */ - if (reenable) - { - BEE_Enable(base); - } -} - -/*! - * brief Loads the AES key for selected region into BEE key registers. - * - * This function loads given AES key to BEE register for the given region. - * The key must be 32-bit aligned and stored in little-endian format. - * - * Please note, that eFuse BEE_KEYx_SEL must be set accordingly to be able to load and use key loaded in BEE registers. - * Otherwise, key cannot loaded and BEE will use key from OTPMK or SW_GP2. - * - * param base BEE peripheral address. - * param region Selection of the BEE region to be configured. - * param key AES key (in little-endian format). - * param keySize Size of AES key. - */ -status_t BEE_SetRegionKey(BEE_Type *base, bee_region_t region, const uint8_t *key, size_t keySize) -{ - bool redisable = false; - - /* Key must be 32-bit aligned */ - if ((0U != ((uintptr_t)key & 0x3u)) || (keySize != 16U)) - { - return kStatus_InvalidArgument; - } - - /* Wait until BEE is in idle state */ - while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag)) - { - } - - /* Clear KEY_VALID bit before new key is loaded */ - base->CTRL &= ~BEE_CTRL_KEY_VALID_MASK; - - /* Write key registers, key is stored in little-endian format in memory */ - aligned_memcpy((uint32_t *)(uint32_t)&base->AES_KEY0_W0, key, keySize); - - /* Enable BEE before key configuration. */ - if (0U == (base->CTRL & BEE_CTRL_BEE_ENABLE_MASK)) - { - BEE_Enable(base); - redisable = true; - } - - if (region == kBEE_Region0) - { - base->CTRL &= ~BEE_CTRL_KEY_REGION_SEL_MASK; - } - - else if (region == kBEE_Region1) - { - base->CTRL |= BEE_CTRL_KEY_REGION_SEL_MASK; - } - - else - { - return kStatus_InvalidArgument; - } - - /* Set KEY_VALID bit to trigger key loading */ - base->CTRL |= BEE_CTRL_KEY_VALID_MASK; - /* Wait until key is ready */ - while (0U == (base->CTRL & BEE_CTRL_KEY_VALID_MASK)) - { - } - - /* Redisable BEE if it was disabled before this function call. */ - if (redisable) - { - BEE_Disable(base); - } - - return kStatus_Success; -} - -/*! - * brief Loads the nonce for selected region into BEE nonce registers. - * - * This function loads given nonce(only AES CTR mode) to BEE register for the given region. - * The nonce must be 32-bit aligned and stored in little-endian format. - * - * param base BEE peripheral address. - * param region Selection of the BEE region to be configured. - * param nonce AES nonce (in little-endian format). - * param nonceSize Size of AES nonce. - */ -status_t BEE_SetRegionNonce(BEE_Type *base, bee_region_t region, const uint8_t *nonce, size_t nonceSize) -{ - /* Nonce must be 32-bit aligned */ - if ((0U != ((uintptr_t)nonce & 0x3u)) || (nonceSize != 16U)) - { - return kStatus_InvalidArgument; - } - - /* Wait until BEE is in idle state */ - while (0U == (BEE_GetStatusFlags(base) & (uint32_t)kBEE_IdleFlag)) - { - } - - /* Write nonce registers, nonce is stored in little-endian format in memory */ - if (region == kBEE_Region0) - { - aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE0_W0, nonce, nonceSize); - } - - else if (region == kBEE_Region1) - { - aligned_memcpy((uint32_t *)(uint32_t)&base->CTR_NONCE1_W0, nonce, nonceSize); - } - - else - { - return kStatus_InvalidArgument; - } - - return kStatus_Success; -} - -/*! - * brief Gets the BEE status flags. - * - * This function returns status of BEE peripheral. - * - * param base BEE peripheral address. - * - * return The status flags. This is the logical OR of members of the - * enumeration ::bee_status_flags_t - */ -uint32_t BEE_GetStatusFlags(BEE_Type *base) -{ - return base->STATUS; -} - -/*! - * brief Clears the BEE status flags. - * - * param base BEE peripheral base address. - * param mask The status flags to clear. This is a logical OR of members of the - * enumeration ::bee_status_flags_t - */ -void BEE_ClearStatusFlags(BEE_Type *base, uint32_t mask) -{ - /* w1c */ - base->STATUS |= mask; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c deleted file mode 100644 index 31d6a2479c..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cache.c +++ /dev/null @@ -1,602 +0,0 @@ -/* - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_cache.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.cache_armv7_m7" -#endif - -#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT -#define L2CACHE_OPERATION_TIMEOUT 0xFFFFFU -#define L2CACHE_8WAYS_MASK 0xFFU -#define L2CACHE_16WAYS_MASK 0xFFFFU -#define L2CACHE_SMALLWAYS_NUM 8U -#define L2CACHE_1KBCOVERTOB 1024U -#define L2CACHE_SAMLLWAYS_SIZE 16U -#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/ - /******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Set for all ways and waiting for the operation finished. - * This is provided for all the background operations. - * - * @param auxCtlReg The auxiliary control register. - * @param regAddr The register address to be operated. - */ -static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr); - -/*! - * @brief Invalidates the Level 2 cache line by physical address. - * This function invalidates a cache line by physcial address. - * - * @param address The physical addderss of the cache. - * The format of the address shall be : - * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0 - * Tag | index | 0 - * Note: the physical address shall be aligned to the line size - 32B (256 bit). - * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero. - * If the input address is not aligned, it will be changed to 32-byte aligned address. - * The n is varies according to the index width. - * @return The actual 32-byte aligned physical address be operated. - */ -static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address); - -/*! - * @brief Cleans the Level 2 cache line based on the physical address. - * This function cleans a cache line based on a physcial address. - * - * @param address The physical addderss of the cache. - * The format of the address shall be : - * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0 - * Tag | index | 0 - * Note: the physical address shall be aligned to the line size - 32B (256 bit). - * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero. - * If the input address is not aligned, it will be changed to 32-byte aligned address. - * The n is varies according to the index width. - * @return The actual 32-byte aligned physical address be operated. - */ -static uint32_t L2CACHE_CleanLineByAddr(uint32_t address); - -/*! - * @brief Cleans and invalidates the Level 2 cache line based on the physical address. - * This function cleans and invalidates a cache line based on a physcial address. - * - * @param address The physical addderss of the cache. - * The format of the address shall be : - * bit 31 ~ bit n+1 | bitn ~ bit5 | bit4 ~ bit0 - * Tag | index | 0 - * Note: the physical address shall be aligned to the line size - 32B (256 bit). - * so keep the last 5 bits (bit 4 ~ bit 0) of the physical address always be zero. - * If the input address is not aligned, it will be changed to 32-byte aligned address. - * The n is varies according to the index width. - * @return The actual 32-byte aligned physical address be operated. - */ -static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address); - -/*! - * @brief Gets the number of the Level 2 cache and the way size. - * This function cleans and invalidates a cache line based on a physcial address. - * - * @param num_ways The number of the cache way. - * @param size_way The way size. - */ -static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way); -/******************************************************************************* - * Code - ******************************************************************************/ -static void L2CACHE_SetAndWaitBackGroundOperate(uint32_t auxCtlReg, uint32_t regAddr) -{ - uint16_t mask = L2CACHE_8WAYS_MASK; - uint32_t timeout = L2CACHE_OPERATION_TIMEOUT; - - /* Check the ways used at first. */ - if (auxCtlReg & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) - { - mask = L2CACHE_16WAYS_MASK; - } - - /* Set the opeartion for all ways/entries of the cache. */ - *(uint32_t *)regAddr = mask; - /* Waiting for until the operation is complete. */ - while ((*(volatile uint32_t *)regAddr & mask) && timeout) - { - __ASM("nop"); - timeout--; - } -} - -static uint32_t L2CACHE_InvalidateLineByAddr(uint32_t address) -{ - /* Align the address first. */ - address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1); - /* Invalidate the cache line by physical address. */ - L2CACHEC->REG7_INV_PA = address; - - return address; -} - -static uint32_t L2CACHE_CleanLineByAddr(uint32_t address) -{ - /* Align the address first. */ - address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1); - /* Invalidate the cache line by physical address. */ - L2CACHEC->REG7_CLEAN_PA = address; - - return address; -} - -static uint32_t L2CACHE_CleanInvalidateLineByAddr(uint32_t address) -{ - /* Align the address first. */ - address &= ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1); - /* Clean and invalidate the cache line by physical address. */ - L2CACHEC->REG7_CLEAN_INV_PA = address; - - return address; -} - -static void L2CACHE_GetWayNumSize(uint32_t *num_ways, uint32_t *size_way) -{ - assert(num_ways); - assert(size_way); - - uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >> - L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT; - uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >> - L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT; - - *num_ways = (number + 1) * L2CACHE_SMALLWAYS_NUM; - if (!size) - { - /* 0 internally mapped to the same size as 1 - 16KB.*/ - size += 1; - } - *size_way = (1 << (size - 1)) * L2CACHE_SAMLLWAYS_SIZE * L2CACHE_1KBCOVERTOB; -} - -/*! - * brief Initializes the level 2 cache controller module. - * - * param config Pointer to configuration structure. See "l2cache_config_t". - */ -void L2CACHE_Init(l2cache_config_t *config) -{ - assert(config); - - uint16_t waysNum = 0xFFU; /* Default use the 8-way mask. */ - uint8_t count; - uint32_t auxReg = 0; - - /*The aux register must be configured when the cachec is disabled - * So disable first if the cache controller is enabled. - */ - if (L2CACHEC->REG1_CONTROL & L2CACHEC_REG1_CONTROL_CE_MASK) - { - L2CACHE_Disable(); - } - - /* Unlock all entries. */ - if (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) - { - waysNum = 0xFFFFU; - } - - for (count = 0; count < L2CACHE_LOCKDOWN_REGNUM; count++) - { - L2CACHE_LockdownByWayEnable(count, waysNum, false); - } - - /* Set the ways and way-size etc. */ - auxReg = L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY(config->wayNum) | - L2CACHEC_REG1_AUX_CONTROL_WAYSIZE(config->waySize) | L2CACHEC_REG1_AUX_CONTROL_CRP(config->repacePolicy) | - L2CACHEC_REG1_AUX_CONTROL_IPE(config->istrPrefetchEnable) | - L2CACHEC_REG1_AUX_CONTROL_DPE(config->dataPrefetchEnable) | - L2CACHEC_REG1_AUX_CONTROL_NLE(config->nsLockdownEnable) | - L2CACHEC_REG1_AUX_CONTROL_FWA(config->writeAlloc) | L2CACHEC_REG1_AUX_CONTROL_HPSDRE(config->writeAlloc); - L2CACHEC->REG1_AUX_CONTROL = auxReg; - - /* Set the tag/data ram latency. */ - if (config->lateConfig) - { - uint32_t data = 0; - /* Tag latency. */ - data = L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) | - L2CACHEC_REG1_TAG_RAM_CONTROL_SL(config->lateConfig->tagSetupLate) | - L2CACHEC_REG1_TAG_RAM_CONTROL_RAL(config->lateConfig->tagReadLate) | - L2CACHEC_REG1_TAG_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate); - L2CACHEC->REG1_TAG_RAM_CONTROL = data; - /* Data latency. */ - data = L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) | - L2CACHEC_REG1_DATA_RAM_CONTROL_SL(config->lateConfig->dataSetupLate) | - L2CACHEC_REG1_DATA_RAM_CONTROL_RAL(config->lateConfig->dataReadLate) | - L2CACHEC_REG1_DATA_RAM_CONTROL_WAL(config->lateConfig->dataWriteLate); - L2CACHEC->REG1_DATA_RAM_CONTROL = data; - } -} - -/*! - * brief Gets an available default settings for the cache controller. - * - * This function initializes the cache controller configuration structure with default settings. - * The default values are: - * code - * config->waysNum = kL2CACHE_8ways; - * config->waySize = kL2CACHE_32KbSize; - * config->repacePolicy = kL2CACHE_Roundrobin; - * config->lateConfig = NULL; - * config->istrPrefetchEnable = false; - * config->dataPrefetchEnable = false; - * config->nsLockdownEnable = false; - * config->writeAlloc = kL2CACHE_UseAwcache; - * endcode - * param config Pointer to the configuration structure. - */ -void L2CACHE_GetDefaultConfig(l2cache_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - memset(config, 0, sizeof(*config)); - - uint32_t number = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >> - L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT; - uint32_t size = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_MASK) >> - L2CACHEC_REG1_AUX_CONTROL_WAYSIZE_SHIFT; - - /* Get the default value */ - config->wayNum = (l2cache_way_num_t)number; - config->waySize = (l2cache_way_size)size; - config->repacePolicy = kL2CACHE_Roundrobin; - config->lateConfig = NULL; - config->istrPrefetchEnable = false; - config->dataPrefetchEnable = false; - config->nsLockdownEnable = false; - config->writeAlloc = kL2CACHE_UseAwcache; -} - -/*! - * brief Enables the level 2 cache controller. - * This function enables the cache controller. Must be written using a secure access. - * If write with a Non-secure access will cause a DECERR response. - * - */ -void L2CACHE_Enable(void) -{ - /* Invalidate first. */ - L2CACHE_Invalidate(); - /* Enable the level 2 cache controller. */ - L2CACHEC->REG1_CONTROL = L2CACHEC_REG1_CONTROL_CE_MASK; -} - -/*! - * brief Disables the level 2 cache controller. - * This function disables the cache controller. Must be written using a secure access. - * If write with a Non-secure access will cause a DECERR response. - * - */ -void L2CACHE_Disable(void) -{ - /* First CleanInvalidate all enties in the cache. */ - L2CACHE_CleanInvalidate(); - /* Disable the level 2 cache controller. */ - L2CACHEC->REG1_CONTROL &= ~L2CACHEC_REG1_CONTROL_CE_MASK; - /* DSB - data sync barrier.*/ - __DSB(); -} - -/*! - * brief Invalidates the Level 2 cache. - * This function invalidates all entries in cache. - * - */ -void L2CACHE_Invalidate(void) -{ - /* Invalidate all entries in cache. */ - L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_INV_WAY); - /* Cache sync. */ - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Cleans the level 2 cache controller. - * This function cleans all entries in the level 2 cache controller. - * - */ -void L2CACHE_Clean(void) -{ - /* Clean all entries of the cache. */ - L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_WAY); - /* Cache sync. */ - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Cleans and invalidates the level 2 cache controller. - * This function cleans and invalidates all entries in the level 2 cache controller. - * - */ -void L2CACHE_CleanInvalidate(void) -{ - /* Clean all entries of the cache. */ - L2CACHE_SetAndWaitBackGroundOperate(L2CACHEC->REG1_AUX_CONTROL, (uint32_t)&L2CACHEC->REG7_CLEAN_INV_WAY); - /* Cache sync. */ - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Invalidates the Level 2 cache lines in the range of two physical addresses. - * This function invalidates all cache lines between two physical addresses. - * - * param address The start address of the memory to be invalidated. - * param size_byte The memory size. - * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned. - * The startAddr here will be forced to align to L2 line size if startAddr - * is not aligned. For the size_byte, application should make sure the - * alignment or make sure the right operation order if the size_byte is not aligned. - */ -void L2CACHE_InvalidateByRange(uint32_t address, uint32_t size_byte) -{ - uint32_t endAddr = address + size_byte; - - /* Invalidate addresses in the range. */ - while (address < endAddr) - { - address = L2CACHE_InvalidateLineByAddr(address); - /* Update the size. */ - address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE; - } - - /* Cache sync. */ - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Cleans the Level 2 cache lines in the range of two physical addresses. - * This function cleans all cache lines between two physical addresses. - * - * param address The start address of the memory to be cleaned. - * param size_byte The memory size. - * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned. - * The startAddr here will be forced to align to L2 line size if startAddr - * is not aligned. For the size_byte, application should make sure the - * alignment or make sure the right operation order if the size_byte is not aligned. - */ -void L2CACHE_CleanByRange(uint32_t address, uint32_t size_byte) -{ - uint32_t num_ways = 0; - uint32_t size_way = 0; - uint32_t endAddr = address + size_byte; - - /* Get the number and size of the cache way. */ - L2CACHE_GetWayNumSize(&num_ways, &size_way); - - /* Check if the clean size is over the cache size. */ - if ((endAddr - address) > num_ways * size_way) - { - L2CACHE_Clean(); - return; - } - - /* Clean addresses in the range. */ - while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr) - { - /* Clean the address in the range. */ - address = L2CACHE_CleanLineByAddr(address); - address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE; - } - - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Cleans and invalidates the Level 2 cache lines in the range of two physical addresses. - * This function cleans and invalidates all cache lines between two physical addresses. - * - * param address The start address of the memory to be cleaned and invalidated. - * param size_byte The memory size. - * note The start address and size_byte should be 32-byte(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) aligned. - * The startAddr here will be forced to align to L2 line size if startAddr - * is not aligned. For the size_byte, application should make sure the - * alignment or make sure the right operation order if the size_byte is not aligned. - */ -void L2CACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte) -{ - uint32_t num_ways = 0; - uint32_t size_way = 0; - uint32_t endAddr = address + size_byte; - - /* Get the number and size of the cache way. */ - L2CACHE_GetWayNumSize(&num_ways, &size_way); - - /* Check if the clean size is over the cache size. */ - if ((endAddr - address) > num_ways * size_way) - { - L2CACHE_CleanInvalidate(); - return; - } - - /* Clean addresses in the range. */ - while ((address & ~(uint32_t)(FSL_FEATURE_L2CACHE_LINESIZE_BYTE - 1)) < endAddr) - { - /* Clean the address in the range. */ - address = L2CACHE_CleanInvalidateLineByAddr(address); - address += FSL_FEATURE_L2CACHE_LINESIZE_BYTE; - } - - L2CACHEC->REG7_CACHE_SYNC = 0; -} - -/*! - * brief Enables or disables to lock down the data and instruction by way. - * This function locks down the cached instruction/data by way and prevent the adresses from - * being allocated and prevent dara from being evicted out of the level 2 cache. - * But the normal cache maintenance operations that invalidate, clean or clean - * and validate cache contents affect the locked-down cache lines as normal. - * - * param masterId The master id, range from 0 ~ 7. - * param mask The ways to be enabled or disabled to lockdown. - * each bit in value is related to each way of the cache. for example: - * value: bit 0 ------ way 0. - * value: bit 1 ------ way 1. - * -------------------------- - * value: bit 15 ------ way 15. - * Note: please make sure the value setting is align with your supported ways. - * param enable True enable the lockdown, false to disable the lockdown. - */ -void L2CACHE_LockdownByWayEnable(uint32_t masterId, uint32_t mask, bool enable) -{ - uint8_t num_ways = (L2CACHEC->REG1_AUX_CONTROL & L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_MASK) >> - L2CACHEC_REG1_AUX_CONTROL_ASSOCIATIVITY_SHIFT; - num_ways = (num_ways + 1) * L2CACHE_SMALLWAYS_NUM; - - assert(mask < (1U << num_ways)); - assert(masterId < L2CACHE_LOCKDOWN_REGNUM); - - uint32_t dataReg = L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN; - uint32_t istrReg = L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN; - - if (enable) - { - /* Data lockdown. */ - L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg | mask; - /* Instruction lockdown. */ - L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg | mask; - } - else - { - /* Data lockdown. */ - L2CACHEC->LOCKDOWN[masterId].REG9_D_LOCKDOWN = dataReg & ~mask; - /* Instruction lockdown. */ - L2CACHEC->LOCKDOWN[masterId].REG9_I_LOCKDOWN = istrReg & ~mask; - } -} -#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */ - -/*! - * brief Invalidate cortex-m7 L1 instruction cache by range. - * - * param address The start address of the memory to be invalidated. - * param size_byte The memory size. - * note The start address and size_byte should be 32-byte(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) aligned. - * The startAddr here will be forced to align to L1 I-cache line size if - * startAddr is not aligned. For the size_byte, application should make sure the - * alignment or make sure the right operation order if the size_byte is not aligned. - */ -void L1CACHE_InvalidateICacheByRange(uint32_t address, uint32_t size_byte) -{ -#if (__DCACHE_PRESENT == 1U) - uint32_t addr = address & ~((uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE - 1U); - uint32_t align_len = address - addr; - int32_t size = (int32_t)size_byte + (int32_t)align_len; - - __DSB(); - while (size > 0) - { - SCB->ICIMVAU = addr; - addr += (uint32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE; - size -= (int32_t)FSL_FEATURE_L1ICACHE_LINESIZE_BYTE; - } - __DSB(); - __ISB(); -#endif -} - -/*! - * brief Invalidates all instruction caches by range. - * - * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte. - * - * param address The physical address. - * param size_byte size of the memory to be invalidated. - * note address and size should be aligned to cache line size - * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced - * to align to the cache line size if startAddr is not aligned. For the size_byte, application should - * make sure the alignment or make sure the right operation order if the size_byte is not aligned. - */ -void ICACHE_InvalidateByRange(uint32_t address, uint32_t size_byte) -{ -#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT -#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT - L2CACHE_InvalidateByRange(address, size_byte); -#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */ -#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */ - - L1CACHE_InvalidateICacheByRange(address, size_byte); -} - -/*! - * brief Invalidates all data caches by range. - * - * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte. - * - * param address The physical address. - * param size_byte size of the memory to be invalidated. - * note address and size should be aligned to cache line size - * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced - * to align to the cache line size if startAddr is not aligned. For the size_byte, application should - * make sure the alignment or make sure the right operation order if the size_byte is not aligned. - */ -void DCACHE_InvalidateByRange(uint32_t address, uint32_t size_byte) -{ -#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT -#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT - L2CACHE_InvalidateByRange(address, size_byte); -#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */ -#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */ - L1CACHE_InvalidateDCacheByRange(address, size_byte); -} - -/*! - * brief Cleans all data caches by range. - * - * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte. - * - * param address The physical address. - * param size_byte size of the memory to be cleaned. - * note address and size should be aligned to cache line size - * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced - * to align to the cache line size if startAddr is not aligned. For the size_byte, application should - * make sure the alignment or make sure the right operation order if the size_byte is not aligned. - */ -void DCACHE_CleanByRange(uint32_t address, uint32_t size_byte) -{ - L1CACHE_CleanDCacheByRange(address, size_byte); -#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT -#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT - L2CACHE_CleanByRange(address, size_byte); -#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */ -#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */ -} - -/*! - * brief Cleans and Invalidates all data caches by range. - * - * Both cortex-m7 L1 cache line and L2 PL310 cache line length is 32-byte. - * - * param address The physical address. - * param size_byte size of the memory to be cleaned and invalidated. - * note address and size should be aligned to cache line size - * 32-Byte due to the cache operation unit is one cache line. The startAddr here will be forced - * to align to the cache line size if startAddr is not aligned. For the size_byte, application should - * make sure the alignment or make sure the right operation order if the size_byte is not aligned. - */ -void DCACHE_CleanInvalidateByRange(uint32_t address, uint32_t size_byte) -{ - L1CACHE_CleanInvalidateDCacheByRange(address, size_byte); -#if defined(FSL_FEATURE_SOC_L2CACHEC_COUNT) && FSL_FEATURE_SOC_L2CACHEC_COUNT -#if defined(FSL_SDK_DISBLE_L2CACHE_PRESENT) && !FSL_SDK_DISBLE_L2CACHE_PRESENT - L2CACHE_CleanInvalidateByRange(address, size_byte); -#endif /* !FSL_SDK_DISBLE_L2CACHE_PRESENT */ -#endif /* FSL_FEATURE_SOC_L2CACHEC_COUNT */ -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c deleted file mode 100644 index cb5ca96dab..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_clock.c +++ /dev/null @@ -1,1250 +0,0 @@ -/* - * Copyright 2017 - 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_clock.h" -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.clock" -#endif -/******************************************************************************* - * Definitions - ******************************************************************************/ -/* To make full use of CM7 hardware FPU, use double instead of uint64_t in clock driver to -achieve better performance, it is depend on the IDE Floating point settings, if double precision is selected -in IDE, clock_64b_t will switch to double type automatically. only support IAR and MDK here */ -#if __FPU_USED - -#if (defined(__ICCARM__)) - -#if (__ARMVFP__ >= __ARMFPV5__) && \ - (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/ -typedef double clock_64b_t; -#else -typedef uint64_t clock_64b_t; -#endif - -#elif (defined(__GNUC__)) - -#if (__ARM_FP == 0xE) /*0xe implies support for half, single and double precision operations*/ -typedef double clock_64b_t; -#else -typedef uint64_t clock_64b_t; -#endif - -#elif defined(__CC_ARM) || defined(__ARMCC_VERSION) - -#if defined __TARGET_FPU_FPV5_D16 -typedef double clock_64b_t; -#else -typedef uint64_t clock_64b_t; -#endif - -#else -typedef uint64_t clock_64b_t; -#endif - -#else -typedef uint64_t clock_64b_t; -#endif - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* External XTAL (OSC) clock frequency. */ -volatile uint32_t g_xtalFreq; -/* External RTC XTAL clock frequency. */ -volatile uint32_t g_rtcXtalFreq; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get the periph clock frequency. - * - * @return Periph clock frequency in Hz. - */ -static uint32_t CLOCK_GetPeriphClkFreq(void); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t CLOCK_GetPeriphClkFreq(void) -{ - uint32_t freq; - - /* Periph_clk2_clk ---> Periph_clk */ - if ((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK_SEL_MASK) != 0U) - { - switch (CCM->CBCMR & CCM_CBCMR_PERIPH_CLK2_SEL_MASK) - { - /* Pll3_sw_clk ---> Periph_clk2_clk ---> Periph_clk */ - case CCM_CBCMR_PERIPH_CLK2_SEL(0U): - freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); - break; - - /* Osc_clk ---> Periph_clk2_clk ---> Periph_clk */ - case CCM_CBCMR_PERIPH_CLK2_SEL(1U): - freq = CLOCK_GetOscFreq(); - break; - - case CCM_CBCMR_PERIPH_CLK2_SEL(2U): - freq = CLOCK_GetPllFreq(kCLOCK_PllSys); - break; - - case CCM_CBCMR_PERIPH_CLK2_SEL(3U): - default: - freq = 0U; - break; - } - - freq /= (((CCM->CBCDR & CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> CCM_CBCDR_PERIPH_CLK2_PODF_SHIFT) + 1U); - } - /* Pre_Periph_clk ---> Periph_clk */ - else - { - switch (CCM->CBCMR & CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) - { - /* PLL2 ---> Pre_Periph_clk ---> Periph_clk */ - case CCM_CBCMR_PRE_PERIPH_CLK_SEL(0U): - freq = CLOCK_GetPllFreq(kCLOCK_PllSys); - break; - - /* PLL2 PFD2 ---> Pre_Periph_clk ---> Periph_clk */ - case CCM_CBCMR_PRE_PERIPH_CLK_SEL(1U): - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); - break; - - /* PLL2 PFD0 ---> Pre_Periph_clk ---> Periph_clk */ - case CCM_CBCMR_PRE_PERIPH_CLK_SEL(2U): - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); - break; - - /* PLL1 divided(/2) ---> Pre_Periph_clk ---> Periph_clk */ - case CCM_CBCMR_PRE_PERIPH_CLK_SEL(3U): - freq = CLOCK_GetPllFreq(kCLOCK_PllArm) / - (((CCM->CACRR & CCM_CACRR_ARM_PODF_MASK) >> CCM_CACRR_ARM_PODF_SHIFT) + 1U); - break; - - default: - freq = 0U; - break; - } - } - - return freq; -} - -/*! - * brief Initialize the external 24MHz clock. - * - * This function supports two modes: - * 1. Use external crystal oscillator. - * 2. Bypass the external crystal oscillator, using input source clock directly. - * - * After this function, please call ref CLOCK_SetXtal0Freq to inform clock driver - * the external clock frequency. - * - * param bypassXtalOsc Pass in true to bypass the external crystal oscillator. - * note This device does not support bypass external crystal oscillator, so - * the input parameter should always be false. - */ -void CLOCK_InitExternalClk(bool bypassXtalOsc) -{ - /* This device does not support bypass XTAL OSC. */ - assert(!bypassXtalOsc); - - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power up */ - while ((XTALOSC24M->LOWPWR_CTRL & XTALOSC24M_LOWPWR_CTRL_XTALOSC_PWRUP_STAT_MASK) == 0U) - { - } - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; /* detect freq */ - while ((CCM_ANALOG->MISC0 & CCM_ANALOG_MISC0_OSC_XTALOK_MASK) == 0UL) - { - } - CCM_ANALOG->MISC0_CLR = CCM_ANALOG_MISC0_OSC_XTALOK_EN_MASK; -} - -/*! - * brief Deinitialize the external 24MHz clock. - * - * This function disables the external 24MHz clock. - * - * After this function, please call ref CLOCK_SetXtal0Freq to set external clock - * frequency to 0. - */ -void CLOCK_DeinitExternalClk(void) -{ - CCM_ANALOG->MISC0_SET = CCM_ANALOG_MISC0_XTAL_24M_PWD_MASK; /* Power down */ -} - -/*! - * brief Switch the OSC. - * - * This function switches the OSC source for SoC. - * - * param osc OSC source to switch to. - */ -void CLOCK_SwitchOsc(clock_osc_t osc) -{ - if (osc == kCLOCK_RcOsc) - { - XTALOSC24M->LOWPWR_CTRL_SET = XTALOSC24M_LOWPWR_CTRL_SET_OSC_SEL_MASK; - } - else - { - XTALOSC24M->LOWPWR_CTRL_CLR = XTALOSC24M_LOWPWR_CTRL_CLR_OSC_SEL_MASK; - } -} - -/*! - * brief Initialize the RC oscillator 24MHz clock. - */ -void CLOCK_InitRcOsc24M(void) -{ - XTALOSC24M->LOWPWR_CTRL |= XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; -} - -/*! - * brief Power down the RCOSC 24M clock. - */ -void CLOCK_DeinitRcOsc24M(void) -{ - XTALOSC24M->LOWPWR_CTRL &= ~XTALOSC24M_LOWPWR_CTRL_RC_OSC_EN_MASK; -} - -/*! - * brief Gets the AHB clock frequency. - * - * return The AHB clock frequency value in hertz. - */ -uint32_t CLOCK_GetAhbFreq(void) -{ - return CLOCK_GetPeriphClkFreq() / (((CCM->CBCDR & CCM_CBCDR_AHB_PODF_MASK) >> CCM_CBCDR_AHB_PODF_SHIFT) + 1U); -} - -/*! - * brief Gets the SEMC clock frequency. - * - * return The SEMC clock frequency value in hertz. - */ -uint32_t CLOCK_GetSemcFreq(void) -{ - uint32_t freq; - - /* SEMC alternative clock ---> SEMC Clock */ - if ((CCM->CBCDR & CCM_CBCDR_SEMC_CLK_SEL_MASK) != 0U) - { - /* PLL3 PFD1 ---> SEMC alternative clock ---> SEMC Clock */ - if ((CCM->CBCDR & CCM_CBCDR_SEMC_ALT_CLK_SEL_MASK) != 0U) - { - freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); - } - /* PLL2 PFD2 ---> SEMC alternative clock ---> SEMC Clock */ - else - { - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); - } - } - /* Periph_clk ---> SEMC Clock */ - else - { - freq = CLOCK_GetPeriphClkFreq(); - } - - freq /= (((CCM->CBCDR & CCM_CBCDR_SEMC_PODF_MASK) >> CCM_CBCDR_SEMC_PODF_SHIFT) + 1U); - - return freq; -} - -/*! - * brief Gets the IPG clock frequency. - * - * return The IPG clock frequency value in hertz. - */ -uint32_t CLOCK_GetIpgFreq(void) -{ - return CLOCK_GetAhbFreq() / (((CCM->CBCDR & CCM_CBCDR_IPG_PODF_MASK) >> CCM_CBCDR_IPG_PODF_SHIFT) + 1U); -} - -/*! - * brief Gets the PER clock frequency. - * - * return The PER clock frequency value in hertz. - */ -uint32_t CLOCK_GetPerClkFreq(void) -{ - uint32_t freq; - - /* Osc_clk ---> PER Clock*/ - if ((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_CLK_SEL_MASK) != 0U) - { - freq = CLOCK_GetOscFreq(); - } - /* Periph_clk ---> AHB Clock ---> IPG Clock ---> PER Clock */ - else - { - freq = CLOCK_GetIpgFreq(); - } - - freq /= (((CCM->CSCMR1 & CCM_CSCMR1_PERCLK_PODF_MASK) >> CCM_CSCMR1_PERCLK_PODF_SHIFT) + 1U); - - return freq; -} - -/*! - * brief Gets the clock frequency for a specific clock name. - * - * This function checks the current clock configurations and then calculates - * the clock frequency for a specific clock name defined in clock_name_t. - * - * param clockName Clock names defined in clock_name_t - * return Clock frequency value in hertz - */ -uint32_t CLOCK_GetFreq(clock_name_t name) -{ - uint32_t freq; - - switch (name) - { - case kCLOCK_CpuClk: - case kCLOCK_AhbClk: - freq = CLOCK_GetAhbFreq(); - break; - - case kCLOCK_SemcClk: - freq = CLOCK_GetSemcFreq(); - break; - - case kCLOCK_IpgClk: - freq = CLOCK_GetIpgFreq(); - break; - - case kCLOCK_PerClk: - freq = CLOCK_GetPerClkFreq(); - break; - - case kCLOCK_OscClk: - freq = CLOCK_GetOscFreq(); - break; - case kCLOCK_RtcClk: - freq = CLOCK_GetRtcFreq(); - break; - case kCLOCK_ArmPllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllArm); - break; - case kCLOCK_Usb1PllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); - break; - case kCLOCK_Usb1PllPfd0Clk: - freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd0); - break; - case kCLOCK_Usb1PllPfd1Clk: - freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd1); - break; - case kCLOCK_Usb1PllPfd2Clk: - freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd2); - break; - case kCLOCK_Usb1PllPfd3Clk: - freq = CLOCK_GetUsb1PfdFreq(kCLOCK_Pfd3); - break; - case kCLOCK_Usb2PllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllUsb2); - break; - case kCLOCK_SysPllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllSys); - break; - case kCLOCK_SysPllPfd0Clk: - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd0); - break; - case kCLOCK_SysPllPfd1Clk: - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd1); - break; - case kCLOCK_SysPllPfd2Clk: - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd2); - break; - case kCLOCK_SysPllPfd3Clk: - freq = CLOCK_GetSysPfdFreq(kCLOCK_Pfd3); - break; - case kCLOCK_EnetPll0Clk: - freq = CLOCK_GetPllFreq(kCLOCK_PllEnet); - break; - case kCLOCK_EnetPll1Clk: - freq = CLOCK_GetPllFreq(kCLOCK_PllEnet25M); - break; - case kCLOCK_AudioPllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllAudio); - break; - case kCLOCK_VideoPllClk: - freq = CLOCK_GetPllFreq(kCLOCK_PllVideo); - break; - default: - freq = 0U; - break; - } - - return freq; -} - -/*! brief Enable USB HS clock. - * - * This function only enables the access to USB HS prepheral, upper layer - * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY - * clock to use USB HS. - * - * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. - * param freq USB HS does not care about the clock source, so this parameter is ignored. - * retval true The clock is set successfully. - * retval false The clock source is invalid to get proper USB HS clock. - */ -bool CLOCK_EnableUsbhs0Clock(clock_usb_src_t src, uint32_t freq) -{ - uint32_t i; - CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; - USB1->USBCMD |= USBHS_USBCMD_RST_MASK; - - /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ - for (i = 0; i < 400000U; i++) - { - __ASM("nop"); - } - PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | - (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); - return true; -} - -/*! brief Enable USB HS clock. - * - * This function only enables the access to USB HS prepheral, upper layer - * should first call the ref CLOCK_EnableUsbhs0PhyPllClock to enable the PHY - * clock to use USB HS. - * - * param src USB HS does not care about the clock source, here must be ref kCLOCK_UsbSrcUnused. - * param freq USB HS does not care about the clock source, so this parameter is ignored. - * retval true The clock is set successfully. - * retval false The clock source is invalid to get proper USB HS clock. - */ -bool CLOCK_EnableUsbhs1Clock(clock_usb_src_t src, uint32_t freq) -{ - uint32_t i = 0; - CCM->CCGR6 |= CCM_CCGR6_CG0_MASK; - USB2->USBCMD |= USBHS_USBCMD_RST_MASK; - - /* Add a delay between RST and RS so make sure there is a DP pullup sequence*/ - for (i = 0; i < 400000U; i++) - { - __ASM("nop"); - } - PMU->REG_3P0 = (PMU->REG_3P0 & (~PMU_REG_3P0_OUTPUT_TRG_MASK)) | - (PMU_REG_3P0_OUTPUT_TRG(0x17) | PMU_REG_3P0_ENABLE_LINREG_MASK); - return true; -} - -/*! brief Enable USB HS PHY PLL clock. - * - * This function enables the internal 480MHz USB PHY PLL clock. - * - * param src USB HS PHY PLL clock source. - * param freq The frequency specified by src. - * retval true The clock is set successfully. - * retval false The clock source is invalid to get proper USB HS clock. - */ -bool CLOCK_EnableUsbhs0PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) -{ - const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; - if ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_ENABLE_MASK) != 0U) - { - CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; - } - else - { - CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); - } - USBPHY1->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ - USBPHY1->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; - - USBPHY1->PWD = 0; - USBPHY1->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | - USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; - return true; -} - -/*! brief Disable USB HS PHY PLL clock. - * - * This function disables USB HS PHY PLL clock. - */ -void CLOCK_DisableUsbhs0PhyPllClock(void) -{ - CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK; - USBPHY1->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ -} - -/*! - * brief Initialize the ARM PLL. - * - * This function initialize the ARM PLL with specific settings - * - * param config configuration to set to PLL. - */ -void CLOCK_InitArmPll(const clock_arm_pll_config_t *config) -{ - /* Bypass PLL first */ - CCM_ANALOG->PLL_ARM = (CCM_ANALOG->PLL_ARM & (~CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_ARM_BYPASS_MASK | CCM_ANALOG_PLL_ARM_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_ARM = - (CCM_ANALOG->PLL_ARM & (~(CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK | CCM_ANALOG_PLL_ARM_POWERDOWN_MASK))) | - CCM_ANALOG_PLL_ARM_ENABLE_MASK | CCM_ANALOG_PLL_ARM_DIV_SELECT(config->loopDivider); - - while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_ARM &= ~CCM_ANALOG_PLL_ARM_BYPASS_MASK; -} - -/*! - * brief De-initialize the ARM PLL. - */ -void CLOCK_DeinitArmPll(void) -{ - CCM_ANALOG->PLL_ARM = CCM_ANALOG_PLL_ARM_POWERDOWN_MASK; -} - -/*! - * brief Initialize the System PLL. - * - * This function initializes the System PLL with specific settings - * - * param config Configuration to set to PLL. - */ -void CLOCK_InitSysPll(const clock_sys_pll_config_t *config) -{ - /* Bypass PLL first */ - CCM_ANALOG->PLL_SYS = (CCM_ANALOG->PLL_SYS & (~CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_SYS_BYPASS_MASK | CCM_ANALOG_PLL_SYS_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_SYS = - (CCM_ANALOG->PLL_SYS & (~(CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK | CCM_ANALOG_PLL_SYS_POWERDOWN_MASK))) | - CCM_ANALOG_PLL_SYS_ENABLE_MASK | CCM_ANALOG_PLL_SYS_DIV_SELECT(config->loopDivider); - - /* Initialize the fractional mode */ - CCM_ANALOG->PLL_SYS_NUM = CCM_ANALOG_PLL_SYS_NUM_A(config->numerator); - CCM_ANALOG->PLL_SYS_DENOM = CCM_ANALOG_PLL_SYS_DENOM_B(config->denominator); - - /* Initialize the spread spectrum mode */ - CCM_ANALOG->PLL_SYS_SS = CCM_ANALOG_PLL_SYS_SS_STEP(config->ss_step) | - CCM_ANALOG_PLL_SYS_SS_ENABLE(config->ss_enable) | - CCM_ANALOG_PLL_SYS_SS_STOP(config->ss_stop); - - while ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_SYS &= ~CCM_ANALOG_PLL_SYS_BYPASS_MASK; -} - -/*! - * brief De-initialize the System PLL. - */ -void CLOCK_DeinitSysPll(void) -{ - CCM_ANALOG->PLL_SYS = CCM_ANALOG_PLL_SYS_POWERDOWN_MASK; -} - -/*! - * brief Initialize the USB1 PLL. - * - * This function initializes the USB1 PLL with specific settings - * - * param config Configuration to set to PLL. - */ -void CLOCK_InitUsb1Pll(const clock_usb_pll_config_t *config) -{ - /* Bypass PLL first */ - CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_USB1_BYPASS_MASK | CCM_ANALOG_PLL_USB1_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_USB1 = (CCM_ANALOG->PLL_USB1 & (~CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK)) | - CCM_ANALOG_PLL_USB1_ENABLE_MASK | CCM_ANALOG_PLL_USB1_POWER_MASK | - CCM_ANALOG_PLL_USB1_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB1_DIV_SELECT(config->loopDivider); - - while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_USB1 &= ~CCM_ANALOG_PLL_USB1_BYPASS_MASK; -} - -/*! - * brief Deinitialize the USB1 PLL. - */ -void CLOCK_DeinitUsb1Pll(void) -{ - CCM_ANALOG->PLL_USB1 = 0U; -} - -/*! - * brief Initialize the USB2 PLL. - * - * This function initializes the USB2 PLL with specific settings - * - * param config Configuration to set to PLL. - */ -void CLOCK_InitUsb2Pll(const clock_usb_pll_config_t *config) -{ - /* Bypass PLL first */ - CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_USB2_BYPASS_MASK | CCM_ANALOG_PLL_USB2_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_USB2 = (CCM_ANALOG->PLL_USB2 & (~CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK)) | - CCM_ANALOG_PLL_USB2_ENABLE_MASK | CCM_ANALOG_PLL_USB2_POWER_MASK | - CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK | CCM_ANALOG_PLL_USB2_DIV_SELECT(config->loopDivider); - - while ((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_BYPASS_MASK; -} - -/*! - * brief Deinitialize the USB2 PLL. - */ -void CLOCK_DeinitUsb2Pll(void) -{ - CCM_ANALOG->PLL_USB2 = 0U; -} - -/*! - * brief Initializes the Audio PLL. - * - * This function initializes the Audio PLL with specific settings - * - * param config Configuration to set to PLL. - */ -void CLOCK_InitAudioPll(const clock_audio_pll_config_t *config) -{ - uint32_t pllAudio; - uint32_t misc2 = 0; - - /* Bypass PLL first */ - CCM_ANALOG->PLL_AUDIO = (CCM_ANALOG->PLL_AUDIO & (~CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_AUDIO_BYPASS_MASK | CCM_ANALOG_PLL_AUDIO_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_AUDIO_NUM = CCM_ANALOG_PLL_AUDIO_NUM_A(config->numerator); - CCM_ANALOG->PLL_AUDIO_DENOM = CCM_ANALOG_PLL_AUDIO_DENOM_B(config->denominator); - - /* - * Set post divider: - * - * ------------------------------------------------------------------------ - * | config->postDivider | PLL_AUDIO[POST_DIV_SELECT] | MISC2[AUDIO_DIV] | - * ------------------------------------------------------------------------ - * | 1 | 2 | 0 | - * ------------------------------------------------------------------------ - * | 2 | 1 | 0 | - * ------------------------------------------------------------------------ - * | 4 | 2 | 3 | - * ------------------------------------------------------------------------ - * | 8 | 1 | 3 | - * ------------------------------------------------------------------------ - * | 16 | 0 | 3 | - * ------------------------------------------------------------------------ - */ - pllAudio = - (CCM_ANALOG->PLL_AUDIO & (~(CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK | CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK))) | - CCM_ANALOG_PLL_AUDIO_ENABLE_MASK | CCM_ANALOG_PLL_AUDIO_DIV_SELECT(config->loopDivider); - - switch (config->postDivider) - { - case 16: - pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0); - misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; - break; - - case 8: - pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); - misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; - break; - - case 4: - pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); - misc2 = CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK; - break; - - case 2: - pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1); - break; - - default: - pllAudio |= CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2); - break; - } - - CCM_ANALOG->MISC2 = - (CCM_ANALOG->MISC2 & ~(CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK)) | misc2; - - CCM_ANALOG->PLL_AUDIO = pllAudio; - - while ((CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_AUDIO &= ~CCM_ANALOG_PLL_AUDIO_BYPASS_MASK; -} - -/*! - * brief De-initialize the Audio PLL. - */ -void CLOCK_DeinitAudioPll(void) -{ - CCM_ANALOG->PLL_AUDIO = (uint32_t)CCM_ANALOG_PLL_AUDIO_POWERDOWN_MASK; -} - -/*! - * brief Initialize the video PLL. - * - * This function configures the Video PLL with specific settings - * - * param config configuration to set to PLL. - */ -void CLOCK_InitVideoPll(const clock_video_pll_config_t *config) -{ - uint32_t pllVideo; - uint32_t misc2 = 0; - - /* Bypass PLL first */ - CCM_ANALOG->PLL_VIDEO = (CCM_ANALOG->PLL_VIDEO & (~CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_VIDEO_BYPASS_MASK | CCM_ANALOG_PLL_VIDEO_BYPASS_CLK_SRC(config->src); - - CCM_ANALOG->PLL_VIDEO_NUM = CCM_ANALOG_PLL_VIDEO_NUM_A(config->numerator); - CCM_ANALOG->PLL_VIDEO_DENOM = CCM_ANALOG_PLL_VIDEO_DENOM_B(config->denominator); - - /* - * Set post divider: - * - * ------------------------------------------------------------------------ - * | config->postDivider | PLL_VIDEO[POST_DIV_SELECT] | MISC2[VIDEO_DIV] | - * ------------------------------------------------------------------------ - * | 1 | 2 | 0 | - * ------------------------------------------------------------------------ - * | 2 | 1 | 0 | - * ------------------------------------------------------------------------ - * | 4 | 2 | 3 | - * ------------------------------------------------------------------------ - * | 8 | 1 | 3 | - * ------------------------------------------------------------------------ - * | 16 | 0 | 3 | - * ------------------------------------------------------------------------ - */ - pllVideo = - (CCM_ANALOG->PLL_VIDEO & (~(CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK | CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK))) | - CCM_ANALOG_PLL_VIDEO_ENABLE_MASK | CCM_ANALOG_PLL_VIDEO_DIV_SELECT(config->loopDivider); - - switch (config->postDivider) - { - case 16: - pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0); - misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); - break; - - case 8: - pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); - misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); - break; - - case 4: - pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); - misc2 = CCM_ANALOG_MISC2_VIDEO_DIV(3); - break; - - case 2: - pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1); - break; - - default: - pllVideo |= CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2); - break; - } - - CCM_ANALOG->MISC2 = (CCM_ANALOG->MISC2 & ~CCM_ANALOG_MISC2_VIDEO_DIV_MASK) | misc2; - - CCM_ANALOG->PLL_VIDEO = pllVideo; - - while ((CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_VIDEO &= ~CCM_ANALOG_PLL_VIDEO_BYPASS_MASK; -} - -/*! - * brief De-initialize the Video PLL. - */ -void CLOCK_DeinitVideoPll(void) -{ - CCM_ANALOG->PLL_VIDEO = CCM_ANALOG_PLL_VIDEO_POWERDOWN_MASK; -} - -/*! - * brief Initialize the ENET PLL. - * - * This function initializes the ENET PLL with specific settings. - * - * param config Configuration to set to PLL. - */ -void CLOCK_InitEnetPll(const clock_enet_pll_config_t *config) -{ - uint32_t enet_pll = CCM_ANALOG_PLL_ENET_DIV_SELECT(config->loopDivider); - - CCM_ANALOG->PLL_ENET = (CCM_ANALOG->PLL_ENET & (~CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK)) | - CCM_ANALOG_PLL_ENET_BYPASS_MASK | CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(config->src); - - if (config->enableClkOutput) - { - enet_pll |= CCM_ANALOG_PLL_ENET_ENABLE_MASK; - } - - if (config->enableClkOutput25M) - { - enet_pll |= CCM_ANALOG_PLL_ENET_ENET_25M_REF_EN_MASK; - } - - CCM_ANALOG->PLL_ENET = - (CCM_ANALOG->PLL_ENET & (~(CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK))) | - enet_pll; - - /* Wait for stable */ - while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0UL) - { - } - - /* Disable Bypass */ - CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK; -} - -/*! - * brief Deinitialize the ENET PLL. - * - * This function disables the ENET PLL. - */ -void CLOCK_DeinitEnetPll(void) -{ - CCM_ANALOG->PLL_ENET = CCM_ANALOG_PLL_ENET_POWERDOWN_MASK; -} - -/*! - * brief Get current PLL output frequency. - * - * This function get current output frequency of specific PLL - * - * param pll pll name to get frequency. - * return The PLL output frequency in hertz. - */ -uint32_t CLOCK_GetPllFreq(clock_pll_t pll) -{ - uint32_t freq; - uint32_t divSelect; - clock_64b_t freqTmp; - - const uint32_t enetRefClkFreq[] = { - 25000000U, /* 25M */ - 50000000U, /* 50M */ - 100000000U, /* 100M */ - 125000000U /* 125M */ - }; - - /* check if PLL is enabled */ - if (!CLOCK_IsPllEnabled(CCM_ANALOG, pll)) - { - return 0U; - } - - /* get pll reference clock */ - freq = CLOCK_GetPllBypassRefClk(CCM_ANALOG, pll); - - /* check if pll is bypassed */ - if (CLOCK_IsPllBypassed(CCM_ANALOG, pll)) - { - return freq; - } - - switch (pll) - { - case kCLOCK_PllArm: - freq = ((freq * ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> - CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT)) >> - 1U); - break; - case kCLOCK_PllSys: - /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ - freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_SYS_NUM))); - freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_SYS_DENOM)); - - if ((CCM_ANALOG->PLL_SYS & CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK) != 0U) - { - freq *= 22U; - } - else - { - freq *= 20U; - } - - freq += (uint32_t)freqTmp; - break; - - case kCLOCK_PllUsb1: - freq = (freq * (((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK) != 0UL) ? 22U : 20U)); - break; - - case kCLOCK_PllAudio: - /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ - divSelect = - (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_AUDIO_DIV_SELECT_SHIFT; - - freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_NUM))); - freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_AUDIO_DENOM)); - - freq = freq * divSelect + (uint32_t)freqTmp; - - /* AUDIO PLL output = PLL output frequency / POSTDIV. */ - - /* - * Post divider: - * - * PLL_AUDIO[POST_DIV_SELECT]: - * 0x00: 4 - * 0x01: 2 - * 0x02: 1 - * - * MISC2[AUDO_DIV]: - * 0x00: 1 - * 0x01: 2 - * 0x02: 1 - * 0x03: 4 - */ - switch (CCM_ANALOG->PLL_AUDIO & CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT_MASK) - { - case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(0U): - freq = freq >> 2U; - break; - - case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(1U): - freq = freq >> 1U; - break; - - case CCM_ANALOG_PLL_AUDIO_POST_DIV_SELECT(2U): - freq = freq >> 0U; - break; - - default: - assert(false); - break; - } - - switch (CCM_ANALOG->MISC2 & (CCM_ANALOG_MISC2_AUDIO_DIV_MSB_MASK | CCM_ANALOG_MISC2_AUDIO_DIV_LSB_MASK)) - { - case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): - freq >>= 2U; - break; - - case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(1): - freq >>= 1U; - break; - - case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(0) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): - case CCM_ANALOG_MISC2_AUDIO_DIV_MSB(1) | CCM_ANALOG_MISC2_AUDIO_DIV_LSB(0): - freq >>= 0U; - break; - - default: - assert(false); - break; - } - break; - - case kCLOCK_PllVideo: - /* PLL output frequency = Fref * (DIV_SELECT + NUM/DENOM). */ - divSelect = - (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_VIDEO_DIV_SELECT_SHIFT; - - freqTmp = ((clock_64b_t)freq * ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_NUM))); - freqTmp /= ((clock_64b_t)(CCM_ANALOG->PLL_VIDEO_DENOM)); - freq = freq * divSelect + (uint32_t)freqTmp; - - /* VIDEO PLL output = PLL output frequency / POSTDIV. */ - - /* - * Post divider: - * - * PLL_VIDEO[POST_DIV_SELECT]: - * 0x00: 4 - * 0x01: 2 - * 0x02: 1 - * - * MISC2[VIDEO_DIV]: - * 0x00: 1 - * 0x01: 2 - * 0x02: 1 - * 0x03: 4 - */ - switch (CCM_ANALOG->PLL_VIDEO & CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT_MASK) - { - case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(0U): - freq = freq >> 2U; - break; - - case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(1U): - freq = freq >> 1U; - break; - - case CCM_ANALOG_PLL_VIDEO_POST_DIV_SELECT(2U): - freq = freq >> 0U; - break; - - default: - assert(false); - break; - } - - switch (CCM_ANALOG->MISC2 & CCM_ANALOG_MISC2_VIDEO_DIV_MASK) - { - case CCM_ANALOG_MISC2_VIDEO_DIV(3U): - freq >>= 2U; - break; - - case CCM_ANALOG_MISC2_VIDEO_DIV(1U): - freq >>= 1U; - break; - - case CCM_ANALOG_MISC2_VIDEO_DIV(0U): - case CCM_ANALOG_MISC2_VIDEO_DIV(2U): - freq >>= 0U; - break; - - default: - assert(false); - break; - } - break; - case kCLOCK_PllEnet: - divSelect = - (CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK) >> CCM_ANALOG_PLL_ENET_DIV_SELECT_SHIFT; - freq = enetRefClkFreq[divSelect]; - break; - - case kCLOCK_PllEnet25M: - /* ref_enetpll1 if fixed at 25MHz. */ - freq = 25000000UL; - break; - - case kCLOCK_PllUsb2: - freq = (freq * (((CCM_ANALOG->PLL_USB2 & CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK) != 0U) ? 22U : 20U)); - break; - default: - freq = 0U; - break; - } - - return freq; -} - -/*! - * brief Initialize the System PLL PFD. - * - * This function initializes the System PLL PFD. During new value setting, - * the clock output is disabled to prevent glitch. - * - * param pfd Which PFD clock to enable. - * param pfdFrac The PFD FRAC value. - * note It is recommended that PFD settings are kept between 12-35. - */ -void CLOCK_InitSysPfd(clock_pfd_t pfd, uint8_t pfdFrac) -{ - uint32_t pfdIndex = (uint32_t)pfd; - uint32_t pfd528; - - pfd528 = CCM_ANALOG->PFD_528 & - ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) - << (8UL * pfdIndex))); - - /* Disable the clock output first. */ - CCM_ANALOG->PFD_528 = pfd528 | ((uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); - - /* Set the new value and enable output. */ - CCM_ANALOG->PFD_528 = pfd528 | (CCM_ANALOG_PFD_528_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); -} - -/*! - * brief De-initialize the System PLL PFD. - * - * This function disables the System PLL PFD. - * - * param pfd Which PFD clock to disable. - */ -void CLOCK_DeinitSysPfd(clock_pfd_t pfd) -{ - CCM_ANALOG->PFD_528 |= (uint32_t)CCM_ANALOG_PFD_528_PFD0_CLKGATE_MASK << (8U * (uint8_t)pfd); -} - -/*! - * brief Initialize the USB1 PLL PFD. - * - * This function initializes the USB1 PLL PFD. During new value setting, - * the clock output is disabled to prevent glitch. - * - * param pfd Which PFD clock to enable. - * param pfdFrac The PFD FRAC value. - * note It is recommended that PFD settings are kept between 12-35. - */ -void CLOCK_InitUsb1Pfd(clock_pfd_t pfd, uint8_t pfdFrac) -{ - uint32_t pfdIndex = (uint32_t)pfd; - uint32_t pfd480; - - pfd480 = CCM_ANALOG->PFD_480 & - ~(((uint32_t)((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK | CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) - << (8UL * pfdIndex))); - - /* Disable the clock output first. */ - CCM_ANALOG->PFD_480 = pfd480 | ((uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * pfdIndex)); - - /* Set the new value and enable output. */ - CCM_ANALOG->PFD_480 = pfd480 | (CCM_ANALOG_PFD_480_PFD0_FRAC(pfdFrac) << (8UL * pfdIndex)); -} - -/*! - * brief De-initialize the USB1 PLL PFD. - * - * This function disables the USB1 PLL PFD. - * - * param pfd Which PFD clock to disable. - */ -void CLOCK_DeinitUsb1Pfd(clock_pfd_t pfd) -{ - CCM_ANALOG->PFD_480 |= (uint32_t)CCM_ANALOG_PFD_480_PFD0_CLKGATE_MASK << (8UL * (uint8_t)pfd); -} - -/*! - * brief Get current System PLL PFD output frequency. - * - * This function get current output frequency of specific System PLL PFD - * - * param pfd pfd name to get frequency. - * return The PFD output frequency in hertz. - */ -uint32_t CLOCK_GetSysPfdFreq(clock_pfd_t pfd) -{ - uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllSys); - - switch (pfd) - { - case kCLOCK_Pfd0: - freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD0_FRAC_SHIFT); - break; - - case kCLOCK_Pfd1: - freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD1_FRAC_SHIFT); - break; - - case kCLOCK_Pfd2: - freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD2_FRAC_SHIFT); - break; - - case kCLOCK_Pfd3: - freq /= ((CCM_ANALOG->PFD_528 & CCM_ANALOG_PFD_528_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_528_PFD3_FRAC_SHIFT); - break; - - default: - freq = 0U; - break; - } - freq *= 18U; - - return freq; -} - -/*! - * brief Get current USB1 PLL PFD output frequency. - * - * This function get current output frequency of specific USB1 PLL PFD - * - * param pfd pfd name to get frequency. - * return The PFD output frequency in hertz. - */ -uint32_t CLOCK_GetUsb1PfdFreq(clock_pfd_t pfd) -{ - uint32_t freq = CLOCK_GetPllFreq(kCLOCK_PllUsb1); - - switch (pfd) - { - case kCLOCK_Pfd0: - freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD0_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD0_FRAC_SHIFT); - break; - - case kCLOCK_Pfd1: - freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD1_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD1_FRAC_SHIFT); - break; - - case kCLOCK_Pfd2: - freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD2_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD2_FRAC_SHIFT); - break; - - case kCLOCK_Pfd3: - freq /= ((CCM_ANALOG->PFD_480 & CCM_ANALOG_PFD_480_PFD3_FRAC_MASK) >> CCM_ANALOG_PFD_480_PFD3_FRAC_SHIFT); - break; - - default: - freq = 0U; - break; - } - freq *= 18U; - - return freq; -} - -/*! brief Enable USB HS PHY PLL clock. - * - * This function enables the internal 480MHz USB PHY PLL clock. - * - * param src USB HS PHY PLL clock source. - * param freq The frequency specified by src. - * retval true The clock is set successfully. - * retval false The clock source is invalid to get proper USB HS clock. - */ -bool CLOCK_EnableUsbhs1PhyPllClock(clock_usb_phy_src_t src, uint32_t freq) -{ - const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; - CLOCK_InitUsb2Pll(&g_ccmConfigUsbPll); - USBPHY2->CTRL &= ~USBPHY_CTRL_SFTRST_MASK; /* release PHY from reset */ - USBPHY2->CTRL &= ~USBPHY_CTRL_CLKGATE_MASK; - - USBPHY2->PWD = 0; - USBPHY2->CTRL |= USBPHY_CTRL_ENAUTOCLR_PHY_PWD_MASK | USBPHY_CTRL_ENAUTOCLR_CLKGATE_MASK | - USBPHY_CTRL_ENUTMILEVEL2_MASK | USBPHY_CTRL_ENUTMILEVEL3_MASK; - - return true; -} - -/*! brief Disable USB HS PHY PLL clock. - * - * This function disables USB HS PHY PLL clock. - */ -void CLOCK_DisableUsbhs1PhyPllClock(void) -{ - CCM_ANALOG->PLL_USB2 &= ~CCM_ANALOG_PLL_USB2_EN_USB_CLKS_MASK; - USBPHY2->CTRL |= USBPHY_CTRL_CLKGATE_MASK; /* Set to 1U to gate clocks */ -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c deleted file mode 100644 index 8f6bed69b4..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_cmp.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_cmp.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.cmp" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for CMP module. - * - * @param base CMP peripheral base address - */ -static uint32_t CMP_GetInstance(CMP_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to CMP bases for each instance. */ -static CMP_Type *const s_cmpBases[] = CMP_BASE_PTRS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to CMP clocks for each instance. */ -static const clock_ip_name_t s_cmpClocks[] = CMP_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Codes - ******************************************************************************/ -static uint32_t CMP_GetInstance(CMP_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_cmpBases); instance++) - { - if (s_cmpBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_cmpBases)); - - return instance; -} - -/*! - * brief Initializes the CMP. - * - * This function initializes the CMP module. The operations included are as follows. - * - Enabling the clock for CMP module. - * - Configuring the comparator. - * - Enabling the CMP module. - * Note that for some devices, multiple CMP instances share the same clock gate. In this case, to enable the clock for - * any instance enables all CMPs. See the appropriate MCU reference manual for the clock assignment of the CMP. - * - * param base CMP peripheral base address. - * param config Pointer to the configuration structure. - */ -void CMP_Init(CMP_Type *base, const cmp_config_t *config) -{ - assert(NULL != config); - - uint8_t tmp8; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock. */ - CLOCK_EnableClock(s_cmpClocks[CMP_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Configure. */ - CMP_Enable(base, false); /* Disable the CMP module during configuring. */ - /* CMPx_CR1. */ - tmp8 = (uint8_t)(base->CR1 & ~(CMP_CR1_PMODE_MASK | CMP_CR1_INV_MASK | CMP_CR1_COS_MASK | CMP_CR1_OPE_MASK)); - if (true == config->enableHighSpeed) - { - tmp8 |= CMP_CR1_PMODE_MASK; - } - if (true == config->enableInvertOutput) - { - tmp8 |= CMP_CR1_INV_MASK; - } - if (true == config->useUnfilteredOutput) - { - tmp8 |= CMP_CR1_COS_MASK; - } - if (true == config->enablePinOut) - { - tmp8 |= CMP_CR1_OPE_MASK; - } -#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE - if (true == config->enableTriggerMode) - { - tmp8 |= CMP_CR1_TRIGM_MASK; - } - else - { - tmp8 &= ~(uint8_t)CMP_CR1_TRIGM_MASK; - } -#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ - base->CR1 = tmp8; - - /* CMPx_CR0. */ - tmp8 = base->CR0 & ~(uint8_t)CMP_CR0_HYSTCTR_MASK; - tmp8 |= CMP_CR0_HYSTCTR(config->hysteresisMode); - base->CR0 = tmp8; - - CMP_Enable(base, config->enableCmp); /* Enable the CMP module after configured or not. */ -} - -/*! - * brief De-initializes the CMP module. - * - * This function de-initializes the CMP module. The operations included are as follows. - * - Disabling the CMP module. - * - Disabling the clock for CMP module. - * - * This function disables the clock for the CMP. - * Note that for some devices, multiple CMP instances share the same clock gate. In this case, before disabling the - * clock for the CMP, ensure that all the CMP instances are not used. - * - * param base CMP peripheral base address. - */ -void CMP_Deinit(CMP_Type *base) -{ - /* Disable the CMP module. */ - CMP_Enable(base, false); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the clock. */ - CLOCK_DisableClock(s_cmpClocks[CMP_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Initializes the CMP user configuration structure. - * - * This function initializes the user configuration structure to these default values. - * code - * config->enableCmp = true; - * config->hysteresisMode = kCMP_HysteresisLevel0; - * config->enableHighSpeed = false; - * config->enableInvertOutput = false; - * config->useUnfilteredOutput = false; - * config->enablePinOut = false; - * config->enableTriggerMode = false; - * endcode - * param config Pointer to the configuration structure. - */ -void CMP_GetDefaultConfig(cmp_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableCmp = true; /* Enable the CMP module after initialization. */ - config->hysteresisMode = kCMP_HysteresisLevel0; - config->enableHighSpeed = false; - config->enableInvertOutput = false; - config->useUnfilteredOutput = false; - config->enablePinOut = false; -#if defined(FSL_FEATURE_CMP_HAS_TRIGGER_MODE) && FSL_FEATURE_CMP_HAS_TRIGGER_MODE - config->enableTriggerMode = false; -#endif /* FSL_FEATURE_CMP_HAS_TRIGGER_MODE */ -} - -/*! - * brief Sets the input channels for the comparator. - * - * This function sets the input channels for the comparator. - * Note that two input channels cannot be set the same way in the application. When the user selects the same input - * from the analog mux to the positive and negative port, the comparator is disabled automatically. - * - * param base CMP peripheral base address. - * param positiveChannel Positive side input channel number. Available range is 0-7. - * param negativeChannel Negative side input channel number. Available range is 0-7. - */ -void CMP_SetInputChannels(CMP_Type *base, uint8_t positiveChannel, uint8_t negativeChannel) -{ - uint8_t tmp8 = base->MUXCR; - - tmp8 &= ~(uint8_t)(CMP_MUXCR_PSEL_MASK | CMP_MUXCR_MSEL_MASK); - tmp8 |= CMP_MUXCR_PSEL(positiveChannel) | CMP_MUXCR_MSEL(negativeChannel); - base->MUXCR = tmp8; -} - -#if defined(FSL_FEATURE_CMP_HAS_DMA) && FSL_FEATURE_CMP_HAS_DMA -/*! - * brief Enables/disables the DMA request for rising/falling events. - * - * This function enables/disables the DMA request for rising/falling events. Either event triggers the generation of - * the DMA request from CMP if the DMA feature is enabled. Both events are ignored for generating the DMA request from - * the CMP - * if the DMA is disabled. - * - * param base CMP peripheral base address. - * param enable Enables or disables the feature. - */ -void CMP_EnableDMA(CMP_Type *base, bool enable) -{ - uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ - - if (enable) - { - tmp8 |= CMP_SCR_DMAEN_MASK; - } - else - { - tmp8 &= ~(uint8_t)CMP_SCR_DMAEN_MASK; - } - base->SCR = tmp8; -} -#endif /* FSL_FEATURE_CMP_HAS_DMA */ - -/*! - * brief Configures the filter. - * - * param base CMP peripheral base address. - * param config Pointer to the configuration structure. - */ -void CMP_SetFilterConfig(CMP_Type *base, const cmp_filter_config_t *config) -{ - assert(NULL != config); - - uint8_t tmp8; - -#if defined(FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT) && FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT - /* Choose the clock source for sampling. */ - if (config->enableSample) - { - base->CR1 |= CMP_CR1_SE_MASK; /* Choose the external SAMPLE clock. */ - } - else - { - base->CR1 &= (uint8_t)(~CMP_CR1_SE_MASK); /* Choose the internal divided bus clock. */ - } -#endif /* FSL_FEATURE_CMP_HAS_EXTERNAL_SAMPLE_SUPPORT */ - /* Set the filter count. */ - tmp8 = (uint8_t)(base->CR0 & ~CMP_CR0_FILTER_CNT_MASK); - tmp8 |= CMP_CR0_FILTER_CNT(config->filterCount); - base->CR0 = tmp8; - /* Set the filter period. It is used as the divider to bus clock. */ - base->FPR = CMP_FPR_FILT_PER(config->filterPeriod); -} - -/*! - * brief Configures the internal DAC. - * - * param base CMP peripheral base address. - * param config Pointer to the configuration structure. "NULL" disables the feature. - */ -void CMP_SetDACConfig(CMP_Type *base, const cmp_dac_config_t *config) -{ - uint8_t tmp8 = 0U; - - if (NULL == config) - { - /* Passing "NULL" as input parameter means no available configuration. So the DAC feature is disabled.*/ - base->DACCR = 0U; - return; - } - /* CMPx_DACCR. */ - tmp8 |= CMP_DACCR_DACEN_MASK; /* Enable the internal DAC. */ - if (kCMP_VrefSourceVin2 == config->referenceVoltageSource) - { - tmp8 |= CMP_DACCR_VRSEL_MASK; - } - tmp8 |= CMP_DACCR_VOSEL(config->DACValue); - - base->DACCR = tmp8; -} - -/*! - * brief Enables the interrupts. - * - * param base CMP peripheral base address. - * param mask Mask value for interrupts. See "_cmp_interrupt_enable". - */ -void CMP_EnableInterrupts(CMP_Type *base, uint32_t mask) -{ - uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ - - if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask)) - { - tmp8 |= CMP_SCR_IER_MASK; - } - if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask)) - { - tmp8 |= CMP_SCR_IEF_MASK; - } - base->SCR = tmp8; -} - -/*! - * brief Disables the interrupts. - * - * param base CMP peripheral base address. - * param mask Mask value for interrupts. See "_cmp_interrupt_enable". - */ -void CMP_DisableInterrupts(CMP_Type *base, uint32_t mask) -{ - uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ - - if (0U != ((uint32_t)kCMP_OutputRisingInterruptEnable & mask)) - { - tmp8 &= ~(uint8_t)CMP_SCR_IER_MASK; - } - if (0U != ((uint32_t)kCMP_OutputFallingInterruptEnable & mask)) - { - tmp8 &= ~(uint8_t)CMP_SCR_IEF_MASK; - } - base->SCR = tmp8; -} - -/*! - * brief Gets the status flags. - * - * param base CMP peripheral base address. - * - * return Mask value for the asserted flags. See "_cmp_status_flags". - */ -uint32_t CMP_GetStatusFlags(CMP_Type *base) -{ - uint32_t ret32 = 0U; - - if (0U != (CMP_SCR_CFR_MASK & base->SCR)) - { - ret32 |= (uint32_t)kCMP_OutputRisingEventFlag; - } - if (0U != (CMP_SCR_CFF_MASK & base->SCR)) - { - ret32 |= (uint32_t)kCMP_OutputFallingEventFlag; - } - if (0U != (CMP_SCR_COUT_MASK & base->SCR)) - { - ret32 |= (uint32_t)kCMP_OutputAssertEventFlag; - } - return ret32; -} - -/*! - * brief Clears the status flags. - * - * param base CMP peripheral base address. - * param mask Mask value for the flags. See "_cmp_status_flags". - */ -void CMP_ClearStatusFlags(CMP_Type *base, uint32_t mask) -{ - uint8_t tmp8 = (uint8_t)(base->SCR & ~(CMP_SCR_CFR_MASK | CMP_SCR_CFF_MASK)); /* To avoid change the w1c bits. */ - - if (0U != ((uint32_t)kCMP_OutputRisingEventFlag & mask)) - { - tmp8 |= CMP_SCR_CFR_MASK; - } - if (0U != ((uint32_t)kCMP_OutputFallingEventFlag & mask)) - { - tmp8 |= CMP_SCR_CFF_MASK; - } - base->SCR = tmp8; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c deleted file mode 100644 index fd96a955c3..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_common.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_common.h" -#define SDK_MEM_MAGIC_NUMBER 12345U - -typedef struct _mem_align_control_block -{ - uint16_t identifier; /*!< Identifier for the memory control block. */ - uint16_t offset; /*!< offset from aligned address to real address */ -} mem_align_cb_t; - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.common" -#endif - -#ifndef __GIC_PRIO_BITS -#if defined(ENABLE_RAM_VECTOR_TABLE) -uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) -{ -/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) - extern uint32_t Image$$VECTOR_ROM$$Base[]; - extern uint32_t Image$$VECTOR_RAM$$Base[]; - extern uint32_t Image$$RW_m_data$$Base[]; - -#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base -#define __VECTOR_RAM Image$$VECTOR_RAM$$Base -#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) -#elif defined(__ICCARM__) - extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; - extern uint32_t __VECTOR_TABLE[]; - extern uint32_t __VECTOR_RAM[]; -#elif defined(__GNUC__) - extern uint32_t __VECTOR_TABLE[]; - extern uint32_t __VECTOR_RAM[]; - extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; - uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); -#endif /* defined(__CC_ARM) || defined(__ARMCC_VERSION) */ - uint32_t n; - uint32_t ret; - uint32_t irqMaskValue; - - irqMaskValue = DisableGlobalIRQ(); - if (SCB->VTOR != (uint32_t)__VECTOR_RAM) - { - /* Copy the vector table from ROM to RAM */ - for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) - { - __VECTOR_RAM[n] = __VECTOR_TABLE[n]; - } - /* Point the VTOR to the position of vector table */ - SCB->VTOR = (uint32_t)__VECTOR_RAM; - } - - ret = __VECTOR_RAM[irq + 16]; - /* make sure the __VECTOR_RAM is noncachable */ - __VECTOR_RAM[irq + 16] = irqHandler; - - EnableGlobalIRQ(irqMaskValue); - SDK_ISR_EXIT_BARRIER; - - return ret; -} -#endif /* ENABLE_RAM_VECTOR_TABLE. */ -#endif /* __GIC_PRIO_BITS. */ - -#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) -#if !(defined(FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) && FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS) - -void EnableDeepSleepIRQ(IRQn_Type interrupt) -{ - uint32_t intNumber = (uint32_t)interrupt; - - uint32_t index = 0; - - while (intNumber >= 32u) - { - index++; - intNumber -= 32u; - } - - SYSCON->STARTERSET[index] = 1u << intNumber; - EnableIRQ(interrupt); /* also enable interrupt at NVIC */ -} - -void DisableDeepSleepIRQ(IRQn_Type interrupt) -{ - uint32_t intNumber = (uint32_t)interrupt; - - DisableIRQ(interrupt); /* also disable interrupt at NVIC */ - uint32_t index = 0; - - while (intNumber >= 32u) - { - index++; - intNumber -= 32u; - } - - SYSCON->STARTERCLR[index] = 1u << intNumber; -} -#endif /* FSL_FEATURE_SYSCON_STARTER_DISCONTINUOUS */ -#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ - -void *SDK_Malloc(size_t size, size_t alignbytes) -{ - mem_align_cb_t *p_cb = NULL; - uint32_t alignedsize = SDK_SIZEALIGN(size, alignbytes) + alignbytes + sizeof(mem_align_cb_t); - union - { - void *pointer_value; - uint32_t unsigned_value; - } p_align_addr, p_addr; - - p_addr.pointer_value = malloc(alignedsize); - - if (p_addr.pointer_value == NULL) - { - return NULL; - } - - p_align_addr.unsigned_value = SDK_SIZEALIGN(p_addr.unsigned_value + sizeof(mem_align_cb_t), alignbytes); - - p_cb = (mem_align_cb_t *)(p_align_addr.unsigned_value - 4U); - p_cb->identifier = SDK_MEM_MAGIC_NUMBER; - p_cb->offset = (uint16_t)(p_align_addr.unsigned_value - p_addr.unsigned_value); - - return p_align_addr.pointer_value; -} - -void SDK_Free(void *ptr) -{ - union - { - void *pointer_value; - uint32_t unsigned_value; - } p_free; - p_free.pointer_value = ptr; - mem_align_cb_t *p_cb = (mem_align_cb_t *)(p_free.unsigned_value - 4U); - - if (p_cb->identifier != SDK_MEM_MAGIC_NUMBER) - { - return; - } - - p_free.unsigned_value = p_free.unsigned_value - p_cb->offset; - - free(p_free.pointer_value); -} - -/*! - * @brief Delay function bases on while loop, every loop includes three instructions. - * - * @param count Counts of loop needed for dalay. - */ -#if defined(SDK_DELAY_USE_DWT) && defined(DWT) -void enableCpuCycleCounter(void) -{ - /* Make sure the DWT trace fucntion is enabled. */ - if (CoreDebug_DEMCR_TRCENA_Msk != (CoreDebug_DEMCR_TRCENA_Msk & CoreDebug->DEMCR)) - { - CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; - } - - /* CYCCNT not supported on this device. */ - assert(DWT_CTRL_NOCYCCNT_Msk != (DWT->CTRL & DWT_CTRL_NOCYCCNT_Msk)); - - /* Read CYCCNT directly if CYCCENT has already been enabled, otherwise enable CYCCENT first. */ - if (DWT_CTRL_CYCCNTENA_Msk != (DWT_CTRL_CYCCNTENA_Msk & DWT->CTRL)) - { - DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; - } -} - -uint32_t getCpuCycleCount(void) -{ - return DWT->CYCCNT; -} -#elif defined __XCC__ -extern uint32_t xthal_get_ccount(void); -void enableCpuCycleCounter(void) -{ - /* do nothing */ -} - -uint32_t getCpuCycleCount(void) -{ - return xthal_get_ccount(); -} -#endif - -#ifndef __XCC__ -#if (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) -#if defined(__CC_ARM) /* This macro is arm v5 specific */ -/* clang-format off */ -__ASM static void DelayLoop(uint32_t count) -{ -loop - SUBS R0, R0, #1 - CMP R0, #0 - BNE loop - BX LR -} -/* clang-format on */ -#elif defined(__ARMCC_VERSION) || defined(__ICCARM__) || defined(__GNUC__) -/* Cortex-M0 has a smaller instruction set, SUBS isn't supported in thumb-16 mode reported from __GNUC__ compiler, - * use SUB and CMP here for compatibility */ -static void DelayLoop(uint32_t count) -{ - __ASM volatile(" MOV R0, %0" : : "r"(count)); - __ASM volatile( - "loop: \n" -#if defined(__GNUC__) && !defined(__ARMCC_VERSION) - " SUB R0, R0, #1 \n" -#else - " SUBS R0, R0, #1 \n" -#endif - " CMP R0, #0 \n" - - " BNE loop \n"); -} -#endif /* defined(__CC_ARM) */ -#endif /* (!defined(SDK_DELAY_USE_DWT)) || (!defined(DWT)) */ -#endif /* __XCC__ */ -/*! - * @brief Delay at least for some time. - * Please note that, if not uses DWT, this API will use while loop for delay, different run-time environments have - * effect on the delay time. If precise delay is needed, please enable DWT delay. The two parmeters delay_us and - * coreClock_Hz have limitation. For example, in the platform with 1GHz coreClock_Hz, the delay_us only supports - * up to 4294967 in current code. If long time delay is needed, please implement a new delay function. - * - * @param delay_us Delay time in unit of microsecond. - * @param coreClock_Hz Core clock frequency with Hz. - */ -void SDK_DelayAtLeastUs(uint32_t delay_us, uint32_t coreClock_Hz) -{ - assert(0U != delay_us); - uint64_t count = USEC_TO_COUNT(delay_us, coreClock_Hz); - assert(count <= UINT32_MAX); - -#if defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) /* Use DWT for better accuracy */ - - enableCpuCycleCounter(); - /* Calculate the count ticks. */ - count += getCpuCycleCount(); - - if (count > UINT32_MAX) - { - count -= UINT32_MAX; - /* Wait for cyccnt overflow. */ - while (count < getCpuCycleCount()) - { - } - } - - /* Wait for cyccnt reach count value. */ - while (count > getCpuCycleCount()) - { - } -#else - /* Divide value may be different in various environment to ensure delay is precise. - * Every loop count includes three instructions, due to Cortex-M7 sometimes executes - * two instructions in one period, through test here set divide 1.5. Other M cores use - * divide 4. By the way, divide 1.5 or 4 could let the count lose precision, but it does - * not matter because other instructions outside while loop is enough to fill the time. - */ -#if (__CORTEX_M == 7) - count = count / 3U * 2U; -#else - count = count / 4U; -#endif - DelayLoop((uint32_t)count); -#endif /* defined(SDK_DELAY_USE_DWT) && defined(DWT) || (defined __XCC__) */ -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c deleted file mode 100644 index 2eea263e5f..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_csi.c +++ /dev/null @@ -1,1395 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_csi.h" -#if CSI_DRIVER_FRAG_MODE -#include "fsl_cache.h" -#endif - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.csi" -#endif - -/* Two frame buffer loaded to CSI register at most. */ -#define CSI_MAX_ACTIVE_FRAME_NUM 2U - -/* CSI driver only support RGB565 and YUV422 in fragment mode, 2 bytes per pixel. */ -#define CSI_FRAG_INPUT_BYTES_PER_PIXEL 2U - -/*! - * @brief Used for conversion between `void*` and `uint32_t`. - */ -typedef union pvoid_to_u32 -{ - void *pvoid; - uint32_t u32; -} pvoid_to_u32_t; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get the instance from the base address - * - * @param base CSI peripheral base address - * - * @return The CSI module instance - */ -static uint32_t CSI_GetInstance(CSI_Type *base); - -#if !CSI_DRIVER_FRAG_MODE -/*! - * @brief Get the delta value of two index in queue. - * - * @param startIdx Start index. - * @param endIdx End index. - * - * @return The delta between startIdx and endIdx in queue. - */ -static uint8_t CSI_TransferGetQueueDelta(uint8_t startIdx, uint8_t endIdx); - -/*! - * @brief Increase a index value in queue. - * - * This function increases the index value in the queue, if the index is out of - * the queue range, it is reset to 0. - * - * @param idx The index value to increase. - * - * @return The index value after increase. - */ -static uint8_t CSI_TransferIncreaseQueueIdx(uint8_t idx); - -/*! - * @brief Get the empty frame buffer count in queue. - * - * @param base CSI peripheral base address - * @param handle Pointer to CSI driver handle. - * - * @return Number of the empty frame buffer count in queue. - */ -static uint32_t CSI_TransferGetEmptyBufferCount(csi_handle_t *handle); - -/*! - * @brief Get the empty frame buffer. - * - * This function should only be called when frame buffer count larger than 0. - * - * @param handle Pointer to CSI driver handle. - * - * @return Empty buffer - */ -static uint32_t CSI_TransferGetEmptyBuffer(csi_handle_t *handle); - -/*! - * @brief Put the empty frame buffer. - * - * @param handle Pointer to CSI driver handle. - * @param buffer The empty buffer to put. - */ -static void CSI_TransferPutEmptyBuffer(csi_handle_t *handle, uint32_t buffer); - -/*! - * @brief Get the RX frame buffer address. - * - * @param base CSI peripheral base address. - * @param index Buffer index. - * @return Frame buffer address. - */ -static uint32_t CSI_GetRxBufferAddr(CSI_Type *base, uint8_t index); - -/* Typedef for interrupt handler. */ -typedef void (*csi_isr_t)(CSI_Type *base, csi_handle_t *handle); - -#else - -/* Typedef for interrupt handler to work in fragment mode. */ -typedef void (*csi_isr_t)(CSI_Type *base, csi_frag_handle_t *handle); -#endif /* CSI_DRIVER_FRAG_MODE */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to CSI bases for each instance. */ -static CSI_Type *const s_csiBases[] = CSI_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to CSI clocks for each CSI submodule. */ -static const clock_ip_name_t s_csiClocks[] = CSI_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/* Array for the CSI driver handle. */ -#if !CSI_DRIVER_FRAG_MODE -static csi_handle_t *s_csiHandle[ARRAY_SIZE(s_csiBases)]; -#else -static csi_frag_handle_t *s_csiHandle[ARRAY_SIZE(s_csiBases)]; -#endif - -/* Array of CSI IRQ number. */ -static const IRQn_Type s_csiIRQ[] = CSI_IRQS; - -/* CSI ISR for transactional APIs. */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -static csi_isr_t s_csiIsr = (csi_isr_t)DefaultISR; -#else -static csi_isr_t s_csiIsr; -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t CSI_GetInstance(CSI_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_csiBases); instance++) - { - if (s_csiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_csiBases)); - - return instance; -} - -#if !CSI_DRIVER_FRAG_MODE -static uint8_t CSI_TransferGetQueueDelta(uint8_t startIdx, uint8_t endIdx) -{ - uint8_t ret; - - if (endIdx >= startIdx) - { - ret = endIdx - startIdx; - } - else - { - ret = (uint8_t)(endIdx + CSI_DRIVER_ACTUAL_QUEUE_SIZE - startIdx); - } - - return ret; -} - -static uint8_t CSI_TransferIncreaseQueueIdx(uint8_t idx) -{ - uint8_t ret; - - /* - * Here not use the method: - * ret = (idx+1) % CSI_DRIVER_ACTUAL_QUEUE_SIZE; - * - * Because the mod function might be slow. - */ - - ret = idx + 1U; - - if (ret >= CSI_DRIVER_ACTUAL_QUEUE_SIZE) - { - ret = 0U; - } - - return ret; -} - -static uint32_t CSI_TransferGetEmptyBufferCount(csi_handle_t *handle) -{ - return handle->emptyBufferCnt; -} - -static uint32_t CSI_TransferGetEmptyBuffer(csi_handle_t *handle) -{ - pvoid_to_u32_t buf; - - buf.pvoid = handle->emptyBuffer; - handle->emptyBufferCnt--; - handle->emptyBuffer = *(void **)(buf.pvoid); - - return buf.u32; -} - -static void CSI_TransferPutEmptyBuffer(csi_handle_t *handle, uint32_t buffer) -{ - pvoid_to_u32_t buf; - buf.u32 = buffer; - - *(void **)(buf.pvoid) = handle->emptyBuffer; - handle->emptyBuffer = buf.pvoid; - handle->emptyBufferCnt++; -} - -static uint32_t CSI_GetRxBufferAddr(CSI_Type *base, uint8_t index) -{ - uint32_t addr; - - if (index != 0U) - { - addr = base->CSIDMASA_FB2; - } - else - { - addr = base->CSIDMASA_FB1; - } - - return addr; -} - -#endif /* CSI_DRIVER_FRAG_MODE */ - -/*! - * brief Initialize the CSI. - * - * This function enables the CSI peripheral clock, and resets the CSI registers. - * - * param base CSI peripheral base address. - * param config Pointer to the configuration structure. - * - * retval kStatus_Success Initialize successfully. - * retval kStatus_InvalidArgument Initialize failed because of invalid argument. - */ -status_t CSI_Init(CSI_Type *base, const csi_config_t *config) -{ - assert(NULL != config); - uint32_t reg; - uint32_t imgWidth_Bytes; - uint8_t busCyclePerPixel; - - imgWidth_Bytes = (uint32_t)config->width * (uint32_t)config->bytesPerPixel; - - /* The image width and frame buffer pitch should be multiple of 8-bytes. */ - if ((0U != (imgWidth_Bytes & 0x07U)) || (0U != ((uint32_t)config->linePitch_Bytes & 0x07U))) - { - return kStatus_InvalidArgument; - } - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = CSI_GetInstance(base); - CLOCK_EnableClock(s_csiClocks[instance]); -#endif - - CSI_Reset(base); - - /* Configure CSICR1. CSICR1 has been reset to the default value, so could write it directly. */ - reg = ((uint32_t)config->workMode) | config->polarityFlags | CSI_CSICR1_FCC_MASK; - - if (config->useExtVsync) - { - reg |= CSI_CSICR1_EXT_VSYNC_MASK; - } - - base->CSICR1 = reg; - - /* - * Generally, CSIIMAG_PARA[IMAGE_WIDTH] indicates how many data bus cycles per line. - * One special case is when receiving 24-bit pixels through 8-bit data bus. - * In this case, the CSIIMAG_PARA[IMAGE_WIDTH] should be set to the pixel number per line. - */ - if ((kCSI_DataBus8Bit == config->dataBus) && (2U == config->bytesPerPixel)) - { - busCyclePerPixel = 2U; - } - else - { - busCyclePerPixel = 1U; - } - - if (4U == config->bytesPerPixel) - { - base->CSICR18 |= CSI_CSICR18_PARALLEL24_EN_MASK; - } - - if (kCSI_DataBus16Bit == config->dataBus) - { - base->CSICR3 |= CSI_CSICR3_TWO_8BIT_SENSOR_MASK; - } - - /* Image parameter. */ - base->CSIIMAG_PARA = - (((uint32_t)config->width * (uint32_t)busCyclePerPixel) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) | - ((uint32_t)(config->height) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT); - - /* The CSI frame buffer bus is 8-byte width. */ - base->CSIFBUF_PARA = (uint32_t)((config->linePitch_Bytes - imgWidth_Bytes) / 8U) - << CSI_CSIFBUF_PARA_FBUF_STRIDE_SHIFT; - - /* Enable auto ECC. */ - base->CSICR3 |= CSI_CSICR3_ECC_AUTO_EN_MASK; - - /* - * For better performance. - * The DMA burst size could be set to 16 * 8 byte, 8 * 8 byte, or 4 * 8 byte, - * choose the best burst size based on bytes per line. - */ - if (0U == (imgWidth_Bytes % (8U * 16U))) - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(3U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((2U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - else if (0U == (imgWidth_Bytes % (8U * 8U))) - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(2U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((1U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - else - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(1U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((0U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - - CSI_ReflashFifoDma(base, kCSI_RxFifo); - - return kStatus_Success; -} - -/*! - * brief De-initialize the CSI. - * - * This function disables the CSI peripheral clock. - * - * param base CSI peripheral base address. - */ -void CSI_Deinit(CSI_Type *base) -{ - /* Disable transfer first. */ - CSI_Stop(base); -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = CSI_GetInstance(base); - CLOCK_DisableClock(s_csiClocks[instance]); -#endif -} - -/*! - * brief Reset the CSI. - * - * This function resets the CSI peripheral registers to default status. - * - * param base CSI peripheral base address. - */ -void CSI_Reset(CSI_Type *base) -{ - uint32_t csisr; - - /* Disable transfer first. */ - CSI_Stop(base); - - /* Disable DMA request. */ - base->CSICR3 = 0U; - - /* Reset the fame count. */ - base->CSICR3 |= CSI_CSICR3_FRMCNT_RST_MASK; - while (0U != (base->CSICR3 & CSI_CSICR3_FRMCNT_RST_MASK)) - { - } - - /* Clear the RX FIFO. */ - CSI_ClearFifo(base, kCSI_AllFifo); - - /* Reflash DMA. */ - CSI_ReflashFifoDma(base, kCSI_AllFifo); - - /* Clear the status. */ - csisr = base->CSISR; - base->CSISR = csisr; - - /* Set the control registers to default value. */ - base->CSICR1 = CSI_CSICR1_HSYNC_POL_MASK | CSI_CSICR1_EXT_VSYNC_MASK; - base->CSICR2 = 0U; - base->CSICR3 = 0U; -#if defined(CSI_CSICR18_CSI_LCDIF_BUFFER_LINES) - base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU) | CSI_CSICR18_CSI_LCDIF_BUFFER_LINES(0x02U); -#else - base->CSICR18 = CSI_CSICR18_AHB_HPROT(0x0DU); -#endif - base->CSIFBUF_PARA = 0U; - base->CSIIMAG_PARA = 0U; -} - -/*! - * brief Get the default configuration for to initialize the CSI. - * - * The default configuration value is: - * - * code - config->width = 320U; - config->height = 240U; - config->polarityFlags = kCSI_HsyncActiveHigh | kCSI_DataLatchOnRisingEdge; - config->bytesPerPixel = 2U; - config->linePitch_Bytes = 320U * 2U; - config->workMode = kCSI_GatedClockMode; - config->dataBus = kCSI_DataBus8Bit; - config->useExtVsync = true; - endcode - * - * param config Pointer to the CSI configuration. - */ -void CSI_GetDefaultConfig(csi_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->width = 320U; - config->height = 240U; - config->polarityFlags = (uint32_t)kCSI_HsyncActiveHigh | (uint32_t)kCSI_DataLatchOnRisingEdge; - config->bytesPerPixel = 2U; - config->linePitch_Bytes = 320U * 2U; - config->workMode = kCSI_GatedClockMode; - config->dataBus = kCSI_DataBus8Bit; - config->useExtVsync = true; -} - -/*! - * brief Set the RX frame buffer address. - * - * param base CSI peripheral base address. - * param index Buffer index. - * param addr Frame buffer address to set. - */ -void CSI_SetRxBufferAddr(CSI_Type *base, uint8_t index, uint32_t addr) -{ - if (0U != index) - { - base->CSIDMASA_FB2 = addr; - } - else - { - base->CSIDMASA_FB1 = addr; - } -} - -/*! - * brief Clear the CSI FIFO. - * - * This function clears the CSI FIFO. - * - * param base CSI peripheral base address. - * param fifo The FIFO to clear. - */ -void CSI_ClearFifo(CSI_Type *base, csi_fifo_t fifo) -{ - uint32_t cr1; - uint32_t mask = 0U; - - /* The FIFO could only be cleared when CSICR1[FCC] = 0, so first clear the FCC. */ - cr1 = base->CSICR1; - base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK); - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)) - { - mask |= CSI_CSICR1_CLR_RXFIFO_MASK; - } - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)) - { - mask |= CSI_CSICR1_CLR_STATFIFO_MASK; - } - - base->CSICR1 = (cr1 & ~CSI_CSICR1_FCC_MASK) | mask; - - /* Wait clear completed. */ - while (0U != (base->CSICR1 & mask)) - { - } - - /* Recover the FCC. */ - base->CSICR1 = cr1; -} - -/*! - * brief Reflash the CSI FIFO DMA. - * - * This function reflashes the CSI FIFO DMA. - * - * For RXFIFO, there are two frame buffers. When the CSI module started, it saves - * the frames to frame buffer 0 then frame buffer 1, the two buffers will be - * written by turns. After reflash DMA using this function, the CSI is reset to - * save frame to buffer 0. - * - * param base CSI peripheral base address. - * param fifo The FIFO DMA to reflash. - */ -void CSI_ReflashFifoDma(CSI_Type *base, csi_fifo_t fifo) -{ - uint32_t cr3 = 0U; - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)) - { - cr3 |= CSI_CSICR3_DMA_REFLASH_RFF_MASK; - } - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)) - { - cr3 |= CSI_CSICR3_DMA_REFLASH_SFF_MASK; - } - - base->CSICR3 |= cr3; - - /* Wait clear completed. */ - while (0U != (base->CSICR3 & cr3)) - { - } -} - -/*! - * brief Enable or disable the CSI FIFO DMA request. - * - * param base CSI peripheral base address. - * param fifo The FIFO DMA reques to enable or disable. - * param enable True to enable, false to disable. - */ -void CSI_EnableFifoDmaRequest(CSI_Type *base, csi_fifo_t fifo, bool enable) -{ - uint32_t cr3 = 0U; - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_RxFifo)) - { - cr3 |= CSI_CSICR3_DMA_REQ_EN_RFF_MASK; - } - - if (0U != ((uint32_t)fifo & (uint32_t)kCSI_StatFifo)) - { - cr3 |= CSI_CSICR3_DMA_REQ_EN_SFF_MASK; - } - - if (enable) - { - base->CSICR3 |= cr3; - } - else - { - base->CSICR3 &= ~cr3; - } -} - -/*! - * brief Enables CSI interrupt requests. - * - * param base CSI peripheral base address. - * param mask The interrupts to enable, pass in as OR'ed value of ref _csi_interrupt_enable. - */ -void CSI_EnableInterrupts(CSI_Type *base, uint32_t mask) -{ - base->CSICR1 |= (mask & CSI_CSICR1_INT_EN_MASK); - base->CSICR3 |= (mask & CSI_CSICR3_INT_EN_MASK); - base->CSICR18 |= ((mask & CSI_CSICR18_INT_EN_MASK) >> 6U); -} - -/*! - * brief Disable CSI interrupt requests. - * - * param base CSI peripheral base address. - * param mask The interrupts to disable, pass in as OR'ed value of ref _csi_interrupt_enable. - */ -void CSI_DisableInterrupts(CSI_Type *base, uint32_t mask) -{ - base->CSICR1 &= ~(mask & CSI_CSICR1_INT_EN_MASK); - base->CSICR3 &= ~(mask & CSI_CSICR3_INT_EN_MASK); - base->CSICR18 &= ~((mask & CSI_CSICR18_INT_EN_MASK) >> 6U); -} - -#if !CSI_DRIVER_FRAG_MODE -/*! - * brief Initializes the CSI handle. - * - * This function initializes CSI handle, it should be called before any other - * CSI transactional functions. - * - * param base CSI peripheral base address. - * param handle Pointer to the handle structure. - * param callback Callback function for CSI transfer. - * param userData Callback function parameter. - * - * retval kStatus_Success Handle created successfully. - */ -status_t CSI_TransferCreateHandle(CSI_Type *base, - csi_handle_t *handle, - csi_transfer_callback_t callback, - void *userData) -{ - assert(NULL != handle); - uint32_t instance; - - (void)memset(handle, 0, sizeof(*handle)); - - /* Set the callback and user data. */ - handle->callback = callback; - handle->userData = userData; - - /* Get instance from peripheral base address. */ - instance = CSI_GetInstance(base); - - /* Save the handle in global variables to support the double weak mechanism. */ - s_csiHandle[instance] = handle; - - s_csiIsr = CSI_TransferHandleIRQ; - - /* Enable interrupt. */ - (void)EnableIRQ(s_csiIRQ[instance]); - - return kStatus_Success; -} - -/*! - * brief Start the transfer using transactional functions. - * - * When the empty frame buffers have been submit to CSI driver using function - * ref CSI_TransferSubmitEmptyBuffer, user could call this function to start - * the transfer. The incoming frame will be saved to the empty frame buffer, - * and user could be optionally notified through callback function. - * - * param base CSI peripheral base address. - * param handle Pointer to the handle structure. - * - * retval kStatus_Success Started successfully. - * retval kStatus_CSI_NoEmptyBuffer Could not start because no empty frame buffer in queue. - */ -status_t CSI_TransferStart(CSI_Type *base, csi_handle_t *handle) -{ - assert(NULL != handle); - - uint32_t emptyBufferCount; - - emptyBufferCount = CSI_TransferGetEmptyBufferCount(handle); - - if (emptyBufferCount < 2U) - { - return kStatus_CSI_NoEmptyBuffer; - } - - /* - * Write to memory from first completed frame. - * DMA base addr switch at the edge of the first data of each frame, thus - * if one frame is broken, it could be reset at the next frame. - */ - base->CSICR18 = (base->CSICR18 & ~CSI_CSICR18_MASK_OPTION_MASK) | CSI_CSICR18_MASK_OPTION(0) | - CSI_CSICR18_BASEADDR_SWITCH_SEL_MASK | CSI_CSICR18_BASEADDR_SWITCH_EN_MASK; - - /* Load the frame buffer to CSI register, there are at least two empty buffers. */ - base->CSIDMASA_FB1 = CSI_TransferGetEmptyBuffer(handle); - base->CSIDMASA_FB2 = CSI_TransferGetEmptyBuffer(handle); - - handle->activeBufferNum = CSI_MAX_ACTIVE_FRAME_NUM; - - /* After reflash DMA, the CSI saves frame to frame buffer 0. */ - CSI_ReflashFifoDma(base, kCSI_RxFifo); - - handle->transferStarted = true; - - CSI_EnableInterrupts( - base, (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable); - - CSI_Start(base); - - return kStatus_Success; -} - -/*! - * brief Stop the transfer using transactional functions. - * - * The driver does not clean the full frame buffers in queue. In other words, after - * calling this function, user still could get the full frame buffers in queue - * using function ref CSI_TransferGetFullBuffer. - * - * param base CSI peripheral base address. - * param handle Pointer to the handle structure. - * - * retval kStatus_Success Stoped successfully. - */ -status_t CSI_TransferStop(CSI_Type *base, csi_handle_t *handle) -{ - assert(NULL != handle); - uint8_t activeBufferNum; - uint8_t bufIdx; - - CSI_Stop(base); - CSI_DisableInterrupts( - base, (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable); - - activeBufferNum = handle->activeBufferNum; - - handle->transferStarted = false; - handle->activeBufferNum = 0; - - /* - * Put active buffers to empty queue. - * - * If there is only one active frame buffers, then FB0 and FB1 use the same address, - * put FB0 to empty buffer queue is OK. - */ - for (bufIdx = 0; bufIdx < activeBufferNum; bufIdx++) - { - CSI_TransferPutEmptyBuffer(handle, CSI_GetRxBufferAddr(base, bufIdx)); - } - - return kStatus_Success; -} - -/*! - * brief Submit empty frame buffer to queue. - * - * This function could be called before ref CSI_TransferStart or after ref - * CSI_TransferStart. If there is no room in queue to store the empty frame - * buffer, this function returns error. - * - * param base CSI peripheral base address. - * param handle Pointer to the handle structure. - * param frameBuffer Empty frame buffer to submit. - * - * retval kStatus_Success Started successfully. - * retval kStatus_CSI_QueueFull Could not submit because there is no room in queue. - */ -status_t CSI_TransferSubmitEmptyBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t frameBuffer) -{ - uint32_t csicr1; - - /* Disable the interrupt to protect the index information in handle. */ - csicr1 = base->CSICR1; - - base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK)); - - /* Save the empty frame buffer address to queue. */ - CSI_TransferPutEmptyBuffer(handle, frameBuffer); - - base->CSICR1 = csicr1; - - return kStatus_Success; -} - -/*! - * brief Get one full frame buffer from queue. - * - * After the transfer started using function ref CSI_TransferStart, the incoming - * frames will be saved to the empty frame buffers in queue. This function gets - * the full-filled frame buffer from the queue. If there is no full frame buffer - * in queue, this function returns error. - * - * param base CSI peripheral base address. - * param handle Pointer to the handle structure. - * param frameBuffer Full frame buffer. - * - * retval kStatus_Success Started successfully. - * retval kStatus_CSI_NoFullBuffer There is no full frame buffer in queue. - */ -status_t CSI_TransferGetFullBuffer(CSI_Type *base, csi_handle_t *handle, uint32_t *frameBuffer) -{ - uint32_t csicr1; - status_t status; - uint8_t queueReadIdx; - uint8_t queueWriteIdx; - - queueReadIdx = handle->queueReadIdx; - queueWriteIdx = handle->queueWriteIdx; - - /* No full frame buffer. */ - if (queueReadIdx == queueWriteIdx) - { - status = kStatus_CSI_NoFullBuffer; - } - else - { - /* Disable the interrupt to protect the index information in handle. */ - csicr1 = base->CSICR1; - - base->CSICR1 = (csicr1 & ~(CSI_CSICR1_FB2_DMA_DONE_INTEN_MASK | CSI_CSICR1_FB1_DMA_DONE_INTEN_MASK)); - - *frameBuffer = handle->frameBufferQueue[handle->queueReadIdx]; - - handle->queueReadIdx = CSI_TransferIncreaseQueueIdx(handle->queueReadIdx); - - base->CSICR1 = csicr1; - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief CSI IRQ handle function. - * - * This function handles the CSI IRQ request to work with CSI driver transactional - * APIs. - * - * param base CSI peripheral base address. - * param handle CSI handle pointer. - */ -void CSI_TransferHandleIRQ(CSI_Type *base, csi_handle_t *handle) -{ - uint8_t queueWriteIdx; - uint8_t queueReadIdx; - uint8_t dmaDoneBufferIdx; - uint32_t frameBuffer; - uint32_t csisr = base->CSISR; - - /* Clear the error flags. */ - base->CSISR = csisr; - - /* - * If both frame buffer 0 and frame buffer 1 flags assert, driver does not - * know which frame buffer ready just now, so skip them. - */ - if ((csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) == - (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) - { - ; /* Skip the frames. */ - } - else if (0U != (csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK))) - { - if (0U != (csisr & CSI_CSISR_DMA_TSF_DONE_FB2_MASK)) - { - dmaDoneBufferIdx = 1; - } - else - { - dmaDoneBufferIdx = 0; - } - - if (handle->activeBufferNum == CSI_MAX_ACTIVE_FRAME_NUM) - { - queueWriteIdx = handle->queueWriteIdx; - queueReadIdx = handle->queueReadIdx; - - if (CSI_TransferGetQueueDelta(queueReadIdx, queueWriteIdx) < CSI_DRIVER_QUEUE_SIZE) - { - /* Put the full frame buffer to full buffer queue. */ - frameBuffer = CSI_GetRxBufferAddr(base, dmaDoneBufferIdx); - handle->frameBufferQueue[queueWriteIdx] = frameBuffer; - - handle->queueWriteIdx = CSI_TransferIncreaseQueueIdx(queueWriteIdx); - - handle->activeBufferNum--; - - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_CSI_FrameDone, handle->userData); - } - } - else - { - } - } - - /* - * User may submit new frame buffer in callback, so recheck activeBufferNum here, - * if there is only one active buffer in CSI device, the two buffer registers - * are both set to the frame buffer address. - */ - if (handle->activeBufferNum < CSI_MAX_ACTIVE_FRAME_NUM) - { - if (CSI_TransferGetEmptyBufferCount(handle) > 0U) - { - /* Get the empty frameBuffer, and submit to CSI device. */ - CSI_SetRxBufferAddr(base, dmaDoneBufferIdx, CSI_TransferGetEmptyBuffer(handle)); - handle->activeBufferNum++; - } - else - { - /* If there is only one active frame buffer, then the two CSI - * output buffer address are all set to this frame buffer. - */ - frameBuffer = CSI_GetRxBufferAddr(base, dmaDoneBufferIdx ^ 1U); - CSI_SetRxBufferAddr(base, dmaDoneBufferIdx, frameBuffer); - } - } - } - else - { - } -} - -#else /* CSI_DRIVER_FRAG_MODE */ - -#if defined(__CC_ARM) -__asm void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count) -{ - /* clang-format off */ - push {r4-r7, lr} -10 - LDMIA R1!, {r3-r6} - bfi r7, r3, #0, #8 /* Y0 */ - bfi ip, r5, #0, #8 /* Y4 */ - lsr r3, r3, #16 - lsr r5, r5, #16 - bfi r7, r3, #8, #8 /* Y1 */ - bfi ip, r5, #8, #8 /* Y5 */ - bfi r7, r4, #16, #8 /* Y2 */ - bfi ip, r6, #16, #8 /* Y6 */ - lsr r4, r4, #16 - lsr r6, r6, #16 - bfi r7, r4, #24, #8 /* Y3 */ - bfi ip, r6, #24, #8 /* Y7 */ - STMIA r0!, {r7, ip} - subs r2, #8 - bne %b10 - pop {r4-r7, pc} - /* clang-format on */ -} - -__asm void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count) -{ - /* clang-format off */ - push {r4-r7, lr} -10 - LDMIA R1!, {r3-r6} - lsr r3, r3, #8 - lsr r5, r5, #8 - bfi r7, r3, #0, #8 /* Y0 */ - bfi ip, r5, #0, #8 /* Y4 */ - lsr r3, r3, #16 - lsr r5, r5, #16 - bfi r7, r3, #8, #8 /* Y1 */ - bfi ip, r5, #8, #8 /* Y5 */ - lsr r4, r4, #8 - lsr r6, r6, #8 - bfi r7, r4, #16, #8 /* Y2 */ - bfi ip, r6, #16, #8 /* Y6 */ - lsr r4, r4, #16 - lsr r6, r6, #16 - bfi r7, r4, #24, #8 /* Y3 */ - bfi ip, r6, #24, #8 /* Y7 */ - STMIA r0!, {r7, ip} - subs r2, #8 - bne %b10 - pop {r4-r7, pc} - /* clang-format on */ -} - -#elif (defined(__GNUC__) || defined(__ICCARM__)) || defined(__ARMCC_VERSION) -#if defined(__ICCARM__) -#pragma diag_suppress = Pe940 -#endif -__attribute__((naked)) void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count); -void CSI_ExtractYFromYUYV(void *datBase, const void *dmaBase, size_t count) -{ - /* clang-format off */ - __asm volatile( - " push {r1-r7, r12, lr} \n" - "loop0: \n" - " ldmia r1!, {r3-r6} \n" - " bfi r7, r3, #0, #8 \n" /* Y0 */ - " bfi r12, r5, #0, #8 \n" /* Y4 */ - " lsr r3, r3, #16 \n" - " lsr r5, r5, #16 \n" - " bfi r7, r3, #8, #8 \n" /* Y1 */ - " bfi r12, r5, #8, #8 \n" /* Y5 */ - " bfi r7, r4, #16, #8 \n" /* Y2 */ - " bfi r12, r6, #16, #8 \n" /* Y6 */ - " lsr r4, r4, #16 \n" - " lsr r6, r6, #16 \n" - " bfi r7, r4, #24, #8 \n" /* Y3 */ - " bfi r12, r6, #24, #8 \n" /* Y7 */ - " stmia r0!, {r7, r12} \n" - " subs r2, #8 \n" - " bne loop0 \n" - " pop {r1-r7, r12, pc} \n"); - /* clang-format on */ -} - -__attribute__((naked)) void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count); -void CSI_ExtractYFromUYVY(void *datBase, const void *dmaBase, size_t count) -{ - /* clang-format off */ - __asm volatile( - " push {r1-r7, r12, lr} \n" - "loop1: \n" - " ldmia r1!, {r3-r6} \n" - " lsr r3, r3, #8 \n" - " lsr r5, r5, #8 \n" - " bfi r7, r3, #0, #8 \n" /* Y0 */ - " bfi r12, r5, #0, #8 \n" /* Y4 */ - " lsr r3, r3, #16 \n" - " lsr r5, r5, #16 \n" - " bfi r7, r3, #8, #8 \n" /* Y1 */ - " bfi r12, r5, #8, #8 \n" /* Y5 */ - " lsr r4, r4, #8 \n" - " lsr r6, r6, #8 \n" - " bfi r7, r4, #16, #8 \n" /* Y2 */ - " bfi r12, r6, #16, #8 \n" /* Y6 */ - " lsr r4, r4, #16 \n" - " lsr r6, r6, #16 \n" - " bfi r7, r4, #24, #8 \n" /* Y3 */ - " bfi r12, r6, #24, #8 \n" /* Y7 */ - " stmia r0!, {r7, r12} \n" - " subs r2, #8 \n" - " bne loop1 \n" - " pop {r1-r7, r12, pc} \n"); - /* clang-format on */ -} -#if defined(__ICCARM__) -#pragma diag_default = Pe940 -#endif -#else -#error Toolchain not supported. -#endif - -static void CSI_MemCopy(void *pDest, const void *pSrc, size_t cnt) -{ - (void)memcpy(pDest, pSrc, cnt); -} - -/*! - * brief Initialize the CSI to work in fragment mode. - * - * This function enables the CSI peripheral clock, and resets the CSI registers. - * - * param base CSI peripheral base address. - */ -void CSI_FragModeInit(CSI_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = CSI_GetInstance(base); - CLOCK_EnableClock(s_csiClocks[instance]); -#endif - - CSI_Reset(base); -} - -/*! - * brief De-initialize the CSI. - * - * This function disables the CSI peripheral clock. - * - * param base CSI peripheral base address. - */ -void CSI_FragModeDeinit(CSI_Type *base) -{ - CSI_Deinit(base); -} - -/*! - * brief Create handle for CSI work in fragment mode. - * - * param base CSI peripheral base address. - * param handle Pointer to the transactional handle. - * param config Pointer to the configuration structure. - * param callback Callback function for CSI transfer. - * param userData Callback function parameter. - * - * retval kStatus_Success Initialize successfully. - * retval kStatus_InvalidArgument Initialize failed because of invalid argument. - */ -status_t CSI_FragModeCreateHandle(CSI_Type *base, - csi_frag_handle_t *handle, - const csi_frag_config_t *config, - csi_frag_transfer_callback_t callback, - void *userData) -{ - assert(NULL != config); - uint32_t reg; - uint32_t instance; - uint32_t imgWidth_Bytes; - - if (config->dataBus != kCSI_DataBus8Bit) - { - return kStatus_InvalidArgument; - } - - imgWidth_Bytes = (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL; - - /* The image buffer line width should be multiple of 8-bytes. */ - if ((imgWidth_Bytes & 0x07U) != 0U) - { - return kStatus_InvalidArgument; - } - - /* Camera frame height must be dividable by DMA buffer line. */ - if (config->height % config->dmaBufferLine != 0U) - { - return kStatus_InvalidArgument; - } - - (void)memset(handle, 0, sizeof(*handle)); - handle->callback = callback; - handle->userData = userData; - handle->height = config->height; - handle->width = config->width; - handle->maxLinePerFrag = config->dmaBufferLine; - handle->dmaBytePerLine = config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL; - handle->isDmaBufferCachable = config->isDmaBufferCachable; - - /* Get instance from peripheral base address. */ - instance = CSI_GetInstance(base); - /* Save the handle in global variables to support the double weak mechanism. */ - s_csiHandle[instance] = handle; - - s_csiIsr = CSI_FragModeTransferHandleIRQ; - - EnableIRQ(s_csiIRQ[instance]); - - /* Configure CSICR1. CSICR1 has been reset to the default value, so could write it directly. */ - reg = ((uint32_t)config->workMode) | config->polarityFlags | CSI_CSICR1_FCC_MASK; - - if (config->useExtVsync) - { - reg |= CSI_CSICR1_EXT_VSYNC_MASK; - } - - base->CSICR1 = reg; - - /* No stride. */ - base->CSIFBUF_PARA = 0; - - /* Enable auto ECC. */ - base->CSICR3 |= CSI_CSICR3_ECC_AUTO_EN_MASK; - - /* - * For better performance. - * The DMA burst size could be set to 16 * 8 byte, 8 * 8 byte, or 4 * 8 byte, - * choose the best burst size based on bytes per line. - */ - if (0U == (imgWidth_Bytes % (8U * 16U))) - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(3U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((2U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - else if (0U == (imgWidth_Bytes % (8U * 8U))) - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(2U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((1U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - else - { - base->CSICR2 = CSI_CSICR2_DMA_BURST_TYPE_RFF(1U); - base->CSICR3 = (CSI->CSICR3 & ~CSI_CSICR3_RxFF_LEVEL_MASK) | ((0U << CSI_CSICR3_RxFF_LEVEL_SHIFT)); - } - - base->CSIDMASA_FB1 = config->dmaBufferAddr0; - base->CSIDMASA_FB2 = config->dmaBufferAddr1; - - if (handle->isDmaBufferCachable) - { - DCACHE_CleanInvalidateByRange( - config->dmaBufferAddr0, - (uint32_t)config->dmaBufferLine * (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL); - DCACHE_CleanInvalidateByRange( - config->dmaBufferAddr1, - (uint32_t)config->dmaBufferLine * (uint32_t)config->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL); - } - - return kStatus_Success; -} - -/*! - * brief Start to capture a image. - * - * param base CSI peripheral base address. - * param handle Pointer to the transactional handle. - * param config Pointer to the capture configuration. - * - * retval kStatus_Success Initialize successfully. - * retval kStatus_InvalidArgument Initialize failed because of invalid argument. - */ -status_t CSI_FragModeTransferCaptureImage(CSI_Type *base, - csi_frag_handle_t *handle, - const csi_frag_capture_config_t *config) -{ - assert(NULL != config); - - uint16_t windowWidth; - - /* - * If no special window setting, capture full frame. - * If capture window, then capture 1 one each fragment. - */ - if (config->window != NULL) - { - handle->windowULX = config->window->windowULX; - handle->windowULY = config->window->windowULY; - handle->windowLRX = config->window->windowLRX; - handle->windowLRY = config->window->windowLRY; - handle->linePerFrag = 1; - } - else - { - handle->windowULX = 0; - handle->windowULY = 0; - handle->windowLRX = handle->width - 1U; - handle->windowLRY = handle->height - 1U; - handle->linePerFrag = handle->maxLinePerFrag; - } - - windowWidth = handle->windowLRX - handle->windowULX + 1U; - - if (config->outputGrayScale) - { - /* When output format is gray, the window width must be multiple value of 8. */ - if (windowWidth % 8U != 0U) - { - return kStatus_InvalidArgument; - } - - handle->datBytePerLine = windowWidth; - if (handle->inputFormat == kCSI_FragInputYUYV) - { - handle->copyFunc = CSI_ExtractYFromYUYV; - } - else - { - handle->copyFunc = CSI_ExtractYFromUYVY; - } - } - else - { - handle->datBytePerLine = windowWidth * CSI_FRAG_INPUT_BYTES_PER_PIXEL; - handle->copyFunc = CSI_MemCopy; - } - - handle->dmaCurLine = 0; - handle->outputBuffer = (uint32_t)config->buffer; - handle->datCurWriteAddr = (uint32_t)config->buffer; - - /* Image parameter. */ - base->CSIIMAG_PARA = - (((uint32_t)handle->width * CSI_FRAG_INPUT_BYTES_PER_PIXEL) << CSI_CSIIMAG_PARA_IMAGE_WIDTH_SHIFT) | - ((uint32_t)(handle->linePerFrag) << CSI_CSIIMAG_PARA_IMAGE_HEIGHT_SHIFT); - - /* - * Write to memory from first completed frame. - * DMA base addr switch at dma transfer done. - */ - base->CSICR18 = (base->CSICR18 & ~CSI_CSICR18_MASK_OPTION_MASK) | CSI_CSICR18_MASK_OPTION(0); - - CSI_EnableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable | - (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | - (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable); - - return kStatus_Success; -} - -/*! - * brief Abort image capture. - * - * Abort image capture initialized by ref CSI_FragModeTransferCaptureImage. - * - * param base CSI peripheral base address. - * param handle Pointer to the transactional handle. - */ -void CSI_FragModeTransferAbortCaptureImage(CSI_Type *base, csi_frag_handle_t *handle) -{ - CSI_Stop(base); - CSI_DisableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable | - (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | - (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable); -} - -/*! - * brief CSI IRQ handle function. - * - * This function handles the CSI IRQ request to work with CSI driver fragment mode - * APIs. - * - * param base CSI peripheral base address. - * param handle CSI handle pointer. - */ -void CSI_FragModeTransferHandleIRQ(CSI_Type *base, csi_frag_handle_t *handle) -{ - uint32_t csisr = base->CSISR; - uint32_t dmaBufAddr; - uint16_t line; - pvoid_to_u32_t memSrc; - pvoid_to_u32_t memDest; - - /* Clear the error flags. */ - base->CSISR = csisr; - - /* Start of frame, clear the FIFO and start receiving. */ - if (0U != (csisr & (uint32_t)kCSI_StartOfFrameFlag)) - { - /* Reflash the DMA and enable RX DMA request. */ - base->CSICR3 |= (CSI_CSICR3_DMA_REFLASH_RFF_MASK | CSI_CSICR3_DMA_REQ_EN_RFF_MASK); - CSI_Start(base); - handle->dmaCurLine = 0; - handle->datCurWriteAddr = handle->outputBuffer; - } - else if ((csisr & (CSI_CSISR_DMA_TSF_DONE_FB2_MASK | CSI_CSISR_DMA_TSF_DONE_FB1_MASK)) != 0U) - { - if ((csisr & CSI_CSISR_DMA_TSF_DONE_FB1_MASK) == CSI_CSISR_DMA_TSF_DONE_FB1_MASK) - { - dmaBufAddr = base->CSIDMASA_FB1; - } - else - { - dmaBufAddr = base->CSIDMASA_FB2; - } - - if (handle->isDmaBufferCachable) - { - DCACHE_InvalidateByRange(dmaBufAddr, (uint32_t)handle->dmaBytePerLine * (uint32_t)handle->linePerFrag); - } - - /* Copy from DMA buffer to user data buffer. */ - dmaBufAddr += ((uint32_t)handle->windowULX * CSI_FRAG_INPUT_BYTES_PER_PIXEL); - - for (line = 0; line < handle->linePerFrag; line++) - { - if (handle->dmaCurLine + line > handle->windowLRY) - { - /* out of window range */ - break; - } - else if (handle->dmaCurLine + line >= handle->windowULY) - { - memDest.u32 = handle->datCurWriteAddr; - memSrc.u32 = dmaBufAddr; - - handle->copyFunc(memDest.pvoid, memSrc.pvoid, handle->datBytePerLine); - handle->datCurWriteAddr += handle->datBytePerLine; - dmaBufAddr += handle->dmaBytePerLine; - } - else - { - ; /* For MISRA C-2012 Rule 15.7 */ - } - } - - handle->dmaCurLine += handle->linePerFrag; - - if (handle->dmaCurLine >= handle->height) - { - CSI_Stop(base); - CSI_DisableInterrupts(base, (uint32_t)kCSI_StartOfFrameInterruptEnable | - (uint32_t)kCSI_RxBuffer1DmaDoneInterruptEnable | - (uint32_t)kCSI_RxBuffer0DmaDoneInterruptEnable); - - /* Image captured. Stop the CSI. */ - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_CSI_FrameDone, handle->userData); - } - } - } - else - { - } -} -#endif /* CSI_DRIVER_FRAG_MODE */ - -#if defined(CSI) -void CSI_DriverIRQHandler(void) -{ - s_csiIsr(CSI, s_csiHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CSI0) -void CSI0_DriverIRQHandler(void) -{ - s_csiIsr(CSI, s_csiHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c deleted file mode 100644 index fa290939bd..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcdc.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2017-2019, NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_dcdc.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.dcdc_1" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for DCDC module. - * - * @param base DCDC peripheral base address - */ -static uint32_t DCDC_GetInstance(DCDC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to DCDC bases for each instance. */ -static DCDC_Type *const s_dcdcBases[] = DCDC_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to DCDC clocks for each instance. */ -static const clock_ip_name_t s_dcdcClocks[] = DCDC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t DCDC_GetInstance(DCDC_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_dcdcBases); instance++) - { - if (s_dcdcBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_dcdcBases)); - - return instance; -} - -/*! - * brief Enable the access to DCDC registers. - * - * param base DCDC peripheral base address. - */ -void DCDC_Init(DCDC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock. */ - CLOCK_EnableClock(s_dcdcClocks[DCDC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Disable the access to DCDC registers. - * - * param base DCDC peripheral base address. - */ -void DCDC_Deinit(DCDC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the clock. */ - CLOCK_DisableClock(s_dcdcClocks[DCDC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Configure the DCDC clock source. - * - * param base DCDC peripheral base address. - * param clockSource Clock source for DCDC. See to "dcdc_clock_source_t". - */ -void DCDC_SetClockSource(DCDC_Type *base, dcdc_clock_source_t clockSource) -{ - uint32_t tmp32; - - /* Configure the DCDC_REG0 register. */ - tmp32 = base->REG0 & ~(DCDC_REG0_XTAL_24M_OK_MASK | DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | - DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK); - switch (clockSource) - { - case kDCDC_ClockInternalOsc: - tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK; - break; - case kDCDC_ClockExternalOsc: - /* Choose the external clock and disable the internal clock. */ - tmp32 |= DCDC_REG0_DISABLE_AUTO_CLK_SWITCH_MASK | DCDC_REG0_SEL_CLK_MASK | DCDC_REG0_PWD_OSC_INT_MASK; - break; - case kDCDC_ClockAutoSwitch: - /* Set to switch from internal ring osc to xtal 24M if auto mode is enabled. */ - tmp32 |= DCDC_REG0_XTAL_24M_OK_MASK; - break; - default: - assert(false); - break; - } - base->REG0 = tmp32; -} - -/*! - * brief Get the default setting for detection configuration. - * - * The default configuration are set according to responding registers' setting when powered on. - * They are: - * code - * config->enableXtalokDetection = false; - * config->powerDownOverVoltageDetection = true; - * config->powerDownLowVlotageDetection = false; - * config->powerDownOverCurrentDetection = true; - * config->powerDownPeakCurrentDetection = true; - * config->powerDownZeroCrossDetection = true; - * config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0; - * config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0; - * endcode - * - * param config Pointer to configuration structure. See to "dcdc_detection_config_t" - */ -void DCDC_GetDefaultDetectionConfig(dcdc_detection_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableXtalokDetection = false; - config->powerDownOverVoltageDetection = true; - config->powerDownLowVlotageDetection = false; - config->powerDownOverCurrentDetection = true; - config->powerDownPeakCurrentDetection = true; - config->powerDownZeroCrossDetection = true; - config->OverCurrentThreshold = kDCDC_OverCurrentThresholdAlt0; - config->PeakCurrentThreshold = kDCDC_PeakCurrentThresholdAlt0; -} - -/*! - * breif Configure the DCDC detection. - * - * param base DCDC peripheral base address. - * param config Pointer to configuration structure. See to "dcdc_detection_config_t" - */ -void DCDC_SetDetectionConfig(DCDC_Type *base, const dcdc_detection_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - /* Configure the DCDC_REG0 register. */ - tmp32 = base->REG0 & - ~(DCDC_REG0_XTALOK_DISABLE_MASK | DCDC_REG0_PWD_HIGH_VOLT_DET_MASK | DCDC_REG0_PWD_CMP_BATT_DET_MASK | - DCDC_REG0_PWD_OVERCUR_DET_MASK | DCDC_REG0_PWD_CUR_SNS_CMP_MASK | DCDC_REG0_PWD_ZCD_MASK | - DCDC_REG0_CUR_SNS_THRSH_MASK | DCDC_REG0_OVERCUR_TRIG_ADJ_MASK); - - tmp32 |= DCDC_REG0_CUR_SNS_THRSH(config->PeakCurrentThreshold) | - DCDC_REG0_OVERCUR_TRIG_ADJ(config->OverCurrentThreshold); - if (false == config->enableXtalokDetection) - { - tmp32 |= DCDC_REG0_XTALOK_DISABLE_MASK; - } - if (config->powerDownOverVoltageDetection) - { - tmp32 |= DCDC_REG0_PWD_HIGH_VOLT_DET_MASK; - } - if (config->powerDownLowVlotageDetection) - { - tmp32 |= DCDC_REG0_PWD_CMP_BATT_DET_MASK; - } - if (config->powerDownOverCurrentDetection) - { - tmp32 |= DCDC_REG0_PWD_OVERCUR_DET_MASK; - } - if (config->powerDownPeakCurrentDetection) - { - tmp32 |= DCDC_REG0_PWD_CUR_SNS_CMP_MASK; - } - if (config->powerDownZeroCrossDetection) - { - tmp32 |= DCDC_REG0_PWD_ZCD_MASK; - } - base->REG0 = tmp32; -} - -/*! - * brief Get the default setting for low power configuration. - * - * The default configuration are set according to responding registers' setting when powered on. - * They are: - * code - * config->enableOverloadDetection = true; - * config->enableAdjustHystereticValue = false; - * config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle; - * config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32; - * endcode - * - * param config Pointer to configuration structure. See to "dcdc_low_power_config_t" - */ -void DCDC_GetDefaultLowPowerConfig(dcdc_low_power_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableOverloadDetection = true; - config->enableAdjustHystereticValue = false; - config->countChargingTimePeriod = kDCDC_CountChargingTimePeriod8Cycle; - config->countChargingTimeThreshold = kDCDC_CountChargingTimeThreshold32; -} - -/*! - * brief Configure the DCDC low power. - * - * param base DCDC peripheral base address. - * param config Pointer to configuration structure. See to "dcdc_low_power_config_t". - */ -void DCDC_SetLowPowerConfig(DCDC_Type *base, const dcdc_low_power_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - /* Configure the DCDC_REG0 register. */ - tmp32 = base->REG0 & ~(DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK | DCDC_REG0_LP_HIGH_HYS_MASK | - DCDC_REG0_LP_OVERLOAD_FREQ_SEL_MASK | DCDC_REG0_LP_OVERLOAD_THRSH_MASK); - tmp32 |= DCDC_REG0_LP_OVERLOAD_FREQ_SEL(config->countChargingTimePeriod) | - DCDC_REG0_LP_OVERLOAD_THRSH(config->countChargingTimeThreshold); - if (config->enableOverloadDetection) - { - tmp32 |= DCDC_REG0_EN_LP_OVERLOAD_SNS_MASK; - } - if (config->enableAdjustHystereticValue) - { - tmp32 |= DCDC_REG0_LP_HIGH_HYS_MASK; - } - base->REG0 = tmp32; -} - -/*! - * brief Get DCDC status flags. - * - * param base peripheral base address. - * return Mask of asserted status flags. See to "_dcdc_status_flags_t". - */ -uint32_t DCDC_GetstatusFlags(DCDC_Type *base) -{ - uint32_t tmp32 = 0U; - - if (DCDC_REG0_STS_DC_OK_MASK == (DCDC_REG0_STS_DC_OK_MASK & base->REG0)) - { - tmp32 |= (uint32_t)kDCDC_LockedOKStatus; - } - - return tmp32; -} - -/*! - * brief Reset current alert signal. Alert signal is generate by peak current detection. - * - * param base DCDC peripheral base address. - * param enable Switcher to reset signal. True means reset signal. False means don't reset signal. - */ -void DCDC_ResetCurrentAlertSignal(DCDC_Type *base, bool enable) -{ - if (enable) - { - base->REG0 |= DCDC_REG0_CURRENT_ALERT_RESET_MASK; - } - else - { - base->REG0 &= ~DCDC_REG0_CURRENT_ALERT_RESET_MASK; - } -} - -/*! - * brief Get the default setting for loop control configuration. - * - * The default configuration are set according to responding registers' setting when powered on. - * They are: - * code - * config->enableCommonHysteresis = false; - * config->enableCommonThresholdDetection = false; - * config->enableInvertHysteresisSign = false; - * config->enableRCThresholdDetection = false; - * config->enableRCScaleCircuit = 0U; - * config->complementFeedForwardStep = 0U; - * config->controlParameterMagnitude = 2U; - * config->integralProportionalRatio = 2U; - * endcode - * - * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t" - */ -void DCDC_GetDefaultLoopControlConfig(dcdc_loop_control_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableCommonHysteresis = false; - config->enableCommonThresholdDetection = false; - config->enableInvertHysteresisSign = false; - config->enableRCThresholdDetection = false; - config->enableRCScaleCircuit = 0U; - config->complementFeedForwardStep = 0U; - config->controlParameterMagnitude = 2U; - config->integralProportionalRatio = 2U; -} - -/*! - * brief Configure the DCDC loop control. - * - * param base DCDC peripheral base address. - * param config Pointer to configuration structure. See to "dcdc_loop_control_config_t". - */ -void DCDC_SetLoopControlConfig(DCDC_Type *base, const dcdc_loop_control_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - - /* Configure the DCDC_REG1 register. */ - tmp32 = base->REG1 & ~(DCDC_REG1_LOOPCTRL_EN_HYST_MASK | DCDC_REG1_LOOPCTRL_HST_THRESH_MASK); - if (config->enableCommonHysteresis) - { - tmp32 |= DCDC_REG1_LOOPCTRL_EN_HYST_MASK; - } - if (config->enableCommonThresholdDetection) - { - tmp32 |= DCDC_REG1_LOOPCTRL_HST_THRESH_MASK; - } - base->REG1 = tmp32; - - /* configure the DCDC_REG2 register. */ - tmp32 = base->REG2 & ~(DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK | DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK | - DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK | DCDC_REG2_LOOPCTRL_DC_FF_MASK | - DCDC_REG2_LOOPCTRL_DC_R_MASK | DCDC_REG2_LOOPCTRL_DC_C_MASK); - tmp32 |= DCDC_REG2_LOOPCTRL_DC_FF(config->complementFeedForwardStep) | - DCDC_REG2_LOOPCTRL_DC_R(config->controlParameterMagnitude) | - DCDC_REG2_LOOPCTRL_DC_C(config->integralProportionalRatio) | - DCDC_REG2_LOOPCTRL_EN_RCSCALE(config->enableRCScaleCircuit); - if (config->enableInvertHysteresisSign) - { - tmp32 |= DCDC_REG2_LOOPCTRL_HYST_SIGN_MASK; - } - if (config->enableRCThresholdDetection) - { - tmp32 |= DCDC_REG2_LOOPCTRL_RCSCALE_THRSH_MASK; - } - base->REG2 = tmp32; -} - -/*! - * brief Configure for the min power. - * - * param base DCDC peripheral base address. - * param config Pointer to configuration structure. See to "dcdc_min_power_config_t". - */ -void DCDC_SetMinPowerConfig(DCDC_Type *base, const dcdc_min_power_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - - tmp32 = base->REG3 & ~DCDC_REG3_MINPWR_DC_HALFCLK_MASK; - if (config->enableUseHalfFreqForContinuous) - { - tmp32 |= DCDC_REG3_MINPWR_DC_HALFCLK_MASK; - } - base->REG3 = tmp32; -} - -/*! - * brief Adjust the target voltage of VDD_SOC in run mode and low power mode. - * @deprecated Do not use this function. It has been superceded by @ref DCDC_AdjustRunTargetVoltage - * and @ref DCDC_AdjustLowPowerTargetVoltage - * - * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is - * stabled. - * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch - * back to run mode if it detects the current loading is larger than about 50 mA(typical value). - * - * param base DCDC peripheral base address. - * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V. - * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V. - */ -void DCDC_AdjustTargetVoltage(DCDC_Type *base, uint32_t VDDRun, uint32_t VDDStandby) -{ - uint32_t tmp32; - - /* Unlock the step for the output. */ - base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK; - - /* Configure the DCDC_REG3 register. */ - tmp32 = base->REG3 & ~(DCDC_REG3_TARGET_LP_MASK | DCDC_REG3_TRG_MASK); - - tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby) | DCDC_REG3_TRG(VDDRun); - base->REG3 = tmp32; - - /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new - * target value, DCDC_STS_DC_OK will be asserted. */ - while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0)) - { - } -} - -/*! - * brief Adjust the target voltage of VDD_SOC in run mode. - * - * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is - * stabled. - * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch - * back to run mode if it detects the current loading is larger than about 50 mA(typical value). - * - * param base DCDC peripheral base address. - * param VDDRun Target value in run mode. 25 mV each step from 0x00 to 0x1F. 00 is for 0.8V, 0x1F is for 1.575V. - */ -void DCDC_AdjustRunTargetVoltage(DCDC_Type *base, uint32_t VDDRun) -{ - uint32_t tmp32; - - /* Unlock the step for the output. */ - base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK; - - /* Configure the DCDC_REG3 register. */ - tmp32 = base->REG3 & ~DCDC_REG3_TRG_MASK; - - tmp32 |= DCDC_REG3_TRG(VDDRun); - base->REG3 = tmp32; - - /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new - * target value, DCDC_STS_DC_OK will be asserted. */ - while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0)) - { - } -} - -/*! - * brief Adjust the target voltage of VDD_SOC in low power mode. - * - * This function is to adjust the target voltage of DCDC output. Change them and finally wait until the output is - * stabled. - * Set the target value of run mode the same as low power mode before entering power save mode, because DCDC will switch - * back to run mode if it detects the current loading is larger than about 50 mA(typical value). - * - * param base DCDC peripheral base address. - * param VDDStandby Target value in low power mode. 25 mV each step from 0x00 to 0x4. 00 is for 0.9V, 0x4 is for 1.0V. - */ -void DCDC_AdjustLowPowerTargetVoltage(DCDC_Type *base, uint32_t VDDStandby) -{ - uint32_t tmp32; - - /* Unlock the step for the output. */ - base->REG3 &= ~DCDC_REG3_DISABLE_STEP_MASK; - - /* Configure the DCDC_REG3 register. */ - tmp32 = base->REG3 & ~DCDC_REG3_TARGET_LP_MASK; - - tmp32 |= DCDC_REG3_TARGET_LP(VDDStandby); - base->REG3 = tmp32; - - /* DCDC_STS_DC_OK bit will be de-asserted after target register changes. After output voltage settling to new - * target value, DCDC_STS_DC_OK will be asserted. */ - while (DCDC_REG0_STS_DC_OK_MASK != (DCDC_REG0_STS_DC_OK_MASK & base->REG0)) - { - } -} - -/*! - * brief Configure the DCDC internal regulator. - * - * param base DCDC peripheral base address. - * param config Pointer to configuration structure. See to "dcdc_internal_regulator_config_t". - */ -void DCDC_SetInternalRegulatorConfig(DCDC_Type *base, const dcdc_internal_regulator_config_t *config) -{ - assert(NULL != config); - - uint32_t tmp32; - - /* Configure the DCDC_REG1 register. */ - tmp32 = base->REG1 & ~(DCDC_REG1_REG_FBK_SEL_MASK | DCDC_REG1_REG_RLOAD_SW_MASK); - tmp32 |= DCDC_REG1_REG_FBK_SEL(config->feedbackPoint); - if (config->enableLoadResistor) - { - tmp32 |= DCDC_REG1_REG_RLOAD_SW_MASK; - } - base->REG1 = tmp32; -} - -/*! - * brief Boot DCDC into DCM(discontinous conduction mode). - * - * pwd_zcd=0x0; - * pwd_cmp_offset=0x0; - * dcdc_loopctrl_en_rcscale=0x3 or 0x5; - * DCM_set_ctrl=1'b1; - * - * param base DCDC peripheral base address. - */ -void DCDC_BootIntoDCM(DCDC_Type *base) -{ - base->REG0 &= ~(DCDC_REG0_PWD_ZCD_MASK | DCDC_REG0_PWD_CMP_OFFSET_MASK); - base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x4U) | - DCDC_REG2_DCM_SET_CTRL_MASK; -} - -/*! - * brief Boot DCDC into CCM(continous conduction mode). - * - * pwd_zcd=0x1; - * pwd_cmp_offset=0x0; - * dcdc_loopctrl_en_rcscale=0x3; - * - * param base DCDC peripheral base address. - */ -void DCDC_BootIntoCCM(DCDC_Type *base) -{ - base->REG0 = (~DCDC_REG0_PWD_CMP_OFFSET_MASK & base->REG0) | DCDC_REG0_PWD_ZCD_MASK; - base->REG2 = (~DCDC_REG2_LOOPCTRL_EN_RCSCALE_MASK & base->REG2) | DCDC_REG2_LOOPCTRL_EN_RCSCALE(0x3U); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c deleted file mode 100644 index fff5e6fe35..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dcp.c +++ /dev/null @@ -1,1465 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_dcp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.dcp" -#endif - -#ifndef DCP_USE_DCACHE -#define DCP_USE_DCACHE 0 -#endif -/* 1 - driver supports DCACHE, 0 - drivers does not support DCACHE */ -/* When enable (DCP_USE_DCACHE = 1) Input/output buffers and hash ctx should be in */ -/* non-cached memory or handled properly (Clean & Invalidate DCACHE) */ - -/*! Compile time sizeof() check */ -#define BUILD_ASSURE(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused)) - -#define dcp_memcpy memcpy - -/*! Internal states of the HASH creation process */ -typedef enum _dcp_hash_algo_state -{ - kDCP_StateHashInit = 1u, /*!< Init state. */ - kDCP_StateHashUpdate, /*!< Update state. */ -} dcp_hash_algo_state_t; - -/*! multiple of 64-byte block represented as byte array of 32-bit words */ -typedef union _dcp_hash_block -{ - uint32_t w[DCP_HASH_BLOCK_SIZE / 4]; /*!< array of 32-bit words */ - uint8_t b[DCP_HASH_BLOCK_SIZE]; /*!< byte array */ -} dcp_hash_block_t; - -/*! internal dcp_hash context structure */ -typedef struct _dcp_hash_ctx_internal -{ - dcp_hash_block_t blk; /*!< memory buffer. only full blocks are written to DCP during hash updates */ - size_t blksz; /*!< number of valid bytes in memory buffer */ - dcp_hash_algo_t algo; /*!< selected algorithm from the set of supported algorithms */ - dcp_hash_algo_state_t state; /*!< finite machine state of the hash software process */ - uint32_t fullMessageSize; /*!< track message size */ - uint32_t ctrl0; /*!< HASH_INIT and HASH_TERM flags */ - uint32_t runningHash[9]; /*!< running hash. up to SHA-256 plus size, that is 36 bytes. */ - dcp_handle_t *handle; -} dcp_hash_ctx_internal_t; - -/*!< SHA-1/SHA-2 digest length in bytes */ -enum _dcp_hash_digest_len -{ - kDCP_OutLenSha1 = 20u, - kDCP_OutLenSha256 = 32u, - kDCP_OutLenCrc32 = 4u, -}; - -enum _dcp_work_packet_bit_definitions -{ - kDCP_CONTROL0_DECR_SEMAPHOR = 1u << 1, /* DECR_SEMAPHOR */ - kDCP_CONTROL0_ENABLE_HASH = 1u << 6, /* ENABLE_HASH */ - kDCP_CONTROL0_HASH_INIT = 1u << 12, /* HASH_INIT */ - kDCP_CONTROL0_HASH_TERM = 1u << 13, /* HASH_TERM */ - kDCP_CONTROL1_HASH_SELECT_SHA256 = 2u << 16, - kDCP_CONTROL1_HASH_SELECT_SHA1 = 0u << 16, - kDCP_CONTROL1_HASH_SELECT_CRC32 = 1u << 16, -}; - -/*! 64-byte block represented as byte array of 16 32-bit words */ -typedef union _dcp_sha_block -{ - uint32_t w[64 / 4]; /*!< array of 32-bit words */ - uint8_t b[64]; /*!< byte array */ -} dcp_sha_block_t; - -#if defined(DCP_HASH_CAVP_COMPATIBLE) -/* result of sha1 hash for message with zero size */ -static uint8_t s_nullSha1[] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, - 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09}; -/* result of sha256 hash for message with zero size */ -static uint8_t s_nullSha256[] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, - 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, - 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}; -#endif /* DCP_HASH_CAVP_COMPATIBLE */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -AT_NONCACHEABLE_SECTION_INIT(static dcp_context_t s_dcpContextSwitchingBuffer); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void dcp_reverse_and_copy(uint8_t *src, uint8_t *dest, size_t src_len) -{ - for (uint32_t i = 0; i < src_len; i++) - { - dest[i] = src[src_len - 1U - i]; - } -} - -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) -static uint32_t *DCP_FindCacheLine(uint8_t *dcpWorkExt) -{ - while ((uint32_t)dcpWorkExt & (FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1)) - dcpWorkExt++; - return (uint32_t *)dcpWorkExt; -} -#endif - -static status_t dcp_get_channel_status(DCP_Type *base, dcp_channel_t channel) -{ - uint32_t statReg = 0; - uint32_t semaReg = 0; - status_t status = kStatus_Fail; - - switch (channel) - { - case kDCP_Channel0: - statReg = base->CH0STAT; - semaReg = base->CH0SEMA; - break; - - case kDCP_Channel1: - statReg = base->CH1STAT; - semaReg = base->CH1SEMA; - break; - - case kDCP_Channel2: - statReg = base->CH2STAT; - semaReg = base->CH2SEMA; - break; - - case kDCP_Channel3: - statReg = base->CH3STAT; - semaReg = base->CH3SEMA; - break; - - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - - if (!((0U != (semaReg & DCP_CH0SEMA_VALUE_MASK)) || (0U != (statReg & DCP_CH0STAT_ERROR_CODE_MASK)))) - { - status = kStatus_Success; - } - - return status; -} - -static void dcp_clear_status(DCP_Type *base) -{ - volatile uint32_t *dcpStatClrPtr = (volatile uint32_t *)&base->STAT + 2u; - *dcpStatClrPtr = 0xFFu; - - while ((base->STAT & 0xffu) != 0U) - { - } -} - -static void dcp_clear_channel_status(DCP_Type *base, uint32_t mask) -{ - volatile uint32_t *chStatClrPtr; - - if (0U != (mask & (uint32_t)kDCP_Channel0)) - { - chStatClrPtr = &base->CH0STAT_CLR; - *chStatClrPtr = 0xFFu; - } - if (0U != (mask & (uint32_t)kDCP_Channel1)) - { - chStatClrPtr = &base->CH1STAT_CLR; - *chStatClrPtr = 0xFFu; - } - if (0U != (mask & (uint32_t)kDCP_Channel2)) - { - chStatClrPtr = &base->CH2STAT_CLR; - *chStatClrPtr = 0xFFu; - } - if (0U != (mask & (uint32_t)kDCP_Channel3)) - { - chStatClrPtr = &base->CH3STAT_CLR; - *chStatClrPtr = 0xFFu; - } -} - -static status_t dcp_aes_set_sram_based_key(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key) -{ - base->KEY = DCP_KEY_INDEX(handle->keySlot) | DCP_KEY_SUBWORD(0); - /* move the key by 32-bit words */ - int i = 0; - size_t keySize = 16u; - while (keySize != 0U) - { - keySize -= sizeof(uint32_t); - base->KEYDATA = ((uint32_t *)(uintptr_t)key)[i]; - i++; - } - return kStatus_Success; -} - -/* Disable optimizations for GCC to prevent instruction reordering */ -#if defined(__GNUC__) -#pragma GCC push_options -#pragma GCC optimize("O0") -#endif -static status_t dcp_schedule_work(DCP_Type *base, dcp_handle_t *handle, dcp_work_packet_t *dcpPacket) -{ - status_t status; - - /* check if our channel is active */ - if ((base->STAT & (uint32_t)handle->channel) != (uint32_t)handle->channel) - { - /* disable global interrupt */ - uint32_t currPriMask = DisableGlobalIRQ(); - - /* re-check if our channel is still available */ - if ((base->STAT & (uint32_t)handle->channel) == 0U) - { - volatile uint32_t *cmdptr = NULL; - volatile uint32_t *chsema = NULL; - - switch (handle->channel) - { - case kDCP_Channel0: - cmdptr = &base->CH0CMDPTR; - chsema = &base->CH0SEMA; - break; - - case kDCP_Channel1: - cmdptr = &base->CH1CMDPTR; - chsema = &base->CH1SEMA; - break; - - case kDCP_Channel2: - cmdptr = &base->CH2CMDPTR; - chsema = &base->CH2SEMA; - break; - - case kDCP_Channel3: - cmdptr = &base->CH3CMDPTR; - chsema = &base->CH3SEMA; - break; - - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - - if ((NULL != cmdptr) && (NULL != chsema)) - { - /* set out packet to DCP CMDPTR */ - *cmdptr = (uint32_t)dcpPacket; - -#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - /* Clean DCACHE before sending DCP packet to engine */ - SCB_CleanDCache_by_Addr((uint32_t *)dcpPacket, sizeof(dcp_work_packet_t)); -#endif - /* Make sure that all data memory accesses are completed before starting of the job */ - __DSB(); - __ISB(); - - /* set the channel semaphore to start the job */ - *chsema = 1u; - } - - status = kStatus_Success; - } - - else - { - status = (int32_t)kStatus_DCP_Again; - } - /* global interrupt enable */ - EnableGlobalIRQ(currPriMask); - } - - else - { - return (int32_t)kStatus_DCP_Again; - } - - return status; -} -#if defined(__GNUC__) -#pragma GCC pop_options -#endif - -/*! - * brief Set AES key to dcp_handle_t struct and optionally to DCP. - * - * Sets the AES key for encryption/decryption with the dcp_handle_t structure. - * The dcp_handle_t input argument specifies keySlot. - * If the keySlot is kDCP_OtpKey, the function will check the OTP_KEY_READY bit and will return it's ready to use - * status. - * For other keySlot selections, the function will copy and hold the key in dcp_handle_t struct. - * If the keySlot is one of the four DCP SRAM-based keys (one of kDCP_KeySlot0, kDCP_KeySlot1, kDCP_KeySlot2, - * kDCP_KeySlot3), - * this function will also load the supplied key to the specified keySlot in DCP. - * - * param base DCP peripheral base address. - * param handle Handle used for the request. - * param key 0-mod-4 aligned pointer to AES key. - * param keySize AES key size in bytes. Shall equal 16. - * return status from set key operation - */ -status_t DCP_AES_SetKey(DCP_Type *base, dcp_handle_t *handle, const uint8_t *key, size_t keySize) -{ - status_t status = kStatus_Fail; - - if ((kDCP_OtpKey == handle->keySlot) || (kDCP_OtpUniqueKey == handle->keySlot)) - { - /* for AES OTP and unique key, check and return read from fuses status */ - if ((base->STAT & DCP_STAT_OTP_KEY_READY_MASK) == DCP_STAT_OTP_KEY_READY_MASK) - { - status = kStatus_Success; - } - } - else - { - /* only work with aligned key[] */ - if ((0x3U & (uintptr_t)key) != 0U) - { - return kStatus_InvalidArgument; - } - - /* keySize must be 16. */ - if (keySize != 16U) - { - return kStatus_InvalidArgument; - } - - /* move the key by 32-bit words */ - int i = 0; - while (keySize != 0U) - { - keySize -= sizeof(uint32_t); - handle->keyWord[i] = ((uint32_t *)(uintptr_t)key)[i]; - i++; - } - - if (kDCP_PayloadKey != handle->keySlot) - { - /* move the key by 32-bit words to DCP SRAM-based key storage */ - status = dcp_aes_set_sram_based_key(base, handle, key); - } - else - { - /* for PAYLOAD_KEY, just return Ok status now */ - status = kStatus_Success; - } - } - - return status; -} - -/*! - * brief Encrypts AES on one or multiple 128-bit block(s). - * - * Encrypts AES. - * The source plaintext and destination ciphertext can overlap in system memory. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param plaintext Input plain text to encrypt - * param[out] ciphertext Output cipher text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * return Status from encrypt operation - */ -status_t DCP_AES_EncryptEcb( - DCP_Type *base, dcp_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size) -{ - status_t completionStatus = kStatus_Fail; - - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_work_packet_t *dcpWork; - uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt); -#else - dcp_work_packet_t dcpWorkPacket = {0}; - dcp_work_packet_t *dcpWork = &dcpWorkPacket; -#endif - - do - { - completionStatus = DCP_AES_EncryptEcbNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size); - } while (completionStatus == (int32_t)kStatus_DCP_Again); - - if (completionStatus != kStatus_Success) - { - return completionStatus; - } - - return DCP_WaitForChannelComplete(base, handle); -} - -/*! - * brief Encrypts AES using the ECB block mode. - * - * Puts AES ECB encrypt work packet to DCP channel. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param[out] dcpPacket Memory for the DCP work packet. - * param plaintext Input plain text to encrypt. - * param[out] ciphertext Output cipher text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * return kStatus_Success The work packet has been scheduled at DCP channel. - * return kStatus_DCP_Again The DCP channel is busy processing previous request. - */ -status_t DCP_AES_EncryptEcbNonBlocking(DCP_Type *base, - dcp_handle_t *handle, - dcp_work_packet_t *dcpPacket, - const uint8_t *plaintext, - uint8_t *ciphertext, - size_t size) -{ - /* Size must be 16-byte multiple */ - if ((size < 16u) || (0U != (size % 16u))) - { - return kStatus_InvalidArgument; - } - - dcpPacket->control0 = - 0x122u | (handle->swapConfig & 0xFC0000u); /* CIPHER_ENCRYPT | ENABLE_CIPHER | DECR_SEMAPHORE */ - dcpPacket->sourceBufferAddress = (uint32_t)plaintext; - dcpPacket->destinationBufferAddress = (uint32_t)ciphertext; - dcpPacket->bufferSize = (uint32_t)size; - - if (handle->keySlot == kDCP_OtpKey) - { - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 = ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */ - } - else if (handle->keySlot == kDCP_OtpUniqueKey) - { - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 = ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */ - } - else if (handle->keySlot == kDCP_PayloadKey) - { - /* ECB does not have IV, so we can point payload directly to keyWord[] stored in handle. */ - dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0]; - dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */ - } - else - { - dcpPacket->control1 = ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */ - } - - return dcp_schedule_work(base, handle, dcpPacket); -} - -/*! - * brief Decrypts AES on one or multiple 128-bit block(s). - * - * Decrypts AES. - * The source ciphertext and destination plaintext can overlap in system memory. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param ciphertext Input plain text to encrypt - * param[out] plaintext Output cipher text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * return Status from decrypt operation - */ -status_t DCP_AES_DecryptEcb( - DCP_Type *base, dcp_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size) -{ - status_t completionStatus = kStatus_Fail; - - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_work_packet_t *dcpWork; - uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt); -#else - dcp_work_packet_t dcpWorkPacket = {0}; - dcp_work_packet_t *dcpWork = &dcpWorkPacket; -#endif - - do - { - completionStatus = DCP_AES_DecryptEcbNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size); - } while (completionStatus == (int32_t)(kStatus_DCP_Again)); - - if (completionStatus != kStatus_Success) - { - return completionStatus; - } - - return DCP_WaitForChannelComplete(base, handle); -} - -/*! - * brief Decrypts AES using ECB block mode. - * - * Puts AES ECB decrypt dcpPacket to DCP input job ring. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param[out] dcpPacket Memory for the DCP work packet. - * param ciphertext Input cipher text to decrypt - * param[out] plaintext Output plain text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * return kStatus_Success The work packet has been scheduled at DCP channel. - * return kStatus_DCP_Again The DCP channel is busy processing previous request. - */ -status_t DCP_AES_DecryptEcbNonBlocking(DCP_Type *base, - dcp_handle_t *handle, - dcp_work_packet_t *dcpPacket, - const uint8_t *ciphertext, - uint8_t *plaintext, - size_t size) -{ - /* Size must be 16-byte multiple */ - if ((size < 16u) || (0U != (size % 16u))) - { - return kStatus_InvalidArgument; - } - - dcpPacket->control0 = 0x22u | (handle->swapConfig & 0xFC0000u); /* ENABLE_CIPHER | DECR_SEMAPHORE */ - dcpPacket->sourceBufferAddress = (uint32_t)ciphertext; - dcpPacket->destinationBufferAddress = (uint32_t)plaintext; - dcpPacket->bufferSize = (uint32_t)size; - - if (handle->keySlot == kDCP_OtpKey) - { - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 = ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */ - } - else if (handle->keySlot == kDCP_OtpUniqueKey) - { - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 = ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */ - } - else if (handle->keySlot == kDCP_PayloadKey) - { - /* ECB does not have IV, so we can point payload directly to keyWord[] stored in handle. */ - dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0]; - dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */ - } - else - { - dcpPacket->control1 = ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */ - } - - return dcp_schedule_work(base, handle, dcpPacket); -} - -/*! - * brief Encrypts AES using CBC block mode. - * - * Encrypts AES using CBC block mode. - * The source plaintext and destination ciphertext can overlap in system memory. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param plaintext Input plain text to encrypt - * param[out] ciphertext Output cipher text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * param iv Input initial vector to combine with the first input block. - * return Status from encrypt operation - */ -status_t DCP_AES_EncryptCbc(DCP_Type *base, - dcp_handle_t *handle, - const uint8_t *plaintext, - uint8_t *ciphertext, - size_t size, - const uint8_t iv[16]) -{ - status_t completionStatus = kStatus_Fail; - - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_work_packet_t *dcpWork; - uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt); -#else - dcp_work_packet_t dcpWorkPacket = {0}; - dcp_work_packet_t *dcpWork = &dcpWorkPacket; -#endif - - do - { - completionStatus = DCP_AES_EncryptCbcNonBlocking(base, handle, dcpWork, plaintext, ciphertext, size, iv); - } while (completionStatus == (int32_t)kStatus_DCP_Again); - - if (completionStatus != kStatus_Success) - { - return completionStatus; - } - - return DCP_WaitForChannelComplete(base, handle); -} - -/*! - * brief Encrypts AES using CBC block mode. - * - * Puts AES CBC encrypt dcpPacket to DCP input job ring. - * - * param base DCP peripheral base address - * param handle Handle used for this request. Specifies jobRing. - * param[out] dcpPacket Memory for the DCP work packet. - * param plaintext Input plain text to encrypt - * param[out] ciphertext Output cipher text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * param iv Input initial vector to combine with the first input block. - * return kStatus_Success The work packet has been scheduled at DCP channel. - * return kStatus_DCP_Again The DCP channel is busy processing previous request. - */ -status_t DCP_AES_EncryptCbcNonBlocking(DCP_Type *base, - dcp_handle_t *handle, - dcp_work_packet_t *dcpPacket, - const uint8_t *plaintext, - uint8_t *ciphertext, - size_t size, - const uint8_t *iv) -{ - /* Size must be 16-byte multiple */ - if ((size < 16u) || (0U != (size % 16u))) - { - return kStatus_InvalidArgument; - } - - dcpPacket->control0 = - 0x322u | (handle->swapConfig & 0xFC0000u); /* CIPHER_INIT | CIPHER_ENCRYPT | ENABLE_CIPHER | DECR_SEMAPHORE */ - dcpPacket->control1 = 0x10u; /* CBC */ - dcpPacket->sourceBufferAddress = (uint32_t)plaintext; - dcpPacket->destinationBufferAddress = (uint32_t)ciphertext; - dcpPacket->bufferSize = (uint32_t)size; - - if (handle->keySlot == kDCP_OtpKey) - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 |= ((uint32_t)0xFFu << 8); /* KEY_SELECT = OTP_KEY */ - } - else if (handle->keySlot == kDCP_OtpUniqueKey) - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 |= ((uint32_t)0xFEu << 8); /* KEY_SELECT = UNIQUE_KEY */ - } - else if (handle->keySlot == kDCP_PayloadKey) - { - /* In this case payload must contain key & iv in one array. */ - /* Copy iv into handle right behind the keyWord[] so we can point payload to keyWord[]. */ - (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16); - dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0]; - dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */ - } - else - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8); /* KEY_SELECT = keySlot */ - } - - return dcp_schedule_work(base, handle, dcpPacket); -} - -/*! - * brief Decrypts AES using CBC block mode. - * - * Decrypts AES using CBC block mode. - * The source ciphertext and destination plaintext can overlap in system memory. - * - * param base DCP peripheral base address - * param handle Handle used for this request. - * param ciphertext Input cipher text to decrypt - * param[out] plaintext Output plain text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * param iv Input initial vector to combine with the first input block. - * return Status from decrypt operation - */ -status_t DCP_AES_DecryptCbc(DCP_Type *base, - dcp_handle_t *handle, - const uint8_t *ciphertext, - uint8_t *plaintext, - size_t size, - const uint8_t iv[16]) -{ - status_t completionStatus = kStatus_Fail; - - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_work_packet_t *dcpWork; - uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt); -#else - dcp_work_packet_t dcpWorkPacket = {0}; - dcp_work_packet_t *dcpWork = &dcpWorkPacket; -#endif - - do - { - completionStatus = DCP_AES_DecryptCbcNonBlocking(base, handle, dcpWork, ciphertext, plaintext, size, iv); - } while (completionStatus == (int32_t)kStatus_DCP_Again); - - if (completionStatus != (int32_t)kStatus_Success) - { - return completionStatus; - } - - return DCP_WaitForChannelComplete(base, handle); -} - -/*! - * brief Decrypts AES using CBC block mode. - * - * Puts AES CBC decrypt dcpPacket to DCP input job ring. - * - * param base DCP peripheral base address - * param handle Handle used for this request. Specifies jobRing. - * param[out] dcpPacket Memory for the DCP work packet. - * param ciphertext Input cipher text to decrypt - * param[out] plaintext Output plain text - * param size Size of input and output data in bytes. Must be multiple of 16 bytes. - * param iv Input initial vector to combine with the first input block. - * return kStatus_Success The work packet has been scheduled at DCP channel. - * return kStatus_DCP_Again The DCP channel is busy processing previous request. - */ -status_t DCP_AES_DecryptCbcNonBlocking(DCP_Type *base, - dcp_handle_t *handle, - dcp_work_packet_t *dcpPacket, - const uint8_t *ciphertext, - uint8_t *plaintext, - size_t size, - const uint8_t *iv) -{ - /* Size must be 16-byte multiple */ - if ((size < 16u) || (0U != (size % 16u))) - { - return kStatus_InvalidArgument; - } - - dcpPacket->control0 = 0x222u | (handle->swapConfig & 0xFC0000u); /* CIPHER_INIT | ENABLE_CIPHER | DECR_SEMAPHORE */ - dcpPacket->control1 = 0x10u; /* CBC */ - dcpPacket->sourceBufferAddress = (uint32_t)ciphertext; - dcpPacket->destinationBufferAddress = (uint32_t)plaintext; - dcpPacket->bufferSize = (uint32_t)size; - - if (handle->keySlot == kDCP_OtpKey) - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 |= ((uint32_t)0xFFu << 8); /* OTP_KEY */ - } - else if (handle->keySlot == kDCP_OtpUniqueKey) - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control0 |= ((uint32_t)1u << 10); /* OTP_KEY */ - dcpPacket->control1 |= ((uint32_t)0xFEu << 8); /* UNIQUE_KEY */ - } - else if (handle->keySlot == kDCP_PayloadKey) - { - /* in this case payload must contain KEY + IV together */ - /* copy iv into handle struct so we can point payload directly to keyWord[]. */ - (void)dcp_memcpy(handle->iv, (const uint32_t *)(uintptr_t)iv, 16); - dcpPacket->payloadPointer = (uint32_t)&handle->keyWord[0]; - dcpPacket->control0 |= ((uint32_t)1u << 11); /* PAYLOAD_KEY */ - } - else - { - dcpPacket->payloadPointer = (uint32_t)iv; - dcpPacket->control1 |= ((uint32_t)handle->keySlot << 8); /* KEY_SELECT */ - } - - return dcp_schedule_work(base, handle, dcpPacket); -} - -/*! - * brief Gets the default configuration structure. - * - * This function initializes the DCP configuration structure to a default value. The default - * values are as follows. - * dcpConfig->gatherResidualWrites = true; - * dcpConfig->enableContextCaching = true; - * dcpConfig->enableContextSwitching = true; - * dcpConfig->enableChannnel = kDCP_chEnableAll; - * dcpConfig->enableChannelInterrupt = kDCP_chIntDisable; - * - * param[out] config Pointer to configuration structure. - */ -void DCP_GetDefaultConfig(dcp_config_t *config) -{ - /* ENABLE_CONTEXT_CACHING is disabled by default as the DCP Hash driver uses - * dcp_hash_save_running_hash() and dcp_hash_restore_running_hash() to support - * Hash context switch (different messages interleaved) on the same channel. - */ - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - dcp_config_t userConfig = { - true, false, true, (uint8_t)kDCP_chEnableAll, (uint8_t)kDCP_chIntDisable, - }; - - *config = userConfig; -} - -/*! - * brief Enables clock to and enables DCP - * - * Enable DCP clock and configure DCP. - * - * param base DCP base address - * param config Pointer to configuration structure. - */ -void DCP_Init(DCP_Type *base, const dcp_config_t *config) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_EnableClock(kCLOCK_Dcp); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - base->CTRL = 0xF0800000u; /* reset value */ - base->CTRL = 0x30800000u; /* default value */ - - dcp_clear_status(base); - dcp_clear_channel_status( - base, (uint32_t)kDCP_Channel0 | (uint32_t)kDCP_Channel1 | (uint32_t)kDCP_Channel2 | (uint32_t)kDCP_Channel3); - - base->CTRL = DCP_CTRL_GATHER_RESIDUAL_WRITES(config->gatherResidualWrites) | - DCP_CTRL_ENABLE_CONTEXT_CACHING(config->enableContextCaching) | - DCP_CTRL_ENABLE_CONTEXT_SWITCHING(config->enableContextSwitching) | - DCP_CTRL_CHANNEL_INTERRUPT_ENABLE(config->enableChannelInterrupt); - - /* enable DCP channels */ - base->CHANNELCTRL = DCP_CHANNELCTRL_ENABLE_CHANNEL(config->enableChannel); - - /* use context switching buffer */ - base->CONTEXT = (uint32_t)&s_dcpContextSwitchingBuffer; -} - -/*! - * brief Disable DCP clock - * - * Reset DCP and Disable DCP clock. - * - * param base DCP base address - */ -void DCP_Deinit(DCP_Type *base) -{ - base->CTRL = 0xF0800000u; /* reset value */ - (void)memset(&s_dcpContextSwitchingBuffer, 0, sizeof(s_dcpContextSwitchingBuffer)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(kCLOCK_Dcp); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Poll and wait on DCP channel. - * - * Polls the specified DCP channel until current it completes activity. - * - * param base DCP peripheral base address. - * param handle Specifies DCP channel. - * return kStatus_Success When data processing completes without error. - * return kStatus_Fail When error occurs. - */ -status_t DCP_WaitForChannelComplete(DCP_Type *base, dcp_handle_t *handle) -{ - /* wait if our channel is still active */ - while ((base->STAT & (uint32_t)handle->channel) == (uint32_t)handle->channel) - { - } - - if (dcp_get_channel_status(base, handle->channel) != kStatus_Success) - { - dcp_clear_status(base); - dcp_clear_channel_status(base, (uint32_t)handle->channel); - return kStatus_Fail; - } - - dcp_clear_status(base); - return kStatus_Success; -} - -/*! - * @brief Check validity of algoritm. - * - * This function checks the validity of input argument. - * - * @param algo Tested algorithm value. - * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise. - */ -static status_t dcp_hash_check_input_alg(dcp_hash_algo_t algo) -{ - if ((algo != kDCP_Sha256) && (algo != kDCP_Sha1) && (algo != kDCP_Crc32)) - { - return kStatus_InvalidArgument; - } - return kStatus_Success; -} - -/*! - * @brief Check validity of input arguments. - * - * This function checks the validity of input arguments. - * - * @param base DCP peripheral base address. - * @param ctx Memory buffer given by user application where the DCP_HASH_Init/DCP_HASH_Update/DCP_HASH_Finish store - * context. - * @param algo Tested algorithm value. - * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise. - */ -static status_t dcp_hash_check_input_args(DCP_Type *base, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo) -{ - /* Check validity of input algorithm */ - if (kStatus_Success != dcp_hash_check_input_alg(algo)) - { - return kStatus_InvalidArgument; - } - - if ((NULL == ctx) || (NULL == base)) - { - return kStatus_InvalidArgument; - } - - return kStatus_Success; -} - -/*! - * @brief Check validity of internal software context. - * - * This function checks if the internal context structure looks correct. - * - * @param ctxInternal Internal context. - * @param message Input message address. - * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise. - */ -static status_t dcp_hash_check_context(dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *message) -{ - if ((NULL == message) || (NULL == ctxInternal) || (kStatus_Success != dcp_hash_check_input_alg(ctxInternal->algo))) - { - return kStatus_InvalidArgument; - } - -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - else if ((uint32_t)ctxInternal & (FSL_FEATURE_L1DCACHE_LINESIZE_BYTE - 1)) - { - /* ctx must be cache line aligned when using DCACHE */ - return kStatus_InvalidArgument; - } -#endif - - return kStatus_Success; -} - -/*! - * @brief Initialize the SHA engine for new hash. - * - * This function sets kDCP_CONTROL0_HASH_INIT for control0 in work packet to start a new hash. - * - * @param base SHA peripheral base address. - * @param ctxInternal Internal context. - */ -static status_t dcp_hash_engine_init(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal) -{ - status_t status; - - status = kStatus_InvalidArgument; - - if ((kDCP_Sha256 == ctxInternal->algo) || (kDCP_Sha1 == ctxInternal->algo) || (kDCP_Crc32 == ctxInternal->algo)) - { - ctxInternal->ctrl0 = (uint32_t)kDCP_CONTROL0_HASH_INIT; - status = kStatus_Success; - } - - return status; -} - -static status_t dcp_hash_update_non_blocking( - DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, dcp_work_packet_t *dcpPacket, const uint8_t *msg, size_t size) -{ - dcpPacket->control0 = ctxInternal->ctrl0 | (ctxInternal->handle->swapConfig & 0xFC0000u) | - (uint32_t)kDCP_CONTROL0_ENABLE_HASH | (uint32_t)kDCP_CONTROL0_DECR_SEMAPHOR; - if (ctxInternal->algo == kDCP_Sha256) - { - dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA256; - } - else if (ctxInternal->algo == kDCP_Sha1) - { - dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_SHA1; - } - else if (ctxInternal->algo == kDCP_Crc32) - { - /* In CRC-32 case if size is zero, do not schedule other computing */ - if (size == 0U) - { -#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - /* Clear DCACHE memory before starting the engine */ - SCB_CleanDCache_by_Addr((uint32_t *)ctxInternal, sizeof(dcp_hash_ctx_internal_t)); -#endif - /* Make sure that all data memory accesses are completed before starting of the job */ - __DSB(); - __ISB(); - return kStatus_Success; - } - dcpPacket->control1 = (uint32_t)kDCP_CONTROL1_HASH_SELECT_CRC32; - } - else - { - return kStatus_Fail; - } - dcpPacket->sourceBufferAddress = (uint32_t)msg; - dcpPacket->destinationBufferAddress = 0; - dcpPacket->bufferSize = size; - dcpPacket->payloadPointer = (uint32_t)ctxInternal->runningHash; - -#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - /* Clear DCACHE memory before starting the engine */ - SCB_CleanDCache_by_Addr((uint32_t *)ctxInternal, sizeof(dcp_hash_ctx_internal_t)); -#endif - /* Make sure that all data memory accesses are completed before starting of the job */ - __DSB(); - __ISB(); - - return dcp_schedule_work(base, ctxInternal->handle, dcpPacket); -} - -static status_t dcp_hash_update(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal, const uint8_t *msg, size_t size) -{ - status_t completionStatus = kStatus_Fail; - - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_work_packet_t *dcpWork; - uint8_t dcpWorkExt[sizeof(dcp_work_packet_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - dcpWork = (dcp_work_packet_t *)DCP_FindCacheLine(dcpWorkExt); -#else - dcp_work_packet_t dcpWorkPacket = {0}; - dcp_work_packet_t *dcpWork = &dcpWorkPacket; -#endif - - do - { - completionStatus = dcp_hash_update_non_blocking(base, ctxInternal, dcpWork, msg, size); - } while (completionStatus == (int32_t)kStatus_DCP_Again); - - completionStatus = DCP_WaitForChannelComplete(base, ctxInternal->handle); - - ctxInternal->ctrl0 = 0; /* clear kDCP_CONTROL0_HASH_INIT and kDCP_CONTROL0_HASH_TERM flags */ - return (completionStatus); -} - -/*! - * @brief Adds message to current hash. - * - * This function merges the message to fill the internal buffer, empties the internal buffer if - * it becomes full, then process all remaining message data. - * - * - * @param base DCP peripheral base address. - * @param ctxInternal Internal context. - * @param message Input message. - * @param messageSize Size of input message in bytes. - * @return kStatus_Success. - */ -static status_t dcp_hash_process_message_data(DCP_Type *base, - dcp_hash_ctx_internal_t *ctxInternal, - const uint8_t *message, - size_t messageSize) -{ - status_t status = kStatus_Fail; - - /* if there is partially filled internal buffer, fill it to full block */ - if (ctxInternal->blksz > 0U) - { - size_t toCopy = DCP_HASH_BLOCK_SIZE - ctxInternal->blksz; - (void)dcp_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy); - message += toCopy; - messageSize -= toCopy; - - /* process full internal block */ - status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], DCP_HASH_BLOCK_SIZE); - if (kStatus_Success != status) - { - return status; - } - } - - /* process all full blocks in message[] */ - uint32_t fullBlocksSize = ((messageSize >> 6) << 6); /* (X / 64) * 64 */ - if (fullBlocksSize > 0U) - { - status = dcp_hash_update(base, ctxInternal, message, fullBlocksSize); - if (kStatus_Success != status) - { - return status; - } - message += fullBlocksSize; - messageSize -= fullBlocksSize; - } - - /* copy last incomplete message bytes into internal block */ - (void)dcp_memcpy(&ctxInternal->blk.b[0], message, messageSize); - ctxInternal->blksz = messageSize; - - return status; -} - -/*! - * @brief Finalize the running hash to make digest. - * - * This function empties the internal buffer, adds padding bits, and generates final digest. - * - * @param base SHA peripheral base address. - * @param ctxInternal Internal context. - * @return kStatus_Success. - */ -static status_t dcp_hash_finalize(DCP_Type *base, dcp_hash_ctx_internal_t *ctxInternal) -{ - status_t status; - - ctxInternal->ctrl0 |= (uint32_t)kDCP_CONTROL0_HASH_TERM; - status = dcp_hash_update(base, ctxInternal, &ctxInternal->blk.b[0], ctxInternal->blksz); - - return status; -} - -static void dcp_hash_save_running_hash(dcp_hash_ctx_internal_t *ctxInternal) -{ - uint32_t *srcAddr = NULL; - - switch (ctxInternal->handle->channel) - { - case kDCP_Channel0: - srcAddr = &s_dcpContextSwitchingBuffer.x[43]; - break; - - case kDCP_Channel1: - srcAddr = &s_dcpContextSwitchingBuffer.x[30]; - break; - - case kDCP_Channel2: - srcAddr = &s_dcpContextSwitchingBuffer.x[17]; - break; - - case kDCP_Channel3: - srcAddr = &s_dcpContextSwitchingBuffer.x[4]; - break; - - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - if (srcAddr != NULL) - { - (void)dcp_memcpy(ctxInternal->runningHash, srcAddr, sizeof(ctxInternal->runningHash)); - } -} - -static void dcp_hash_restore_running_hash(dcp_hash_ctx_internal_t *ctxInternal) -{ - uint32_t *destAddr = NULL; - - switch (ctxInternal->handle->channel) - { - case kDCP_Channel0: - destAddr = &s_dcpContextSwitchingBuffer.x[43]; - break; - - case kDCP_Channel1: - destAddr = &s_dcpContextSwitchingBuffer.x[30]; - break; - - case kDCP_Channel2: - destAddr = &s_dcpContextSwitchingBuffer.x[17]; - break; - - case kDCP_Channel3: - destAddr = &s_dcpContextSwitchingBuffer.x[4]; - break; - - default: - /* No valid channel */ - break; - } - if (destAddr != NULL) - { - (void)dcp_memcpy(destAddr, ctxInternal->runningHash, sizeof(ctxInternal->runningHash)); - } -} - -/*! - * brief Initialize HASH context - * - * This function initializes the HASH. - * - * param base DCP peripheral base address - * param handle Specifies the DCP channel used for hashing. - * param[out] ctx Output hash context - * param algo Underlaying algorithm to use for hash computation. - * return Status of initialization - */ -status_t DCP_HASH_Init(DCP_Type *base, dcp_handle_t *handle, dcp_hash_ctx_t *ctx, dcp_hash_algo_t algo) -{ - status_t status; - - dcp_hash_ctx_internal_t *ctxInternal; -#ifndef __rtems__ - /* compile time check for the correct structure size */ - BUILD_ASSURE(sizeof(dcp_hash_ctx_t) >= sizeof(dcp_hash_ctx_internal_t), dcp_hash_ctx_t_size); -#else /* __rtems__ */ - assert(sizeof(dcp_hash_ctx_t) >= sizeof(dcp_hash_ctx_internal_t)); -#endif /* __rtems__ */ - uint32_t i; - - status = dcp_hash_check_input_args(base, ctx, algo); - if (status != kStatus_Success) - { - return status; - } - - /* set algorithm in context struct for later use */ - ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx; - ctxInternal->algo = algo; - ctxInternal->blksz = 0u; - - const uint32_t j = sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); - for (i = 0; i < j; i++) - { - ctxInternal->blk.w[i] = 0u; - } - ctxInternal->state = kDCP_StateHashInit; - ctxInternal->fullMessageSize = 0; - ctxInternal->handle = handle; - return status; -} - -/*! - * brief Add data to current HASH - * - * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be - * hashed. The functions blocks. If it returns kStatus_Success, the running hash - * has been updated (DCP has processed the input data), so the memory at ref input pointer - * can be released back to system. The DCP context buffer is updated with the running hash - * and with all necessary information to support possible context switch. - * - * param base DCP peripheral base address - * param[in,out] ctx HASH context - * param input Input data - * param inputSize Size of input data in bytes - * return Status of the hash update operation - */ -status_t DCP_HASH_Update(DCP_Type *base, dcp_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize) -{ - bool isUpdateState; - status_t status; - dcp_hash_ctx_internal_t *ctxInternal; - size_t blockSize; - - if (inputSize == 0U) - { - return kStatus_Success; - } - - ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx; - status = dcp_hash_check_context(ctxInternal, input); - if (kStatus_Success != status) - { - return status; - } - - ctxInternal->fullMessageSize += inputSize; - blockSize = DCP_HASH_BLOCK_SIZE; - /* if we are still less than DCP_HASH_BLOCK_SIZE bytes, keep only in context */ - if ((ctxInternal->blksz + inputSize) <= blockSize) - { - (void)dcp_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize); - ctxInternal->blksz += inputSize; - return status; - } - else - { - isUpdateState = ctxInternal->state == kDCP_StateHashUpdate; - if (!isUpdateState) - { - /* start NEW hash */ - status = dcp_hash_engine_init(base, ctxInternal); - if (status != kStatus_Success) - { - return status; - } - ctxInternal->state = kDCP_StateHashUpdate; - } - else - { - dcp_hash_restore_running_hash(ctxInternal); - } - } - - /* process input data */ - status = dcp_hash_process_message_data(base, ctxInternal, input, inputSize); - dcp_hash_save_running_hash(ctxInternal); - return status; -} - -/*! - * brief Finalize hashing - * - * Outputs the final hash (computed by DCP_HASH_Update()) and erases the context. - * - * param[in,out] ctx Input hash context - * param[out] output Output hash data - * param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of - * output[] buffer. On function return, it stores the number of updated output bytes. - * return Status of the hash finish operation - */ -status_t DCP_HASH_Finish(DCP_Type *base, dcp_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize) -{ - size_t algOutSize = 0; - status_t status; - dcp_hash_ctx_internal_t *ctxInternal; - - ctxInternal = (dcp_hash_ctx_internal_t *)(uint32_t)ctx; - status = dcp_hash_check_context(ctxInternal, output); - - if (kStatus_Success != status) - { - return status; - } - - if (ctxInternal->state == kDCP_StateHashInit) - { - status = dcp_hash_engine_init(base, ctxInternal); - if (status != kStatus_Success) - { - return status; - } - } - else - { - dcp_hash_restore_running_hash(ctxInternal); - } - - size_t outSize = 0u; - - /* compute algorithm output length */ - switch (ctxInternal->algo) - { - case kDCP_Sha256: - outSize = (uint32_t)kDCP_OutLenSha256; - break; - case kDCP_Sha1: - outSize = (uint32_t)kDCP_OutLenSha1; - break; - case kDCP_Crc32: - outSize = (uint32_t)kDCP_OutLenCrc32; - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - algOutSize = outSize; - -#if defined(DCP_HASH_CAVP_COMPATIBLE) - if (ctxInternal->fullMessageSize == 0U) - { - switch (ctxInternal->algo) - { - case kDCP_Sha256: - (void)dcp_memcpy(&output[0], &s_nullSha256, 32); - break; - case kDCP_Sha1: - (void)dcp_memcpy(&output[0], &s_nullSha1, 20); - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - - return kStatus_Success; - } -#endif /* DCP_HASH_CAVP_COMPATIBLE */ - - /* flush message last incomplete block, if there is any, and add padding bits */ - status = dcp_hash_finalize(base, ctxInternal); - - if (outputSize != NULL) - { - if (algOutSize < *outputSize) - { - *outputSize = algOutSize; - } - else - { - algOutSize = *outputSize; - } - } - -#if defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - SCB_InvalidateDCache_by_Addr(ctx, sizeof(dcp_hash_ctx_t)); -#endif - /* Reverse and copy result to output[] */ - dcp_reverse_and_copy((uint8_t *)ctxInternal->runningHash, &output[0], algOutSize); - - (void)memset(ctx, 0, sizeof(dcp_hash_ctx_t)); - return status; -} - -/*! - * brief Create HASH on given data - * - * Perform the full SHA or CRC32 in one function call. The function is blocking. - * - * param base DCP peripheral base address - * param handle Handle used for the request. - * param algo Underlaying algorithm to use for hash computation. - * param input Input data - * param inputSize Size of input data in bytes - * param[out] output Output hash data - * param[out] outputSize Output parameter storing the size of the output hash in bytes - * return Status of the one call hash operation. - */ -status_t DCP_HASH(DCP_Type *base, - dcp_handle_t *handle, - dcp_hash_algo_t algo, - const uint8_t *input, - size_t inputSize, - uint8_t *output, - size_t *outputSize) -{ - /* Use extended DCACHE line size aligned structure */ -#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) && defined(DCP_USE_DCACHE) && (DCP_USE_DCACHE == 1U) - dcp_hash_ctx_t *hashCtx; - uint8_t hashCtxExt[sizeof(dcp_hash_ctx_t) + FSL_FEATURE_L1DCACHE_LINESIZE_BYTE] = {0U}; - hashCtx = (dcp_hash_ctx_t *)DCP_FindCacheLine(hashCtxExt); -#else - dcp_hash_ctx_t hashCtxStruct = {0}; - dcp_hash_ctx_t *hashCtx = &hashCtxStruct; -#endif - - status_t status; - - status = DCP_HASH_Init(base, handle, hashCtx, algo); - if (status != kStatus_Success) - { - return status; - } - - status = DCP_HASH_Update(base, hashCtx, input, inputSize); - if (status != kStatus_Success) - { - return status; - } - - status = DCP_HASH_Finish(base, hashCtx, output, outputSize); - - return status; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c deleted file mode 100644 index 8bfbe6c367..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_dmamux.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_dmamux.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.dmamux" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get instance number for DMAMUX. - * - * @param base DMAMUX peripheral base address. - */ -static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*! @brief Array to map DMAMUX instance number to base pointer. */ -static DMAMUX_Type *const s_dmamuxBases[] = DMAMUX_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Array to map DMAMUX instance number to clock name. */ -static const clock_ip_name_t s_dmamuxClockName[] = DMAMUX_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t DMAMUX_GetInstance(DMAMUX_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_dmamuxBases); instance++) - { - if (s_dmamuxBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_dmamuxBases)); - - return instance; -} - -/*! - * brief Initializes the DMAMUX peripheral. - * - * This function ungates the DMAMUX clock. - * - * param base DMAMUX peripheral base address. - * - */ -void DMAMUX_Init(DMAMUX_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_EnableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Deinitializes the DMAMUX peripheral. - * - * This function gates the DMAMUX clock. - * - * param base DMAMUX peripheral base address. - */ -void DMAMUX_Deinit(DMAMUX_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(s_dmamuxClockName[DMAMUX_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c deleted file mode 100644 index e74334bc5a..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_edma.c +++ /dev/null @@ -1,2849 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.edma" -#endif - -#define EDMA_TRANSFER_ENABLED_MASK 0x80U - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get instance offset. - * - * @param instance EDMA peripheral instance number. - */ -static uint32_t EDMA_GetInstanceOffset(uint32_t instance); - -/*! - * @brief Map transfer width. - * - * @param width transfer width. - */ -static edma_transfer_size_t EDMA_TransferWidthMapping(uint32_t width); -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*! @brief Array to map EDMA instance number to base pointer. */ -static DMA_Type *const s_edmaBases[] = DMA_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Array to map EDMA instance number to clock name. */ -static const clock_ip_name_t s_edmaClockName[] = EDMA_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Array to map EDMA instance number to IRQ number. */ -static const IRQn_Type s_edmaIRQNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; - -/*! @brief Pointers to transfer handle for each EDMA channel. */ -static edma_handle_t *s_EDMAHandle[FSL_FEATURE_EDMA_MODULE_CHANNEL * FSL_FEATURE_SOC_EDMA_COUNT]; - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t EDMA_GetInstance(DMA_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_edmaBases); instance++) - { - if (s_edmaBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_edmaBases)); - - return instance; -} - -/*! - * brief Push content of TCD structure into hardware TCD register. - * - * param base EDMA peripheral base address. - * param channel EDMA channel number. - * param tcd Point to TCD structure. - */ -void EDMA_InstallTCD(DMA_Type *base, uint32_t channel, edma_tcd_t *tcd) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - - /* Push tcd into hardware TCD register */ - base->TCD[channel].SADDR = tcd->SADDR; - base->TCD[channel].SOFF = tcd->SOFF; - base->TCD[channel].ATTR = tcd->ATTR; - base->TCD[channel].NBYTES_MLNO = tcd->NBYTES; - base->TCD[channel].SLAST = tcd->SLAST; - base->TCD[channel].DADDR = tcd->DADDR; - base->TCD[channel].DOFF = tcd->DOFF; - base->TCD[channel].CITER_ELINKNO = tcd->CITER; - base->TCD[channel].DLAST_SGA = tcd->DLAST_SGA; - /* Clear DONE bit first, otherwise ESG cannot be set */ - base->TCD[channel].CSR = 0; - base->TCD[channel].CSR = tcd->CSR; - base->TCD[channel].BITER_ELINKNO = tcd->BITER; -} - -/*! - * brief Initializes the eDMA peripheral. - * - * This function ungates the eDMA clock and configures the eDMA peripheral according - * to the configuration structure. - * - * param base eDMA peripheral base address. - * param config A pointer to the configuration structure, see "edma_config_t". - * note This function enables the minor loop map feature. - */ -void EDMA_Init(DMA_Type *base, const edma_config_t *config) -{ - assert(config != NULL); - - uint32_t tmpreg; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate EDMA peripheral clock */ - CLOCK_EnableClock(s_edmaClockName[EDMA_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* clear all the enabled request, status to make sure EDMA status is in normal condition */ - base->ERQ = 0U; - base->INT = 0xFFFFFFFFU; - base->ERR = 0xFFFFFFFFU; - /* Configure EDMA peripheral according to the configuration structure. */ - tmpreg = base->CR; - tmpreg &= ~(DMA_CR_ERCA_MASK | DMA_CR_HOE_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK); - tmpreg |= (DMA_CR_ERCA(config->enableRoundRobinArbitration) | DMA_CR_HOE(config->enableHaltOnError) | - DMA_CR_CLM(config->enableContinuousLinkMode) | DMA_CR_EDBG(config->enableDebugMode) | DMA_CR_EMLM(1U)); - base->CR = tmpreg; -} - -/*! - * brief Deinitializes the eDMA peripheral. - * - * This function gates the eDMA clock. - * - * param base eDMA peripheral base address. - */ -void EDMA_Deinit(DMA_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Gate EDMA peripheral clock */ - CLOCK_DisableClock(s_edmaClockName[EDMA_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the eDMA default configuration structure. - * - * This function sets the configuration structure to default values. - * The default configuration is set to the following values. - * code - * config.enableContinuousLinkMode = false; - * config.enableHaltOnError = true; - * config.enableRoundRobinArbitration = false; - * config.enableDebugMode = false; - * endcode - * - * param config A pointer to the eDMA configuration structure. - */ -void EDMA_GetDefaultConfig(edma_config_t *config) -{ - assert(config != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableRoundRobinArbitration = false; - config->enableHaltOnError = true; - config->enableContinuousLinkMode = false; - config->enableDebugMode = false; -} - -/*! - * brief Sets all TCD registers to default values. - * - * This function sets TCD registers for this channel to default values. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * note This function must not be called while the channel transfer is ongoing - * or it causes unpredictable results. - * note This function enables the auto stop request feature. - */ -void EDMA_ResetChannel(DMA_Type *base, uint32_t channel) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - EDMA_TcdReset((edma_tcd_t *)(uint32_t)&base->TCD[channel]); -} - -/*! - * brief Configures the eDMA transfer attribute. - * - * This function configures the transfer attribute, including source address, destination address, - * transfer size, address offset, and so on. It also configures the scatter gather feature if the - * user supplies the TCD address. - * Example: - * code - * edma_transfer_t config; - * edma_tcd_t tcd; - * config.srcAddr = ..; - * config.destAddr = ..; - * ... - * EDMA_SetTransferConfig(DMA0, channel, &config, &stcd); - * endcode - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param config Pointer to eDMA transfer configuration structure. - * param nextTcd Point to TCD structure. It can be NULL if users - * do not want to enable scatter/gather feature. - * note If nextTcd is not NULL, it means scatter gather feature is enabled - * and DREQ bit is cleared in the previous transfer configuration, which - * is set in the eDMA_ResetChannel. - */ -void EDMA_SetTransferConfig(DMA_Type *base, uint32_t channel, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - assert(config != NULL); - assert(((uint32_t)nextTcd & 0x1FU) == 0U); - - EDMA_TcdSetTransferConfig((edma_tcd_t *)(uint32_t)&base->TCD[channel], config, nextTcd); -} - -/*! - * brief Configures the eDMA minor offset feature. - * - * The minor offset means that the signed-extended value is added to the source address or destination - * address after each minor loop. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param config A pointer to the minor offset configuration structure. - */ -void EDMA_SetMinorOffsetConfig(DMA_Type *base, uint32_t channel, const edma_minor_offset_config_t *config) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - assert(config != NULL); - - uint32_t tmpreg; - - tmpreg = base->TCD[channel].NBYTES_MLOFFYES; - tmpreg &= ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); - tmpreg |= - (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | - DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); - base->TCD[channel].NBYTES_MLOFFYES = tmpreg; -} - -/*! - * brief Configures the eDMA channel preemption feature. - * - * This function configures the channel preemption attribute and the priority of the channel. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number - * param config A pointer to the channel preemption configuration structure. - */ -void EDMA_SetChannelPreemptionConfig(DMA_Type *base, uint32_t channel, const edma_channel_Preemption_config_t *config) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - assert(config != NULL); - - bool tmpEnablePreemptAbility = config->enablePreemptAbility; - bool tmpEnableChannelPreemption = config->enableChannelPreemption; - uint8_t tmpChannelPriority = config->channelPriority; - volatile uint8_t *tmpReg = &base->DCHPRI3; - - ((volatile uint8_t *)tmpReg)[DMA_DCHPRI_INDEX(channel)] = - (DMA_DCHPRI0_DPA((true == tmpEnablePreemptAbility ? 0U : 1U)) | - DMA_DCHPRI0_ECP((true == tmpEnableChannelPreemption ? 1U : 0U)) | DMA_DCHPRI0_CHPRI(tmpChannelPriority)); -} - -/*! - * brief Sets the channel link for the eDMA transfer. - * - * This function configures either the minor link or the major link mode. The minor link means that the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is - * exhausted. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param type A channel link type, which can be one of the following: - * arg kEDMA_LinkNone - * arg kEDMA_MinorLink - * arg kEDMA_MajorLink - * param linkedChannel The linked channel number. - * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. - */ -void EDMA_SetChannelLink(DMA_Type *base, uint32_t channel, edma_channel_link_type_t type, uint32_t linkedChannel) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - assert(linkedChannel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - EDMA_TcdSetChannelLink((edma_tcd_t *)(uint32_t)&base->TCD[channel], type, linkedChannel); -} - -/*! - * brief Sets the bandwidth for the eDMA transfer. - * - * Because the eDMA processes the minor loop, it continuously generates read/write sequences - * until the minor count is exhausted. The bandwidth forces the eDMA to stall after the completion of - * each read/write access to control the bus request bandwidth seen by the crossbar switch. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param bandWidth A bandwidth setting, which can be one of the following: - * arg kEDMABandwidthStallNone - * arg kEDMABandwidthStall4Cycle - * arg kEDMABandwidthStall8Cycle - */ -void EDMA_SetBandWidth(DMA_Type *base, uint32_t channel, edma_bandwidth_t bandWidth) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - base->TCD[channel].CSR = (uint16_t)((base->TCD[channel].CSR & (~DMA_CSR_BWC_MASK)) | DMA_CSR_BWC(bandWidth)); -} - -/*! - * brief Sets the source modulo and the destination modulo for the eDMA transfer. - * - * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) - * calculation is performed or the original register value. It provides the ability to implement a circular data - * queue easily. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param srcModulo A source modulo value. - * param destModulo A destination modulo value. - */ -void EDMA_SetModulo(DMA_Type *base, uint32_t channel, edma_modulo_t srcModulo, edma_modulo_t destModulo) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - uint16_t tmpreg; - - tmpreg = base->TCD[channel].ATTR & (~(uint16_t)(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); - base->TCD[channel].ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); -} - -/*! - * brief Enables the interrupt source for the eDMA transfer. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param mask The mask of interrupt source to be set. Users need to use - * the defined edma_interrupt_enable_t type. - */ -void EDMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - /* Enable error interrupt */ - if (0U != (mask & (uint32_t)kEDMA_ErrorInterruptEnable)) - { - base->EEI |= ((uint32_t)0x1U << channel); - } - - /* Enable Major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable)) - { - base->TCD[channel].CSR |= DMA_CSR_INTMAJOR_MASK; - } - - /* Enable Half major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable)) - { - base->TCD[channel].CSR |= DMA_CSR_INTHALF_MASK; - } -} - -/*! - * brief Disables the interrupt source for the eDMA transfer. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param mask The mask of the interrupt source to be set. Use - * the defined edma_interrupt_enable_t type. - */ -void EDMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel, uint32_t mask) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - /* Disable error interrupt */ - if (0U != (mask & (uint32_t)kEDMA_ErrorInterruptEnable)) - { - base->EEI &= (~((uint32_t)0x1U << channel)); - } - - /* Disable Major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable)) - { - base->TCD[channel].CSR &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK; - } - - /* Disable Half major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable)) - { - base->TCD[channel].CSR &= ~(uint16_t)DMA_CSR_INTHALF_MASK; - } -} - -/*! - * brief Sets all fields to default values for the TCD structure. - * - * This function sets all fields for this TCD structure to default value. - * - * param tcd Pointer to the TCD structure. - * note This function enables the auto stop request feature. - */ -void EDMA_TcdReset(edma_tcd_t *tcd) -{ - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - - /* Reset channel TCD */ - tcd->SADDR = 0U; - tcd->SOFF = 0U; - tcd->ATTR = 0U; - tcd->NBYTES = 0U; - tcd->SLAST = 0U; - tcd->DADDR = 0U; - tcd->DOFF = 0U; - tcd->CITER = 0U; - tcd->DLAST_SGA = 0U; - /* Enable auto disable request feature */ - tcd->CSR = DMA_CSR_DREQ(true); - tcd->BITER = 0U; -} - -/*! - * brief Configures the eDMA TCD transfer attribute. - * - * The TCD is a transfer control descriptor. The content of the TCD is the same as the hardware TCD registers. - * The STCD is used in the scatter-gather mode. - * This function configures the TCD transfer attribute, including source address, destination address, - * transfer size, address offset, and so on. It also configures the scatter gather feature if the - * user supplies the next TCD address. - * Example: - * code - * edma_transfer_t config = { - * ... - * } - * edma_tcd_t tcd __aligned(32); - * edma_tcd_t nextTcd __aligned(32); - * EDMA_TcdSetTransferConfig(&tcd, &config, &nextTcd); - * endcode - * - * param tcd Pointer to the TCD structure. - * param config Pointer to eDMA transfer configuration structure. - * param nextTcd Pointer to the next TCD structure. It can be NULL if users - * do not want to enable scatter/gather feature. - * note TCD address should be 32 bytes aligned or it causes an eDMA error. - * note If the nextTcd is not NULL, the scatter gather feature is enabled - * and DREQ bit is cleared in the previous transfer configuration, which - * is set in the EDMA_TcdReset. - */ -void EDMA_TcdSetTransferConfig(edma_tcd_t *tcd, const edma_transfer_config_t *config, edma_tcd_t *nextTcd) -{ - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - assert(config != NULL); - assert(((uint32_t)nextTcd & 0x1FU) == 0U); - assert((config->srcAddr % (1UL << (uint32_t)config->srcTransferSize)) == 0U); - assert((config->destAddr % (1UL << (uint32_t)config->destTransferSize)) == 0U); - - /* source address */ - tcd->SADDR = config->srcAddr; - /* destination address */ - tcd->DADDR = config->destAddr; - /* Source data and destination data transfer size */ - tcd->ATTR = DMA_ATTR_SSIZE(config->srcTransferSize) | DMA_ATTR_DSIZE(config->destTransferSize); - /* Source address signed offset */ - tcd->SOFF = (uint16_t)config->srcOffset; - /* Destination address signed offset */ - tcd->DOFF = (uint16_t)config->destOffset; - /* Minor byte transfer count */ - tcd->NBYTES = config->minorLoopBytes; - /* Current major iteration count */ - tcd->CITER = (uint16_t)config->majorLoopCounts; - /* Starting major iteration count */ - tcd->BITER = (uint16_t)config->majorLoopCounts; - /* Enable scatter/gather processing */ - if (nextTcd != NULL) - { - tcd->DLAST_SGA = (uint32_t)nextTcd; - /* - Before call EDMA_TcdSetTransferConfig or EDMA_SetTransferConfig, - user must call EDMA_TcdReset or EDMA_ResetChannel which will set - DREQ, so must use "|" or "&" rather than "=". - - Clear the DREQ bit because scatter gather has been enabled, so the - previous transfer is not the last transfer, and channel request should - be enabled at the next transfer(the next TCD). - */ - tcd->CSR = (tcd->CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK; - } -} - -/*! - * brief Configures the eDMA TCD minor offset feature. - * - * A minor offset is a signed-extended value added to the source address or a destination - * address after each minor loop. - * - * param tcd A point to the TCD structure. - * param config A pointer to the minor offset configuration structure. - */ -void EDMA_TcdSetMinorOffsetConfig(edma_tcd_t *tcd, const edma_minor_offset_config_t *config) -{ - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - - uint32_t tmpreg; - - tmpreg = tcd->NBYTES & - ~(DMA_NBYTES_MLOFFYES_SMLOE_MASK | DMA_NBYTES_MLOFFYES_DMLOE_MASK | DMA_NBYTES_MLOFFYES_MLOFF_MASK); - tmpreg |= - (DMA_NBYTES_MLOFFYES_SMLOE(config->enableSrcMinorOffset) | - DMA_NBYTES_MLOFFYES_DMLOE(config->enableDestMinorOffset) | DMA_NBYTES_MLOFFYES_MLOFF(config->minorOffset)); - tcd->NBYTES = tmpreg; -} - -/*! - * brief Sets the channel link for the eDMA TCD. - * - * This function configures either a minor link or a major link. The minor link means the channel link is - * triggered every time CITER decreases by 1. The major link means that the channel link is triggered when the CITER is - * exhausted. - * - * note Users should ensure that DONE flag is cleared before calling this interface, or the configuration is invalid. - * param tcd Point to the TCD structure. - * param type Channel link type, it can be one of: - * arg kEDMA_LinkNone - * arg kEDMA_MinorLink - * arg kEDMA_MajorLink - * param linkedChannel The linked channel number. - */ -void EDMA_TcdSetChannelLink(edma_tcd_t *tcd, edma_channel_link_type_t type, uint32_t linkedChannel) -{ - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - assert(linkedChannel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - if (type == kEDMA_MinorLink) /* Minor link config */ - { - uint16_t tmpreg; - - /* Enable minor link */ - tcd->CITER |= DMA_CITER_ELINKYES_ELINK_MASK; - tcd->BITER |= DMA_BITER_ELINKYES_ELINK_MASK; - /* Set linked channel */ - tmpreg = tcd->CITER & (~(uint16_t)DMA_CITER_ELINKYES_LINKCH_MASK); - tmpreg |= DMA_CITER_ELINKYES_LINKCH(linkedChannel); - tcd->CITER = tmpreg; - tmpreg = tcd->BITER & (~(uint16_t)DMA_BITER_ELINKYES_LINKCH_MASK); - tmpreg |= DMA_BITER_ELINKYES_LINKCH(linkedChannel); - tcd->BITER = tmpreg; - } - else if (type == kEDMA_MajorLink) /* Major link config */ - { - uint16_t tmpreg; - - /* Enable major link */ - tcd->CSR |= DMA_CSR_MAJORELINK_MASK; - /* Set major linked channel */ - tmpreg = tcd->CSR & (~(uint16_t)DMA_CSR_MAJORLINKCH_MASK); - tcd->CSR = tmpreg | DMA_CSR_MAJORLINKCH(linkedChannel); - } - else /* Link none */ - { - tcd->CITER &= ~(uint16_t)DMA_CITER_ELINKYES_ELINK_MASK; - tcd->BITER &= ~(uint16_t)DMA_BITER_ELINKYES_ELINK_MASK; - tcd->CSR &= ~(uint16_t)DMA_CSR_MAJORELINK_MASK; - } -} - -/*! - * brief Sets the source modulo and the destination modulo for the eDMA TCD. - * - * This function defines a specific address range specified to be the value after (SADDR + SOFF)/(DADDR + DOFF) - * calculation is performed or the original register value. It provides the ability to implement a circular data - * queue easily. - * - * param tcd A pointer to the TCD structure. - * param srcModulo A source modulo value. - * param destModulo A destination modulo value. - */ -void EDMA_TcdSetModulo(edma_tcd_t *tcd, edma_modulo_t srcModulo, edma_modulo_t destModulo) -{ - assert(tcd != NULL); - assert(((uint32_t)tcd & 0x1FU) == 0U); - - uint16_t tmpreg; - - tmpreg = tcd->ATTR & (~(uint16_t)(DMA_ATTR_SMOD_MASK | DMA_ATTR_DMOD_MASK)); - tcd->ATTR = tmpreg | DMA_ATTR_DMOD(destModulo) | DMA_ATTR_SMOD(srcModulo); -} - -/*! - * brief Enables the interrupt source for the eDMA TCD. - * - * param tcd Point to the TCD structure. - * param mask The mask of interrupt source to be set. Users need to use - * the defined edma_interrupt_enable_t type. - */ -void EDMA_TcdEnableInterrupts(edma_tcd_t *tcd, uint32_t mask) -{ - assert(tcd != NULL); - - /* Enable Major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable)) - { - tcd->CSR |= DMA_CSR_INTMAJOR_MASK; - } - - /* Enable Half major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable)) - { - tcd->CSR |= DMA_CSR_INTHALF_MASK; - } -} - -/*! - * brief Disables the interrupt source for the eDMA TCD. - * - * param tcd Point to the TCD structure. - * param mask The mask of interrupt source to be set. Users need to use - * the defined edma_interrupt_enable_t type. - */ -void EDMA_TcdDisableInterrupts(edma_tcd_t *tcd, uint32_t mask) -{ - assert(tcd != NULL); - - /* Disable Major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_MajorInterruptEnable)) - { - tcd->CSR &= ~(uint16_t)DMA_CSR_INTMAJOR_MASK; - } - - /* Disable Half major interrupt */ - if (0U != (mask & (uint32_t)kEDMA_HalfInterruptEnable)) - { - tcd->CSR &= ~(uint16_t)DMA_CSR_INTHALF_MASK; - } -} - -/*! - * brief Gets the remaining major loop count from the eDMA current channel TCD. - * - * This function checks the TCD (Task Control Descriptor) status for a specified - * eDMA channel and returns the number of major loop count that has not finished. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * return Major loop count which has not been transferred yet for the current TCD. - * note 1. This function can only be used to get unfinished major loop count of transfer without - * the next TCD, or it might be inaccuracy. - * 2. The unfinished/remaining transfer bytes cannot be obtained directly from registers while - * the channel is running. - * Because to calculate the remaining bytes, the initial NBYTES configured in DMA_TCDn_NBYTES_MLNO - * register is needed while the eDMA IP does not support getting it while a channel is active. - * In another word, the NBYTES value reading is always the actual (decrementing) NBYTES value the dma_engine - * is working with while a channel is running. - * Consequently, to get the remaining transfer bytes, a software-saved initial value of NBYTES (for example - * copied before enabling the channel) is needed. The formula to calculate it is shown below: - * RemainingBytes = RemainingMajorLoopCount * NBYTES(initially configured) - */ -uint32_t EDMA_GetRemainingMajorLoopCount(DMA_Type *base, uint32_t channel) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - uint32_t remainingCount = 0; - - if (0U != (DMA_CSR_DONE_MASK & base->TCD[channel].CSR)) - { - remainingCount = 0; - } - else - { - /* Calculate the unfinished bytes */ - if (0U != (base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_ELINK_MASK)) - { - remainingCount = (((uint32_t)base->TCD[channel].CITER_ELINKYES & DMA_CITER_ELINKYES_CITER_MASK) >> - DMA_CITER_ELINKYES_CITER_SHIFT); - } - else - { - remainingCount = (((uint32_t)base->TCD[channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) >> - DMA_CITER_ELINKNO_CITER_SHIFT); - } - } - - return remainingCount; -} - -/*! - * brief Gets the eDMA channel status flags. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * return The mask of channel status flags. Users need to use the - * _edma_channel_status_flags type to decode the return variables. - */ -uint32_t EDMA_GetChannelStatusFlags(DMA_Type *base, uint32_t channel) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - uint32_t retval = 0; - - /* Get DONE bit flag */ - retval |= (((uint32_t)base->TCD[channel].CSR & DMA_CSR_DONE_MASK) >> DMA_CSR_DONE_SHIFT); - /* Get ERROR bit flag */ - retval |= ((((uint32_t)base->ERR >> channel) & 0x1U) << 1U); - /* Get INT bit flag */ - retval |= ((((uint32_t)base->INT >> channel) & 0x1U) << 2U); - - return retval; -} - -/*! - * brief Clears the eDMA channel status flags. - * - * param base eDMA peripheral base address. - * param channel eDMA channel number. - * param mask The mask of channel status to be cleared. Users need to use - * the defined _edma_channel_status_flags type. - */ -void EDMA_ClearChannelStatusFlags(DMA_Type *base, uint32_t channel, uint32_t mask) -{ - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - /* Clear DONE bit flag */ - if (0U != (mask & (uint32_t)kEDMA_DoneFlag)) - { - base->CDNE = (uint8_t)channel; - } - /* Clear ERROR bit flag */ - if (0U != (mask & (uint32_t)kEDMA_ErrorFlag)) - { - base->CERR = (uint8_t)channel; - } - /* Clear INT bit flag */ - if (0U != (mask & (uint32_t)kEDMA_InterruptFlag)) - { - base->CINT = (uint8_t)channel; - } -} - -static uint32_t EDMA_GetInstanceOffset(uint32_t instance) -{ - static uint8_t startInstanceNum; - -#if defined(DMA0) - startInstanceNum = (uint8_t)EDMA_GetInstance(DMA0); -#elif defined(DMA1) - startInstanceNum = (uint8_t)EDMA_GetInstance(DMA1); -#elif defined(DMA2) - startInstanceNum = (uint8_t)EDMA_GetInstance(DMA2); -#elif defined(DMA3) - startInstanceNum = (uint8_t)EDMA_GetInstance(DMA3); -#endif - - assert(startInstanceNum <= instance); - - return instance - startInstanceNum; -} - -/*! - * brief Creates the eDMA handle. - * - * This function is called if using the transactional API for eDMA. This function - * initializes the internal state of the eDMA handle. - * - * param handle eDMA handle pointer. The eDMA handle stores callback function and - * parameters. - * param base eDMA peripheral base address. - * param channel eDMA channel number. - */ -void EDMA_CreateHandle(edma_handle_t *handle, DMA_Type *base, uint32_t channel) -{ - assert(handle != NULL); - assert(channel < (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL); - - uint32_t edmaInstance; - uint32_t channelIndex; - edma_tcd_t *tcdRegs; - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - handle->base = base; - handle->channel = (uint8_t)channel; - /* Get the DMA instance number */ - edmaInstance = EDMA_GetInstance(base); - channelIndex = (EDMA_GetInstanceOffset(edmaInstance) * (uint32_t)FSL_FEATURE_EDMA_MODULE_CHANNEL) + channel; - s_EDMAHandle[channelIndex] = handle; - - /* Enable NVIC interrupt */ - (void)EnableIRQ(s_edmaIRQNumber[edmaInstance][channel]); - - /* - Reset TCD registers to zero. Unlike the EDMA_TcdReset(DREQ will be set), - CSR will be 0. Because in order to suit EDMA busy check mechanism in - EDMA_SubmitTransfer, CSR must be set 0. - */ - tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel]; - tcdRegs->SADDR = 0; - tcdRegs->SOFF = 0; - tcdRegs->ATTR = 0; - tcdRegs->NBYTES = 0; - tcdRegs->SLAST = 0; - tcdRegs->DADDR = 0; - tcdRegs->DOFF = 0; - tcdRegs->CITER = 0; - tcdRegs->DLAST_SGA = 0; - tcdRegs->CSR = 0; - tcdRegs->BITER = 0; -} - -/*! - * brief Installs the TCDs memory pool into the eDMA handle. - * - * This function is called after the EDMA_CreateHandle to use scatter/gather feature. This function shall only be used - * while users need to use scatter gather mode. Scatter gather mode enables EDMA to load a new transfer control block - * (tcd) in hardware, and automatically reconfigure that DMA channel for a new transfer. - * Users need to prepare tcd memory and also configure tcds using interface EDMA_SubmitTransfer. - * - * param handle eDMA handle pointer. - * param tcdPool A memory pool to store TCDs. It must be 32 bytes aligned. - * param tcdSize The number of TCD slots. - */ -void EDMA_InstallTCDMemory(edma_handle_t *handle, edma_tcd_t *tcdPool, uint32_t tcdSize) -{ - assert(handle != NULL); - assert(((uint32_t)tcdPool & 0x1FU) == 0U); - - /* Initialize tcd queue attribute. */ - handle->header = 0; - handle->tail = 0; - handle->tcdUsed = 0; - handle->tcdSize = (int8_t)tcdSize; - handle->flags = 0; - handle->tcdPool = tcdPool; -} - -/*! - * brief Installs a callback function for the eDMA transfer. - * - * This callback is called in the eDMA IRQ handler. Use the callback to do something after - * the current major loop transfer completes. This function will be called every time one tcd finished transfer. - * - * param handle eDMA handle pointer. - * param callback eDMA callback function pointer. - * param userData A parameter for the callback function. - */ -void EDMA_SetCallback(edma_handle_t *handle, edma_callback callback, void *userData) -{ - assert(handle != NULL); - - handle->callback = callback; - handle->userData = userData; -} - -static edma_transfer_size_t EDMA_TransferWidthMapping(uint32_t width) -{ - edma_transfer_size_t transferSize = kEDMA_TransferSize1Bytes; - - /* map width to register value */ - switch (width) - { - /* width 8bit */ - case 1U: - transferSize = kEDMA_TransferSize1Bytes; - break; - /* width 16bit */ - case 2U: - transferSize = kEDMA_TransferSize2Bytes; - break; - /* width 32bit */ - case 4U: - transferSize = kEDMA_TransferSize4Bytes; - break; -#if (defined(FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_8_BYTES_TRANSFER) - /* width 64bit */ - case 8U: - transferSize = kEDMA_TransferSize8Bytes; - break; -#endif -#if (defined(FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) && FSL_FEATURE_EDMA_SUPPORT_16_BYTES_TRANSFER) - /* width 128bit */ - case 16U: - transferSize = kEDMA_TransferSize16Bytes; - break; -#endif - /* width 256bit */ - case 32U: - transferSize = kEDMA_TransferSize32Bytes; - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - assert(false); - break; - } - - return transferSize; -} - -/*! - * brief Prepares the eDMA transfer structure configurations. - * - * This function prepares the transfer configuration structure according to the user input. - * - * param config The user configuration structure of type edma_transfer_t. - * param srcAddr eDMA transfer source address. - * param srcWidth eDMA transfer source address width(bytes). - * param srcOffset source address offset. - * param destAddr eDMA transfer destination address. - * param destWidth eDMA transfer destination address width(bytes). - * param destOffset destination address offset. - * param bytesEachRequest eDMA transfer bytes per channel request. - * param transferBytes eDMA transfer bytes to be transferred. - * note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, the source address must be 4 bytes aligned, or it results in - * source address error (SAE). - */ -void EDMA_PrepareTransferConfig(edma_transfer_config_t *config, - void *srcAddr, - uint32_t srcWidth, - int16_t srcOffset, - void *destAddr, - uint32_t destWidth, - int16_t destOffset, - uint32_t bytesEachRequest, - uint32_t transferBytes) -{ - assert(config != NULL); - assert(srcAddr != NULL); - assert(destAddr != NULL); - assert((srcWidth != 0U) && (srcWidth <= 32U) && ((srcWidth & (srcWidth - 1U)) == 0U)); - assert((destWidth != 0U) && (destWidth <= 32U) && ((destWidth & (destWidth - 1U)) == 0U)); - assert((transferBytes % bytesEachRequest) == 0U); - assert((((uint32_t)(uint32_t *)srcAddr) % srcWidth) == 0U); - assert((((uint32_t)(uint32_t *)destAddr) % destWidth) == 0U); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->destAddr = (uint32_t)(uint32_t *)destAddr; - config->srcAddr = (uint32_t)(uint32_t *)srcAddr; - config->minorLoopBytes = bytesEachRequest; - config->majorLoopCounts = transferBytes / bytesEachRequest; - config->srcTransferSize = EDMA_TransferWidthMapping(srcWidth); - config->destTransferSize = EDMA_TransferWidthMapping(destWidth); - config->destOffset = destOffset; - config->srcOffset = srcOffset; -} - -/*! - * brief Prepares the eDMA transfer structure. - * - * This function prepares the transfer configuration structure according to the user input. - * - * param config The user configuration structure of type edma_transfer_t. - * param srcAddr eDMA transfer source address. - * param srcWidth eDMA transfer source address width(bytes). - * param destAddr eDMA transfer destination address. - * param destWidth eDMA transfer destination address width(bytes). - * param bytesEachRequest eDMA transfer bytes per channel request. - * param transferBytes eDMA transfer bytes to be transferred. - * param type eDMA transfer type. - * note The data address and the data width must be consistent. For example, if the SRC - * is 4 bytes, the source address must be 4 bytes aligned, or it results in - * source address error (SAE). - */ -void EDMA_PrepareTransfer(edma_transfer_config_t *config, - void *srcAddr, - uint32_t srcWidth, - void *destAddr, - uint32_t destWidth, - uint32_t bytesEachRequest, - uint32_t transferBytes, - edma_transfer_type_t type) -{ - assert(config != NULL); - - int16_t srcOffset = 0, destOffset = 0; - - switch (type) - { - case kEDMA_MemoryToMemory: - destOffset = (int16_t)destWidth; - srcOffset = (int16_t)srcWidth; - break; - case kEDMA_MemoryToPeripheral: - destOffset = 0; - srcOffset = (int16_t)srcWidth; - break; - case kEDMA_PeripheralToMemory: - destOffset = (int16_t)destWidth; - srcOffset = 0; - break; - case kEDMA_PeripheralToPeripheral: - destOffset = 0; - srcOffset = 0; - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - assert(false); - break; - } - - EDMA_PrepareTransferConfig(config, srcAddr, srcWidth, srcOffset, destAddr, destWidth, destOffset, bytesEachRequest, - transferBytes); -} - -/*! - * brief Submits the eDMA transfer request. - * - * This function submits the eDMA transfer request according to the transfer configuration structure. - * In scatter gather mode, call this function will add a configured tcd to the circular list of tcd pool. - * The tcd pools is setup by call function EDMA_InstallTCDMemory before. - * - * param handle eDMA handle pointer. - * param config Pointer to eDMA transfer configuration structure. - * retval kStatus_EDMA_Success It means submit transfer request succeed. - * retval kStatus_EDMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. - * retval kStatus_EDMA_Busy It means the given channel is busy, need to submit request later. - */ -status_t EDMA_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config) -{ - assert(handle != NULL); - assert(config != NULL); - - edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel]; - - if (handle->tcdPool == NULL) - { - /* - * Check if EDMA channel is busy: - * 1. if channel active bit is set, it implies that minor loop is executing, then channel is busy - * 2. if channel active bit is not set and BITER not equal to CITER, it implies that major loop is executing, - * then channel is busy - * - * There is one case can not be covered in below condition: - * When transfer request is submitted, but no request from peripheral, that is to say channel sevice doesn't - * begin, if application would like to submit another transfer , then the TCD will be overwritten, since the - * ACTIVE is 0 and BITER = CITER, for such case, it is a scatter gather(link TCD) case actually, so - * application should enabled TCD pool for dynamic scatter gather mode by calling EDMA_InstallTCDMemory. - */ - if (((handle->base->TCD[handle->channel].CSR & DMA_CSR_ACTIVE_MASK) != 0U) || - (((handle->base->TCD[handle->channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) != - (handle->base->TCD[handle->channel].BITER_ELINKNO & DMA_BITER_ELINKNO_BITER_MASK)))) - { - return kStatus_EDMA_Busy; - } - else - { - EDMA_SetTransferConfig(handle->base, handle->channel, config, NULL); - /* Enable auto disable request feature */ - handle->base->TCD[handle->channel].CSR |= DMA_CSR_DREQ_MASK; - /* Enable major interrupt */ - handle->base->TCD[handle->channel].CSR |= DMA_CSR_INTMAJOR_MASK; - - return kStatus_Success; - } - } - else /* Use the TCD queue. */ - { - uint32_t primask; - uint16_t csr; - int8_t currentTcd; - int8_t previousTcd; - int8_t nextTcd; - int8_t tmpTcdUsed; - int8_t tmpTcdSize; - - /* Check if tcd pool is full. */ - primask = DisableGlobalIRQ(); - tmpTcdUsed = handle->tcdUsed; - tmpTcdSize = handle->tcdSize; - if (tmpTcdUsed >= tmpTcdSize) - { - EnableGlobalIRQ(primask); - - return kStatus_EDMA_QueueFull; - } - currentTcd = handle->tail; - handle->tcdUsed++; - /* Calculate index of next TCD */ - nextTcd = currentTcd + 1; - if (nextTcd == handle->tcdSize) - { - nextTcd = 0; - } - /* Advance queue tail index */ - handle->tail = nextTcd; - EnableGlobalIRQ(primask); - /* Calculate index of previous TCD */ - previousTcd = currentTcd != 0 ? currentTcd - 1 : (handle->tcdSize - 1); - /* Configure current TCD block. */ - EDMA_TcdReset(&handle->tcdPool[currentTcd]); - EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL); - /* Enable major interrupt */ - handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK; - /* Link current TCD with next TCD for identification of current TCD */ - handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd]; - /* Chain from previous descriptor unless tcd pool size is 1(this descriptor is its own predecessor). */ - if (currentTcd != previousTcd) - { - /* Enable scatter/gather feature in the previous TCD block. */ - csr = handle->tcdPool[previousTcd].CSR | ((uint16_t)DMA_CSR_ESG_MASK); - csr &= ~((uint16_t)DMA_CSR_DREQ_MASK); - handle->tcdPool[previousTcd].CSR = csr; - /* - Check if the TCD block in the registers is the previous one (points to current TCD block). It - is used to check if the previous TCD linked has been loaded in TCD register. If so, it need to - link the TCD register in case link the current TCD with the dead chain when TCD loading occurs - before link the previous TCD block. - */ - if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd]) - { - /* Clear the DREQ bits for the dynamic scatter gather */ - tcdRegs->CSR |= DMA_CSR_DREQ_MASK; - /* Enable scatter/gather also in the TCD registers. */ - csr = tcdRegs->CSR | DMA_CSR_ESG_MASK; - /* Must write the CSR register one-time, because the transfer maybe finished anytime. */ - tcdRegs->CSR = csr; - /* - It is very important to check the ESG bit! - Because this hardware design: if DONE bit is set, the ESG bit can not be set. So it can - be used to check if the dynamic TCD link operation is successful. If ESG bit is not set - and the DLAST_SGA is not the next TCD address(it means the dynamic TCD link succeed and - the current TCD block has been loaded into TCD registers), it means transfer finished - and TCD link operation fail, so must install TCD content into TCD registers and enable - transfer again. And if ESG is set, it means transfer has not finished, so TCD dynamic - link succeed. - */ - if (0U != (tcdRegs->CSR & DMA_CSR_ESG_MASK)) - { - tcdRegs->CSR &= ~(uint16_t)DMA_CSR_DREQ_MASK; - return kStatus_Success; - } - /* - Check whether the current TCD block is already loaded in the TCD registers. It is another - condition when ESG bit is not set: it means the dynamic TCD link succeed and the current - TCD block has been loaded into TCD registers. - */ - if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd]) - { - return kStatus_Success; - } - /* - If go to this, means the previous transfer finished, and the DONE bit is set. - So shall configure TCD registers. - */ - } - else if (tcdRegs->DLAST_SGA != 0UL) - { - /* The current TCD block has been linked successfully. */ - return kStatus_Success; - } - else - { - /* - DLAST_SGA is 0 and it means the first submit transfer, so shall configure - TCD registers. - */ - } - } - /* There is no live chain, TCD block need to be installed in TCD registers. */ - EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]); - /* Enable channel request again. */ - if (0U != (handle->flags & EDMA_TRANSFER_ENABLED_MASK)) - { - handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); - } - - return kStatus_Success; - } -} - -/*! - * brief eDMA starts transfer. - * - * This function enables the channel request. Users can call this function after submitting the transfer request - * or before submitting the transfer request. - * - * param handle eDMA handle pointer. - */ -void EDMA_StartTransfer(edma_handle_t *handle) -{ - assert(handle != NULL); - uint32_t tmpCSR = 0; - - if (handle->tcdPool == NULL) - { - handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); - } - else /* Use the TCD queue. */ - { - uint32_t primask; - edma_tcd_t *tcdRegs = (edma_tcd_t *)(uint32_t)&handle->base->TCD[handle->channel]; - - handle->flags |= EDMA_TRANSFER_ENABLED_MASK; - - /* Check if there was at least one descriptor submitted since reset (TCD in registers is valid) */ - if (tcdRegs->DLAST_SGA != 0U) - { - primask = DisableGlobalIRQ(); - /* Check if channel request is actually disable. */ - if ((handle->base->ERQ & ((uint32_t)1U << handle->channel)) == 0U) - { - /* Check if transfer is paused. */ - tmpCSR = tcdRegs->CSR; - if ((0U == (tmpCSR & DMA_CSR_DONE_MASK)) || (0U != (tmpCSR & DMA_CSR_ESG_MASK))) - { - /* - Re-enable channel request must be as soon as possible, so must put it into - critical section to avoid task switching or interrupt service routine. - */ - handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); - } - } - EnableGlobalIRQ(primask); - } - } -} - -/*! - * brief eDMA stops transfer. - * - * This function disables the channel request to pause the transfer. Users can call EDMA_StartTransfer() - * again to resume the transfer. - * - * param handle eDMA handle pointer. - */ -void EDMA_StopTransfer(edma_handle_t *handle) -{ - assert(handle != NULL); - - handle->flags &= (~(uint8_t)EDMA_TRANSFER_ENABLED_MASK); - handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); -} - -/*! - * brief eDMA aborts transfer. - * - * This function disables the channel request and clear transfer status bits. - * Users can submit another transfer after calling this API. - * - * param handle DMA handle pointer. - */ -void EDMA_AbortTransfer(edma_handle_t *handle) -{ - handle->base->CERQ = DMA_CERQ_CERQ(handle->channel); - /* - Clear CSR to release channel. Because if the given channel started transfer, - CSR will be not zero. Because if it is the last transfer, DREQ will be set. - If not, ESG will be set. - */ - handle->base->TCD[handle->channel].CSR = 0; - /* Cancel all next TCD transfer. */ - handle->base->TCD[handle->channel].DLAST_SGA = 0; - - /* Handle the tcd */ - if (handle->tcdPool != NULL) - { - handle->header = 0; - handle->tail = 0; - handle->tcdUsed = 0; - } -} - -/*! - * brief eDMA IRQ handler for the current major loop transfer completion. - * - * This function clears the channel major interrupt flag and calls - * the callback function if it is not NULL. - * - * Note: - * For the case using TCD queue, when the major iteration count is exhausted, additional operations are performed. - * These include the final address adjustments and reloading of the BITER field into the CITER. - * Assertion of an optional interrupt request also occurs at this time, as does a possible fetch of a new TCD from - * memory using the scatter/gather address pointer included in the descriptor (if scatter/gather is enabled). - * - * For instance, when the time interrupt of TCD[0] happens, the TCD[1] has already been loaded into the eDMA engine. - * As sga and sga_index are calculated based on the DLAST_SGA bitfield lies in the TCD_CSR register, the sga_index - * in this case should be 2 (DLAST_SGA of TCD[1] stores the address of TCD[2]). Thus, the "tcdUsed" updated should be - * (tcdUsed - 2U) which indicates the number of TCDs can be loaded in the memory pool (because TCD[0] and TCD[1] have - * been loaded into the eDMA engine at this point already.). - * - * For the last two continuous ISRs in a scatter/gather process, they both load the last TCD (The last ISR does not - * load a new TCD) from the memory pool to the eDMA engine when major loop completes. - * Therefore, ensure that the header and tcdUsed updated are identical for them. - * tcdUsed are both 0 in this case as no TCD to be loaded. - * - * See the "eDMA basic data flow" in the eDMA Functional description section of the Reference Manual for - * further details. - * - * param handle eDMA handle pointer. - */ -void EDMA_HandleIRQ(edma_handle_t *handle) -{ - assert(handle != NULL); - - bool transfer_done; - - /* Clear EDMA interrupt flag */ - handle->base->CINT = handle->channel; - /* Check if transfer is already finished. */ - transfer_done = ((handle->base->TCD[handle->channel].CSR & DMA_CSR_DONE_MASK) != 0U); - - if (handle->tcdPool == NULL) - { - if (handle->callback != NULL) - { - (handle->callback)(handle, handle->userData, transfer_done, 0); - } - } - else /* Use the TCD queue. Please refer to the API descriptions in the eDMA header file for detailed information. */ - { - uint32_t sga = handle->base->TCD[handle->channel].DLAST_SGA; - uint32_t sga_index; - int32_t tcds_done; - uint8_t new_header; - - /* Get the offset of the next transfer TCD blocks to be loaded into the eDMA engine. */ - sga -= (uint32_t)handle->tcdPool; - /* Get the index of the next transfer TCD blocks to be loaded into the eDMA engine. */ - sga_index = sga / sizeof(edma_tcd_t); - /* Adjust header positions. */ - if (transfer_done) - { - /* New header shall point to the next TCD to be loaded (current one is already finished) */ - new_header = (uint8_t)sga_index; - } - else - { - /* New header shall point to this descriptor currently loaded (not finished yet) */ - new_header = sga_index != 0U ? (uint8_t)sga_index - 1U : (uint8_t)handle->tcdSize - 1U; - } - /* Calculate the number of finished TCDs */ - if (new_header == (uint8_t)handle->header) - { - int8_t tmpTcdUsed = handle->tcdUsed; - int8_t tmpTcdSize = handle->tcdSize; - - if (tmpTcdUsed == tmpTcdSize) - { - tcds_done = handle->tcdUsed; - } - else - { - /* No TCD in the memory are going to be loaded or internal error occurs. */ - tcds_done = 0; - } - } - else - { - tcds_done = (int32_t)new_header - (int32_t)handle->header; - if (tcds_done < 0) - { - tcds_done += handle->tcdSize; - } - } - /* Advance header which points to the TCD to be loaded into the eDMA engine from memory. */ - handle->header = (int8_t)new_header; - /* Release TCD blocks. tcdUsed is the TCD number which can be used/loaded in the memory pool. */ - handle->tcdUsed -= (int8_t)tcds_done; - /* Invoke callback function. */ - if (NULL != handle->callback) - { - (handle->callback)(handle, handle->userData, transfer_done, tcds_done); - } - - /* clear the DONE bit here is meaningful for below cases: - *1.A new TCD has been loaded to EDMA already: - * need to clear the DONE bit in the IRQ handler to avoid TCD in EDMA been overwritten - * if peripheral request isn't coming before next transfer request. - *2.A new TCD has not been loaded to EDMA: - * for the case that transfer request occur in the privious edma callback, this is a case that doesn't - * need scatter gather, so keep DONE bit during the next transfer request will re-install the TCD. - */ - if (transfer_done) - { - handle->base->CDNE = handle->channel; - } - } -} - -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \ - (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 4) -/* 8 channels (Shared): kl28 */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 8U) - -#if defined(DMA0) -void DMA0_04_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_15_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_37_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA1) - -#if defined(DMA0) -void DMA1_04_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[8]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[12]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_15_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[9]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[13]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[10]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[14]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_37_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[11]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[15]); - } - SDK_ISR_EXIT_BARRIER; -} - -#else -void DMA1_04_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_15_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_37_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif -#endif /* 8 channels (Shared) */ -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */ - -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \ - (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 8) -/* 16 channels (Shared): K32H844P */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 16U) - -void DMA0_08_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[8]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_19_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[9]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_210_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[10]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_311_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[11]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_412_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[12]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_513_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[13]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_614_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[14]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_715_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[15]); - } - SDK_ISR_EXIT_BARRIER; -} - -#if defined(DMA1) -void DMA1_08_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[16]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[24]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_19_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[17]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[25]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_210_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[18]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[26]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_311_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[19]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[27]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_412_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[20]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[28]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_513_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[21]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[29]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_614_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[22]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[30]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_715_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[23]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[31]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif /* 16 channels (Shared) */ -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */ - -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \ - (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 16) -/* 32 channels (Shared): k80 */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U -#if defined(DMA0) && !(defined(DMA1)) -void DMA0_DMA16_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[16]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_DMA17_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[17]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA2_DMA18_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[18]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA3_DMA19_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[19]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA4_DMA20_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[20]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA5_DMA21_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[21]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA6_DMA22_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[22]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA7_DMA23_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[23]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA8_DMA24_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[8]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[24]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA9_DMA25_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[9]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[25]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA10_DMA26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[10]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[26]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA11_DMA27_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[11]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[27]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA12_DMA28_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[12]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[28]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA13_DMA29_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[13]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[29]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA14_DMA30_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[14]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[30]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA15_DMA31_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[15]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[31]); - } - SDK_ISR_EXIT_BARRIER; -} - -#else -void DMA0_0_16_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[16]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_1_17_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[17]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_2_18_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[18]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_3_19_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[19]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_4_20_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[20]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_5_21_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[21]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_6_22_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[22]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_7_23_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[23]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_8_24_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[8]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[24]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_9_25_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[9]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[25]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_10_26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[10]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[26]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_11_27_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[11]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[27]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_12_28_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[12]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[28]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_13_29_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[13]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[29]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_14_30_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[14]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[30]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_15_31_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[15]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[31]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_0_16_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[32]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[48]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_1_17_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[33]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[49]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_2_18_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[34]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[50]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_3_19_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[35]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[51]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_4_20_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[36]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[52]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_5_21_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[37]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[53]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_6_22_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[38]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[54]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_7_23_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[39]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[55]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_8_24_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[40]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[56]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_9_25_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[41]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[57]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_10_26_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[42]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[58]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_11_27_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[43]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[59]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_12_28_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[44]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[60]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_13_29_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[45]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[61]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_14_30_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[46]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[62]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_15_31_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA1, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[47]); - } - if ((EDMA_GetChannelStatusFlags(DMA1, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[63]); - } - SDK_ISR_EXIT_BARRIER; -} - -#endif -#endif /* 32 channels (Shared) */ -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */ - -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \ - (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 4) -/* 32 channels (Shared): MCIMX7U5_M4 */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL == 32U) - -void DMA0_0_4_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 0U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[0]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 4U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[4]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_1_5_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 1U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[1]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 5U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[5]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_2_6_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 2U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[2]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 6U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[6]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_3_7_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 3U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[3]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 7U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[7]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_8_12_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 8U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[8]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 12U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[12]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_9_13_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 9U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[9]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 13U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[13]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_10_14_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 10U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[10]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 14U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[14]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_11_15_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 11U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[11]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 15U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[15]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_16_20_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 16U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[16]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 20U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[20]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_17_21_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 17U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[17]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 21U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[21]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_18_22_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 18U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[18]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 22U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[22]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_19_23_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 19U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[19]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 23U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[23]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_24_28_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 24U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[24]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 28U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[28]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_25_29_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 25U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[25]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 29U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[29]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_26_30_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 26U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[26]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 30U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[30]); - } - SDK_ISR_EXIT_BARRIER; -} - -void DMA0_27_31_DriverIRQHandler(void) -{ - if ((EDMA_GetChannelStatusFlags(DMA0, 27U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[27]); - } - if ((EDMA_GetChannelStatusFlags(DMA0, 31U) & (uint32_t)kEDMA_InterruptFlag) != 0U) - { - EDMA_HandleIRQ(s_EDMAHandle[31]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* 32 channels (Shared): MCIMX7U5 */ -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */ - -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET) && \ - (FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET == 0) -/* 4 channels (No Shared): kv10 */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 0) - -void DMA0_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[0]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA1_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[1]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA2_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[2]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA3_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[3]); - SDK_ISR_EXIT_BARRIER; -} - -/* 8 channels (No Shared) */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 4U) - -void DMA4_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[4]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA5_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[5]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA6_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[6]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA7_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[7]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 8 */ - -/* 16 channels (No Shared) */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 8U) - -void DMA8_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[8]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA9_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[9]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA10_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[10]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA11_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[11]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA12_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[12]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA13_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[13]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA14_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[14]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA15_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[15]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 16 */ - -/* 32 channels (No Shared) */ -#if defined(FSL_FEATURE_EDMA_MODULE_CHANNEL) && (FSL_FEATURE_EDMA_MODULE_CHANNEL > 16U) - -void DMA16_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[16]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA17_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[17]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA18_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[18]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA19_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[19]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA20_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[20]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA21_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[21]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA22_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[22]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA23_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[23]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA24_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[24]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA25_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[25]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA26_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[26]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA27_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[27]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA28_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[28]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA29_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[29]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA30_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[30]); - SDK_ISR_EXIT_BARRIER; -} - -void DMA31_DriverIRQHandler(void) -{ - EDMA_HandleIRQ(s_EDMAHandle[31]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL == 32 */ - -#endif /* 4/8/16/32 channels (No Shared) */ -#endif /* FSL_FEATURE_EDMA_MODULE_CHANNEL_IRQ_ENTRY_SHARED_OFFSET */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c deleted file mode 100644 index ab9f63f912..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_elcdif.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_elcdif.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.elcdif" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get instance number for ELCDIF module. - * - * @param base ELCDIF peripheral base address - */ -static uint32_t ELCDIF_GetInstance(LCDIF_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*! @brief Pointers to ELCDIF bases for each instance. */ -static LCDIF_Type *const s_elcdifBases[] = LCDIF_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to eLCDIF apb_clk for each instance. */ -static const clock_ip_name_t s_elcdifApbClocks[] = LCDIF_CLOCKS; -#if defined(LCDIF_PERIPH_CLOCKS) -/*! @brief Pointers to eLCDIF pix_clk for each instance. */ -static const clock_ip_name_t s_elcdifPixClocks[] = LCDIF_PERIPH_CLOCKS; -#endif -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief The control register value to select different pixel format. */ -static const elcdif_pixel_format_reg_t s_pixelFormatReg[] = { - /* kELCDIF_PixelFormatRAW8 */ - {/* Register CTRL. */ - LCDIF_CTRL_WORD_LENGTH(1U), - /* Register CTRL1. */ - LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, - /* kELCDIF_PixelFormatRGB565 */ - {/* Register CTRL. */ - LCDIF_CTRL_WORD_LENGTH(0U), - /* Register CTRL1. */ - LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, - /* kELCDIF_PixelFormatRGB666 */ - {/* Register CTRL. */ - LCDIF_CTRL_WORD_LENGTH(3U) | LCDIF_CTRL_DATA_FORMAT_24_BIT(1U), - /* Register CTRL1. */ - LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)}, - /* kELCDIF_PixelFormatXRGB8888 */ - {/* Register CTRL. 24-bit. */ - LCDIF_CTRL_WORD_LENGTH(3U), - /* Register CTRL1. */ - LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x07U)}, - /* kELCDIF_PixelFormatRGB888 */ - {/* Register CTRL. 24-bit. */ - LCDIF_CTRL_WORD_LENGTH(3U), - /* Register CTRL1. */ - LCDIF_CTRL1_BYTE_PACKING_FORMAT(0x0FU)}, -}; - -/******************************************************************************* - * Codes - ******************************************************************************/ -static uint32_t ELCDIF_GetInstance(LCDIF_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_elcdifBases); instance++) - { - if (s_elcdifBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_elcdifBases)); - - return instance; -} - -/*! - * brief Initializes the eLCDIF to work in RGB mode (DOTCLK mode). - * - * This function ungates the eLCDIF clock and configures the eLCDIF peripheral according - * to the configuration structure. - * - * param base eLCDIF peripheral base address. - * param config Pointer to the configuration structure. - */ -void ELCDIF_RgbModeInit(LCDIF_Type *base, const elcdif_rgb_mode_config_t *config) -{ - assert(NULL != config); - assert((uint32_t)config->pixelFormat < ARRAY_SIZE(s_pixelFormatReg)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = ELCDIF_GetInstance(base); - /* Enable the clock. */ - CLOCK_EnableClock(s_elcdifApbClocks[instance]); -#if defined(LCDIF_PERIPH_CLOCKS) - CLOCK_EnableClock(s_elcdifPixClocks[instance]); -#endif -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Reset. */ - ELCDIF_Reset(base); - - base->CTRL = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl | (uint32_t)(config->dataBus) | - LCDIF_CTRL_DOTCLK_MODE_MASK | /* RGB mode. */ - LCDIF_CTRL_BYPASS_COUNT_MASK | /* Keep RUN bit set. */ - LCDIF_CTRL_MASTER_MASK; - - base->CTRL1 = s_pixelFormatReg[(uint32_t)config->pixelFormat].regCtrl1; - - base->TRANSFER_COUNT = ((uint32_t)config->panelHeight << LCDIF_TRANSFER_COUNT_V_COUNT_SHIFT) | - ((uint32_t)config->panelWidth << LCDIF_TRANSFER_COUNT_H_COUNT_SHIFT); - - base->VDCTRL0 = LCDIF_VDCTRL0_ENABLE_PRESENT_MASK | /* Data enable signal. */ - LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT_MASK | /* VSYNC period in the unit of display clock. */ - LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT_MASK | /* VSYNC pulse width in the unit of display clock. */ - (uint32_t)config->polarityFlags | (uint32_t)config->vsw; - - base->VDCTRL1 = - (uint32_t)config->vsw + (uint32_t)config->panelHeight + (uint32_t)config->vfp + (uint32_t)config->vbp; - base->VDCTRL2 = - ((uint32_t)config->hsw << LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH_SHIFT) | - (((uint32_t)config->hfp + (uint32_t)config->hbp + (uint32_t)config->panelWidth + (uint32_t)config->hsw)) - << LCDIF_VDCTRL2_HSYNC_PERIOD_SHIFT; - - base->VDCTRL3 = (((uint32_t)config->hbp + config->hsw) << LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT_SHIFT) | - (((uint32_t)config->vbp + config->vsw) << LCDIF_VDCTRL3_VERTICAL_WAIT_CNT_SHIFT); - - base->VDCTRL4 = LCDIF_VDCTRL4_SYNC_SIGNALS_ON_MASK | - ((uint32_t)config->panelWidth << LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT_SHIFT); - - base->CUR_BUF = config->bufferAddr; - base->NEXT_BUF = config->bufferAddr; -} - -/*! - * brief Gets the eLCDIF default configuration structure for RGB (DOTCLK) mode. - * - * This function sets the configuration structure to default values. - * The default configuration is set to the following values. - * code - config->panelWidth = 480U; - config->panelHeight = 272U; - config->hsw = 41; - config->hfp = 4; - config->hbp = 8; - config->vsw = 10; - config->vfp = 4; - config->vbp = 2; - config->polarityFlags = kELCDIF_VsyncActiveLow | - kELCDIF_HsyncActiveLow | - kELCDIF_DataEnableActiveLow | - kELCDIF_DriveDataOnFallingClkEdge; - config->bufferAddr = 0U; - config->pixelFormat = kELCDIF_PixelFormatRGB888; - config->dataBus = kELCDIF_DataBus24Bit; - code - * - * param config Pointer to the eLCDIF configuration structure. - */ -void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->panelWidth = 480U; - config->panelHeight = 272U; - config->hsw = 41; - config->hfp = 4; - config->hbp = 8; - config->vsw = 10; - config->vfp = 4; - config->vbp = 2; - config->polarityFlags = (uint32_t)kELCDIF_VsyncActiveLow | (uint32_t)kELCDIF_HsyncActiveLow | - (uint32_t)kELCDIF_DataEnableActiveLow | (uint32_t)kELCDIF_DriveDataOnFallingClkEdge; - config->bufferAddr = 0U; - config->pixelFormat = kELCDIF_PixelFormatRGB888; - config->dataBus = kELCDIF_DataBus24Bit; -} - -/*! - * brief Set the pixel format in RGB (DOTCLK) mode. - * - * param base eLCDIF peripheral base address. - * param pixelFormat The pixel format. - */ -void ELCDIF_RgbModeSetPixelFormat(LCDIF_Type *base, elcdif_pixel_format_t pixelFormat) -{ - assert((uint32_t)pixelFormat < ARRAY_SIZE(s_pixelFormatReg)); - - base->CTRL = (base->CTRL & ~(LCDIF_CTRL_WORD_LENGTH_MASK | LCDIF_CTRL_DATA_FORMAT_24_BIT_MASK | - LCDIF_CTRL_DATA_FORMAT_18_BIT_MASK | LCDIF_CTRL_DATA_FORMAT_16_BIT_MASK)) | - s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl; - - base->CTRL1 = s_pixelFormatReg[(uint32_t)pixelFormat].regCtrl1; -} - -/*! - * brief Deinitializes the eLCDIF peripheral. - * - * param base eLCDIF peripheral base address. - */ -void ELCDIF_Deinit(LCDIF_Type *base) -{ - ELCDIF_Reset(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = ELCDIF_GetInstance(base); -/* Disable the clock. */ -#if defined(LCDIF_PERIPH_CLOCKS) - CLOCK_DisableClock(s_elcdifPixClocks[instance]); -#endif - CLOCK_DisableClock(s_elcdifApbClocks[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Stop display in RGB (DOTCLK) mode and wait until finished. - * - * param base eLCDIF peripheral base address. - */ -void ELCDIF_RgbModeStop(LCDIF_Type *base) -{ - base->CTRL_CLR = LCDIF_CTRL_DOTCLK_MODE_MASK; - - /* Wait for data transfer finished. */ - while (0U != (base->CTRL & LCDIF_CTRL_DOTCLK_MODE_MASK)) - { - } -} - -/*! - * brief Reset the eLCDIF peripheral. - * - * param base eLCDIF peripheral base address. - */ -void ELCDIF_Reset(LCDIF_Type *base) -{ - /* - * ELCDIF reset workflow: - * - * 1. Ungate clock. - * 2. Trigger the software reset. - * 3. The software reset finished when clk_gate bit is set. - * 4. Ungate the clock. - * 5. Release the reset. - */ - - /* Ungate clock. */ - base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK; - - /* - * If already in reset state, release the reset. - * If not, trigger reset. - */ - if (0U == (base->CTRL & LCDIF_CTRL_SFTRST_MASK)) - { - /* Trigger reset. */ - base->CTRL_SET = LCDIF_CTRL_SFTRST_MASK; - - /* Reset is not finished until CLK_GATE is set. */ - while (0U == (base->CTRL & LCDIF_CTRL_CLKGATE_MASK)) - { - } - - /* Ungate the clock. */ - base->CTRL_CLR = LCDIF_CTRL_CLKGATE_MASK; - } - - /* Release the reset. */ - base->CTRL_CLR = LCDIF_CTRL_SFTRST_MASK; -} - -#if !(defined(FSL_FEATURE_LCDIF_HAS_NO_AS) && FSL_FEATURE_LCDIF_HAS_NO_AS) -/*! - * brief Set the configuration for alpha surface buffer. - * - * param base eLCDIF peripheral base address. - * param config Pointer to the configuration structure. - */ -void ELCDIF_SetAlphaSurfaceBufferConfig(LCDIF_Type *base, const elcdif_as_buffer_config_t *config) -{ - assert(NULL != config); - - base->AS_CTRL = (base->AS_CTRL & ~LCDIF_AS_CTRL_FORMAT_MASK) | LCDIF_AS_CTRL_FORMAT(config->pixelFormat); - base->AS_BUF = config->bufferAddr; - base->AS_NEXT_BUF = config->bufferAddr; -} - -/*! - * brief Set the alpha surface blending configuration. - * - * param base eLCDIF peripheral base address. - * param config Pointer to the configuration structure. - */ -void ELCDIF_SetAlphaSurfaceBlendConfig(LCDIF_Type *base, const elcdif_as_blend_config_t *config) -{ - assert(NULL != config); - uint32_t reg; - - reg = base->AS_CTRL; - reg &= ~(LCDIF_AS_CTRL_ALPHA_INVERT_MASK | LCDIF_AS_CTRL_ROP_MASK | LCDIF_AS_CTRL_ALPHA_MASK | - LCDIF_AS_CTRL_ALPHA_CTRL_MASK); - reg |= (LCDIF_AS_CTRL_ROP(config->ropMode) | LCDIF_AS_CTRL_ALPHA(config->alpha) | - LCDIF_AS_CTRL_ALPHA_CTRL(config->alphaMode)); - - if (config->invertAlpha) - { - reg |= LCDIF_AS_CTRL_ALPHA_INVERT_MASK; - } - - base->AS_CTRL = reg; -} -#endif /* FSL_FEATURE_LCDIF_HAS_NO_AS */ - -#if (defined(FSL_FEATURE_LCDIF_HAS_LUT) && FSL_FEATURE_LCDIF_HAS_LUT) -/*! - * brief Load the LUT value. - * - * This function loads the LUT value to the specific LUT memory, user can - * specify the start entry index. - * - * param base eLCDIF peripheral base address. - * param lut Which LUT to load. - * param startIndex The start index of the LUT entry to update. - * param lutData The LUT data to load. - * param count Count of p lutData. - * retval kStatus_Success Initialization success. - * retval kStatus_InvalidArgument Wrong argument. - */ -status_t ELCDIF_UpdateLut( - LCDIF_Type *base, elcdif_lut_t lut, uint16_t startIndex, const uint32_t *lutData, uint16_t count) -{ - volatile uint32_t *regLutAddr; - volatile uint32_t *regLutData; - uint32_t i; - status_t status; - - /* Only has 256 entries. */ - if (startIndex + count > ELCDIF_LUT_ENTRY_NUM) - { - status = kStatus_InvalidArgument; - } - else - { - if (kELCDIF_Lut0 == lut) - { - regLutAddr = &(base->LUT0_ADDR); - regLutData = &(base->LUT0_DATA); - } - else - { - regLutAddr = &(base->LUT1_ADDR); - regLutData = &(base->LUT1_DATA); - } - - *regLutAddr = startIndex; - - for (i = 0; i < count; i++) - { - *regLutData = lutData[i]; - } - - status = kStatus_Success; - } - - return status; -} -#endif /* FSL_FEATURE_LCDIF_HAS_LUT */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c deleted file mode 100644 index 8117df1332..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enc.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_enc.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.enc" -#endif - -#define ENC_CTRL_W1C_FLAGS (ENC_CTRL_HIRQ_MASK | ENC_CTRL_XIRQ_MASK | ENC_CTRL_DIRQ_MASK | ENC_CTRL_CMPIRQ_MASK) -#define ENC_CTRL2_W1C_FLAGS (ENC_CTRL2_SABIRQ_MASK | ENC_CTRL2_ROIRQ_MASK | ENC_CTRL2_RUIRQ_MASK) - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for ENC module. - * - * @param base ENC peripheral base address - */ -static uint32_t ENC_GetInstance(ENC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to ENC bases for each instance. */ -static ENC_Type *const s_encBases[] = ENC_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to ENC clocks for each instance. */ -static const clock_ip_name_t s_encClocks[] = ENC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t ENC_GetInstance(ENC_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_encBases); instance++) - { - if (s_encBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_encBases)); - - return instance; -} - -/*! - * brief Initialization for the ENC module. - * - * This function is to make the initialization for the ENC module. It should be called firstly before any operation to - * the ENC with the operations like: - * - Enable the clock for ENC module. - * - Configure the ENC's working attributes. - * - * param base ENC peripheral base address. - * param config Pointer to configuration structure. See to "enc_config_t". - */ -void ENC_Init(ENC_Type *base, const enc_config_t *config) -{ - assert(NULL != config); - - uint16_t tmp16; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock. */ - CLOCK_EnableClock(s_encClocks[ENC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* ENC_CTRL. */ - tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_HIP_MASK | ENC_CTRL_HNE_MASK | ENC_CTRL_REV_MASK | - ENC_CTRL_PH1_MASK | ENC_CTRL_XIP_MASK | ENC_CTRL_XNE_MASK | ENC_CTRL_WDE_MASK)); - /* For HOME trigger. */ - if (kENC_HOMETriggerDisabled != config->HOMETriggerMode) - { - tmp16 |= ENC_CTRL_HIP_MASK; - if (kENC_HOMETriggerOnFallingEdge == config->HOMETriggerMode) - { - tmp16 |= ENC_CTRL_HNE_MASK; - } - } - /* For encoder work mode. */ - if (config->enableReverseDirection) - { - tmp16 |= ENC_CTRL_REV_MASK; - } - if (kENC_DecoderWorkAsSignalPhaseCountMode == config->decoderWorkMode) - { - tmp16 |= ENC_CTRL_PH1_MASK; - } - /* For INDEX trigger. */ - if (kENC_INDEXTriggerDisabled != config->INDEXTriggerMode) - { - tmp16 |= ENC_CTRL_XIP_MASK; - if (kENC_INDEXTriggerOnFallingEdge == config->INDEXTriggerMode) - { - tmp16 |= ENC_CTRL_XNE_MASK; - } - } - /* Watchdog. */ - if (config->enableWatchdog) - { - tmp16 |= ENC_CTRL_WDE_MASK; - base->WTR = config->watchdogTimeoutValue; /* WDOG can be only available when the feature is enabled. */ - } - base->CTRL = tmp16; - - /* ENC_FILT. */ - base->FILT = ENC_FILT_FILT_CNT(config->filterCount) | ENC_FILT_FILT_PER(config->filterSamplePeriod); - - /* ENC_CTRL2. */ - tmp16 = base->CTRL2 & (uint16_t)(~(ENC_CTRL2_W1C_FLAGS | ENC_CTRL2_OUTCTL_MASK | ENC_CTRL2_REVMOD_MASK | - ENC_CTRL2_MOD_MASK | ENC_CTRL2_UPDPOS_MASK | ENC_CTRL2_UPDHLD_MASK)); - if (kENC_POSMATCHOnReadingAnyPositionCounter == config->positionMatchMode) - { - tmp16 |= ENC_CTRL2_OUTCTL_MASK; - } - if (kENC_RevolutionCountOnRollOverModulus == config->revolutionCountCondition) - { - tmp16 |= ENC_CTRL2_REVMOD_MASK; - } - if (config->enableModuloCountMode) - { - tmp16 |= ENC_CTRL2_MOD_MASK; - /* Set modulus value. */ - base->UMOD = (uint16_t)(config->positionModulusValue >> 16U); /* Upper 16 bits. */ - base->LMOD = (uint16_t)(config->positionModulusValue); /* Lower 16 bits. */ - } - if (config->enableTRIGGERClearPositionCounter) - { - tmp16 |= ENC_CTRL2_UPDPOS_MASK; - } - if (config->enableTRIGGERClearHoldPositionCounter) - { - tmp16 |= ENC_CTRL2_UPDHLD_MASK; - } - base->CTRL2 = tmp16; - - /* ENC_UCOMP & ENC_LCOMP. */ - base->UCOMP = (uint16_t)(config->positionCompareValue >> 16U); /* Upper 16 bits. */ - base->LCOMP = (uint16_t)(config->positionCompareValue); /* Lower 16 bits. */ - - /* ENC_UINIT & ENC_LINIT. */ - base->UINIT = (uint16_t)(config->positionInitialValue >> 16U); /* Upper 16 bits. */ - base->LINIT = (uint16_t)(config->positionInitialValue); /* Lower 16 bits. */ -} - -/*! - * brief De-initialization for the ENC module. - * - * This function is to make the de-initialization for the ENC module. It could be called when ENC is no longer used with - * the operations like: - * - Disable the clock for ENC module. - * - * param base ENC peripheral base address. - */ -void ENC_Deinit(ENC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the clock. */ - CLOCK_DisableClock(s_encClocks[ENC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Get an available pre-defined settings for ENC's configuration. - * - * This function initializes the ENC configuration structure with an available settings, the default value are: - * code - * config->enableReverseDirection = false; - * config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; - * config->HOMETriggerMode = kENC_HOMETriggerDisabled; - * config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; - * config->enableTRIGGERClearPositionCounter = false; - * config->enableTRIGGERClearHoldPositionCounter = false; - * config->enableWatchdog = false; - * config->watchdogTimeoutValue = 0U; - * config->filterCount = 0U; - * config->filterSamplePeriod = 0U; - * config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; - * config->positionCompareValue = 0xFFFFFFFFU; - * config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; - * config->enableModuloCountMode = false; - * config->positionModulusValue = 0U; - * config->positionInitialValue = 0U; - * endcode - * param config Pointer to a variable of configuration structure. See to "enc_config_t". - */ -void ENC_GetDefaultConfig(enc_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableReverseDirection = false; - config->decoderWorkMode = kENC_DecoderWorkAsNormalMode; - config->HOMETriggerMode = kENC_HOMETriggerDisabled; - config->INDEXTriggerMode = kENC_INDEXTriggerDisabled; - config->enableTRIGGERClearPositionCounter = false; - config->enableTRIGGERClearHoldPositionCounter = false; - config->enableWatchdog = false; - config->watchdogTimeoutValue = 0U; - config->filterCount = 0U; - config->filterSamplePeriod = 0U; - config->positionMatchMode = kENC_POSMATCHOnPositionCounterEqualToComapreValue; - config->positionCompareValue = 0xFFFFFFFFU; - config->revolutionCountCondition = kENC_RevolutionCountOnINDEXPulse; - config->enableModuloCountMode = false; - config->positionModulusValue = 0U; - config->positionInitialValue = 0U; -} - -/*! - * brief Load the initial position value to position counter. - * - * This function is to transfer the initial position value (UINIT and LINIT) contents to position counter (UPOS and - * LPOS), so that to provide the consistent operation the position counter registers. - * - * param base ENC peripheral base address. - */ -void ENC_DoSoftwareLoadInitialPositionValue(ENC_Type *base) -{ - uint16_t tmp16 = base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS); - - tmp16 |= ENC_CTRL_SWIP_MASK; /* Write 1 to trigger the command for loading initial position value. */ - base->CTRL = tmp16; -} - -/*! - * brief Enable and configure the self test function. - * - * This function is to enable and configuration the self test function. It controls and sets the frequency of a - * quadrature signal generator. It provides a quadrature test signal to the inputs of the quadrature decoder module. - * It is a factory test feature; however, it may be useful to customers' software development and testing. - * - * param base ENC peripheral base address. - * param config Pointer to configuration structure. See to "enc_self_test_config_t". Pass "NULL" to disable. - */ -void ENC_SetSelfTestConfig(ENC_Type *base, const enc_self_test_config_t *config) -{ - uint16_t tmp16 = 0U; - - if (NULL == config) /* Pass "NULL" to disable the feature. */ - { - tmp16 = 0U; - } - else - { - tmp16 = ENC_TST_TEN_MASK | ENC_TST_TCE_MASK | ENC_TST_TEST_PERIOD(config->signalPeriod) | - ENC_TST_TEST_COUNT(config->signalCount); - if (kENC_SelfTestDirectionNegative == config->signalDirection) - { - tmp16 |= ENC_TST_QDN_MASK; - } - } - - base->TST = tmp16; -} - -/*! - * brief Enable watchdog for ENC module. - * - * param base ENC peripheral base address - * param enable Enables or disables the watchdog - */ -void ENC_EnableWatchdog(ENC_Type *base, bool enable) -{ - uint16_t tmp16 = base->CTRL & (uint16_t)(~(ENC_CTRL_W1C_FLAGS | ENC_CTRL_WDE_MASK)); - - if (enable) - { - tmp16 |= ENC_CTRL_WDE_MASK; - } - base->CTRL = tmp16; -} - -/*! - * brief Get the status flags. - * - * param base ENC peripheral base address. - * - * return Mask value of status flags. For available mask, see to "_enc_status_flags". - */ -uint32_t ENC_GetStatusFlags(ENC_Type *base) -{ - uint32_t ret32 = 0U; - - /* ENC_CTRL. */ - if (0U != (ENC_CTRL_HIRQ_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_HOMETransitionFlag; - } - if (0U != (ENC_CTRL_XIRQ_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_INDEXPulseFlag; - } - if (0U != (ENC_CTRL_DIRQ_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_WatchdogTimeoutFlag; - } - if (0U != (ENC_CTRL_CMPIRQ_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_PositionCompareFlag; - } - - /* ENC_CTRL2. */ - if (0U != (ENC_CTRL2_SABIRQ_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_SimultBothPhaseChangeFlag; - } - if (0U != (ENC_CTRL2_ROIRQ_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_PositionRollOverFlag; - } - if (0U != (ENC_CTRL2_RUIRQ_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_PositionRollUnderFlag; - } - if (0U != (ENC_CTRL2_DIR_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_LastCountDirectionFlag; - } - - return ret32; -} - -/*! - * brief Clear the status flags. - * - * param base ENC peripheral base address. - * param mask Mask value of status flags to be cleared. For available mask, see to "_enc_status_flags". - */ -void ENC_ClearStatusFlags(ENC_Type *base, uint32_t mask) -{ - uint32_t tmp16 = 0U; - - /* ENC_CTRL. */ - if (0U != ((uint32_t)kENC_HOMETransitionFlag & mask)) - { - tmp16 |= ENC_CTRL_HIRQ_MASK; - } - if (0U != ((uint32_t)kENC_INDEXPulseFlag & mask)) - { - tmp16 |= ENC_CTRL_XIRQ_MASK; - } - if (0U != ((uint32_t)kENC_WatchdogTimeoutFlag & mask)) - { - tmp16 |= ENC_CTRL_DIRQ_MASK; - } - if (0U != ((uint32_t)kENC_PositionCompareFlag & mask)) - { - tmp16 |= ENC_CTRL_CMPIRQ_MASK; - } - if (0U != tmp16) - { - base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); - } - - /* ENC_CTRL2. */ - tmp16 = 0U; - if (0U != ((uint32_t)kENC_SimultBothPhaseChangeFlag & mask)) - { - tmp16 |= ENC_CTRL2_SABIRQ_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollOverFlag & mask)) - { - tmp16 |= ENC_CTRL2_ROIRQ_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollUnderFlag & mask)) - { - tmp16 |= ENC_CTRL2_RUIRQ_MASK; - } - if (0U != tmp16) - { - base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); - } -} - -/*! - * brief Enable the interrupts. - * - * param base ENC peripheral base address. - * param mask Mask value of interrupts to be enabled. For available mask, see to "_enc_interrupt_enable". - */ -void ENC_EnableInterrupts(ENC_Type *base, uint32_t mask) -{ - uint32_t tmp16 = 0U; - - /* ENC_CTRL. */ - if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_HIE_MASK; - } - if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_XIE_MASK; - } - if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_DIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) - { - tmp16 |= ENC_CTRL_CMPIE_MASK; - } - if (tmp16 != 0U) - { - base->CTRL = (uint16_t)(((uint32_t)base->CTRL & (~ENC_CTRL_W1C_FLAGS)) | tmp16); - } - /* ENC_CTRL2. */ - tmp16 = 0U; - if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_SABIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_ROIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_RUIE_MASK; - } - if (tmp16 != 0U) - { - base->CTRL2 = (uint16_t)(((uint32_t)base->CTRL2 & (~ENC_CTRL2_W1C_FLAGS)) | tmp16); - } -} - -/*! - * brief Disable the interrupts. - * - * param base ENC peripheral base address. - * param mask Mask value of interrupts to be disabled. For available mask, see to "_enc_interrupt_enable". - */ -void ENC_DisableInterrupts(ENC_Type *base, uint32_t mask) -{ - uint16_t tmp16 = 0U; - - /* ENC_CTRL. */ - if (0U != ((uint32_t)kENC_HOMETransitionInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_HIE_MASK; - } - if (0U != ((uint32_t)kENC_INDEXPulseInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_XIE_MASK; - } - if (0U != ((uint32_t)kENC_WatchdogTimeoutInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL_DIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionCompareInerruptEnable & mask)) - { - tmp16 |= ENC_CTRL_CMPIE_MASK; - } - if (0U != tmp16) - { - base->CTRL = (uint16_t)(base->CTRL & (uint16_t)(~ENC_CTRL_W1C_FLAGS)) & (uint16_t)(~tmp16); - } - /* ENC_CTRL2. */ - tmp16 = 0U; - if (0U != ((uint32_t)kENC_SimultBothPhaseChangeInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_SABIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollOverInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_ROIE_MASK; - } - if (0U != ((uint32_t)kENC_PositionRollUnderInterruptEnable & mask)) - { - tmp16 |= ENC_CTRL2_RUIE_MASK; - } - if (tmp16 != 0U) - { - base->CTRL2 = (uint16_t)(base->CTRL2 & (uint16_t)(~ENC_CTRL2_W1C_FLAGS)) & (uint16_t)(~tmp16); - } -} - -/*! - * brief Get the enabled interrupts' flags. - * - * param base ENC peripheral base address. - * - * return Mask value of enabled interrupts. - */ -uint32_t ENC_GetEnabledInterrupts(ENC_Type *base) -{ - uint32_t ret32 = 0U; - - /* ENC_CTRL. */ - if (0U != (ENC_CTRL_HIE_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_HOMETransitionInterruptEnable; - } - if (0U != (ENC_CTRL_XIE_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_INDEXPulseInterruptEnable; - } - if (0U != (ENC_CTRL_DIE_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_WatchdogTimeoutInterruptEnable; - } - if (0U != (ENC_CTRL_CMPIE_MASK & base->CTRL)) - { - ret32 |= (uint32_t)kENC_PositionCompareInerruptEnable; - } - /* ENC_CTRL2. */ - if (0U != (ENC_CTRL2_SABIE_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_SimultBothPhaseChangeInterruptEnable; - } - if (0U != (ENC_CTRL2_ROIE_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_PositionRollOverInterruptEnable; - } - if (0U != (ENC_CTRL2_RUIE_MASK & base->CTRL2)) - { - ret32 |= (uint32_t)kENC_PositionRollUnderInterruptEnable; - } - return ret32; -} - -/*! - * brief Set initial position value for ENC module. - * - * param base ENC peripheral base address - * param value Positive initial value - */ -void ENC_SetInitialPositionValue(ENC_Type *base, uint32_t value) -{ - base->UINIT = (uint16_t)(value >> 16U); /* Set upper 16 bits. */ - base->LINIT = (uint16_t)(value); /* Set lower 16 bits. */ -} - -/*! - * brief Get the current position counter's value. - * - * param base ENC peripheral base address. - * - * return Current position counter's value. - */ -uint32_t ENC_GetPositionValue(ENC_Type *base) -{ - uint32_t ret32; - - ret32 = base->UPOS; /* Get upper 16 bits and make a snapshot. */ - ret32 <<= 16U; - ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ - - return ret32; -} - -/*! - * brief Get the hold position counter's value. - * - * When any of the counter registers is read, the contents of each counter register is written to the corresponding hold - * register. Taking a snapshot of the counters' values provides a consistent view of a system position and a velocity to - * be attained. - * - * param base ENC peripheral base address. - * - * return Hold position counter's value. - */ -uint32_t ENC_GetHoldPositionValue(ENC_Type *base) -{ - uint32_t ret32; - - ret32 = base->UPOSH; /* Get upper 16 bits and make a snapshot. */ - ret32 <<= 16U; - ret32 |= base->LPOSH; /* Get lower 16 bits from hold register. */ - - return ret32; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c deleted file mode 100644 index 2e9d229a18..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_enet.c +++ /dev/null @@ -1,3389 +0,0 @@ -/* - * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_enet.h" -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL -#include "fsl_cache.h" -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.enet" -#endif - -/*! @brief Ethernet mac address length. */ -#define ENET_FRAME_MACLEN 6U -/*! @brief Ethernet VLAN header length. */ -#define ENET_FRAME_VLAN_TAGLEN 4U -/*! @brief MDC frequency. */ -#define ENET_MDC_FREQUENCY 2500000U -/*! @brief NanoSecond in one second. */ -#define ENET_NANOSECOND_ONE_SECOND 1000000000U -/*! @brief Define a common clock cycle delays used for time stamp capture. */ -#ifndef ENET_1588TIME_DELAY_COUNT -#define ENET_1588TIME_DELAY_COUNT 10U -#endif - -/*! @brief Define the ENET ring/class bumber . */ -enum -{ - kENET_Ring0 = 0U, /*!< ENET ring/class 0. */ -#if FSL_FEATURE_ENET_QUEUE > 1 - kENET_Ring1 = 1U, /*!< ENET ring/class 1. */ - kENET_Ring2 = 2U /*!< ENET ring/class 2. */ -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ -}; - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*! @brief Pointers to enet clocks for each instance. */ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -const clock_ip_name_t s_enetClock[] = ENET_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Pointers to enet transmit IRQ number for each instance. */ -static const IRQn_Type s_enetTxIrqId[] = ENET_Transmit_IRQS; -/*! @brief Pointers to enet receive IRQ number for each instance. */ -static const IRQn_Type s_enetRxIrqId[] = ENET_Receive_IRQS; -#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE -/*! @brief Pointers to enet timestamp IRQ number for each instance. */ -static const IRQn_Type s_enetTsIrqId[] = ENET_1588_Timer_IRQS; -#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G) -/*! @brief Pointers to enet 1588 timestamp IRQ number for each instance. */ -static const IRQn_Type s_enet1588TimerIrqId[] = ENET_1588_Timer_IRQS; -#endif -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ -/*! @brief Pointers to enet error IRQ number for each instance. */ -static const IRQn_Type s_enetErrIrqId[] = ENET_Error_IRQS; - -/*! @brief Pointers to enet bases for each instance. */ -static ENET_Type *const s_enetBases[] = ENET_BASE_PTRS; - -/*! @brief Pointers to enet handles for each instance. */ -static enet_handle_t *s_ENETHandle[ARRAY_SIZE(s_enetBases)]; - -/* ENET ISR for transactional APIs. */ -#if FSL_FEATURE_ENET_QUEUE > 1 -static enet_isr_ring_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)]; -static enet_isr_ring_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)]; -#else -static enet_isr_t s_enetTxIsr[ARRAY_SIZE(s_enetBases)]; -static enet_isr_t s_enetRxIsr[ARRAY_SIZE(s_enetBases)]; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ -static enet_isr_t s_enetErrIsr[ARRAY_SIZE(s_enetBases)]; -static enet_isr_t s_enetTsIsr[ARRAY_SIZE(s_enetBases)]; -#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G) -static enet_isr_t s_enet1588TimerIsr[ARRAY_SIZE(s_enetBases)]; -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Set ENET MAC controller with the configuration. - * - * @param base ENET peripheral base address. - * @param handle The ENET handle pointer. - * @param config ENET Mac configuration. - * @param bufferConfig ENET buffer configuration. - * @param macAddr ENET six-byte mac address. - * @param srcClock_Hz ENET module clock source, normally it's system clock. - */ -static void ENET_SetMacController(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig, - uint8_t *macAddr, - uint32_t srcClock_Hz); - -/*! - * @brief Set ENET handler. - * - * @param base ENET peripheral base address. - * @param handle The ENET handle pointer. - * @param config ENET configuration stucture pointer. - * @param bufferConfig ENET buffer configuration. - */ -static void ENET_SetHandler(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig); - -/*! - * @brief Set ENET MAC transmit buffer descriptors. - * - * @param handle The ENET handle pointer. - * @param config The ENET configuration structure. - * @param bufferConfig The ENET buffer configuration. - */ -static void ENET_SetTxBufferDescriptors(enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig); - -/*! - * @brief Set ENET MAC receive buffer descriptors. - * - * @param handle The ENET handle pointer. - * @param config The ENET configuration structure. - * @param bufferConfig The ENET buffer configuration. - */ -static void ENET_SetRxBufferDescriptors(enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig); - -/*! - * @brief Updates the ENET read buffer descriptors. - * - * @param base ENET peripheral base address. - * @param handle The ENET handle pointer. - * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - */ -static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId); - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * @brief Get the ENET instance from peripheral base address. - * - * @param base ENET peripheral base address. - * @return ENET instance. - */ -uint32_t ENET_GetInstance(ENET_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_enetBases); instance++) - { - if (s_enetBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_enetBases)); - - return instance; -} - -/*! - * brief Gets the ENET default configuration structure. - * - * The purpose of this API is to get the default ENET MAC controller - * configure structure for ENET_Init(). User may use the initialized - * structure unchanged in ENET_Init(), or modify some fields of the - * structure before calling ENET_Init(). - * Example: - code - enet_config_t config; - ENET_GetDefaultConfig(&config); - endcode - * param config The ENET mac controller configuration structure pointer. - */ -void ENET_GetDefaultConfig(enet_config_t *config) -{ - /* Checks input parameter. */ - assert(config != NULL); - - /* Initializes the MAC configure structure to zero. */ - (void)memset(config, 0, sizeof(enet_config_t)); - - /* Sets MII mode, full duplex, 100Mbps for MAC and PHY data interface. */ -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - config->miiMode = kENET_RgmiiMode; -#else - config->miiMode = kENET_RmiiMode; -#endif - config->miiSpeed = kENET_MiiSpeed100M; - config->miiDuplex = kENET_MiiFullDuplex; - - config->ringNum = 1; - - /* Sets the maximum receive frame length. */ - config->rxMaxFrameLen = ENET_FRAME_MAX_FRAMELEN; -} - -/*! - * brief Initializes the ENET module. - * - * This function initializes the module with the ENET configuration. - * note ENET has two buffer descriptors legacy buffer descriptors and - * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To - * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor - * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure() - * to configure the 1588 feature and related buffers after calling ENET_Up(). - * - * param base ENET peripheral base address. - * param handle ENET handler pointer. - * param config ENET mac configuration structure pointer. - * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig - * can be used directly. It is also possible to verify the Mac configuration using other methods. - * param bufferConfig ENET buffer configuration structure pointer. - * The buffer configuration should be prepared for ENET Initialization. - * It is the start address of "ringNum" enet_buffer_config structures. - * To support added multi-ring features in some soc and compatible with the previous - * enet driver version. For single ring supported, this bufferConfig is a buffer - * configure structure pointer, for multi-ring supported and used case, this bufferConfig - * pointer should be a buffer configure structure array pointer. - * param macAddr ENET mac address of Ethernet device. This MAC address should be - * provided. - * param srcClock_Hz The internal module clock source for MII clock. - */ -void ENET_Up(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig, - uint8_t *macAddr, - uint32_t srcClock_Hz) -{ - /* Checks input parameters. */ - assert(handle != NULL); - assert(config != NULL); - assert(bufferConfig != NULL); - assert(macAddr != NULL); - assert(config->ringNum <= (uint8_t)FSL_FEATURE_ENET_QUEUE); - - /* Initializes the ENET transmit buffer descriptors. */ - ENET_SetTxBufferDescriptors(handle, config, bufferConfig); - - /* Initializes the ENET receive buffer descriptors. */ - ENET_SetRxBufferDescriptors(handle, config, bufferConfig); - - /* Initializes the ENET MAC controller with basic function. */ - ENET_SetMacController(base, handle, config, bufferConfig, macAddr, srcClock_Hz); - - /* Set all buffers or data in handler for data transmit/receive process. */ - ENET_SetHandler(base, handle, config, bufferConfig); -} - -/*! - * brief Initializes the ENET module. - * - * This function ungates the module clock and initializes it with the ENET configuration. - * note ENET has two buffer descriptors legacy buffer descriptors and - * enhanced IEEE 1588 buffer descriptors. The legacy descriptor is used by default. To - * use the IEEE 1588 feature, use the enhanced IEEE 1588 buffer descriptor - * by defining "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" and calling ENET_Ptp1588Configure() - * to configure the 1588 feature and related buffers after calling ENET_Init(). - * - * param base ENET peripheral base address. - * param handle ENET handler pointer. - * param config ENET mac configuration structure pointer. - * The "enet_config_t" type mac configuration return from ENET_GetDefaultConfig - * can be used directly. It is also possible to verify the Mac configuration using other methods. - * param bufferConfig ENET buffer configuration structure pointer. - * The buffer configuration should be prepared for ENET Initialization. - * It is the start address of "ringNum" enet_buffer_config structures. - * To support added multi-ring features in some soc and compatible with the previous - * enet driver version. For single ring supported, this bufferConfig is a buffer - * configure structure pointer, for multi-ring supported and used case, this bufferConfig - * pointer should be a buffer configure structure array pointer. - * param macAddr ENET mac address of Ethernet device. This MAC address should be - * provided. - * param srcClock_Hz The internal module clock source for MII clock. - */ -void ENET_Init(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig, - uint8_t *macAddr, - uint32_t srcClock_Hz) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = ENET_GetInstance(base); - - /* Ungate ENET clock. */ - (void)CLOCK_EnableClock(s_enetClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - /* Reset ENET module. */ - ENET_Reset(base); - - ENET_Up(base, handle, config, bufferConfig, macAddr, srcClock_Hz); -} - -/*! - * brief Stops the ENET module. - - * This function disables the ENET module. - * - * param base ENET peripheral base address. - */ -void ENET_Down(ENET_Type *base) -{ - /* Disable interrupt. */ - base->EIMR = 0; - - /* Disable ENET. */ - base->ECR &= ~ENET_ECR_ETHEREN_MASK; -} - -/*! - * brief Deinitializes the ENET module. - - * This function gates the module clock, clears ENET interrupts, and disables the ENET module. - * - * param base ENET peripheral base address. - */ -void ENET_Deinit(ENET_Type *base) -{ - ENET_Down(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disables the clock source. */ - (void)CLOCK_DisableClock(s_enetClock[ENET_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Sets the callback function. - * This API is provided for the application callback required case when ENET - * interrupt is enabled. This API should be called after calling ENET_Init. - * - * param handle ENET handler pointer. Should be provided by application. - * param callback The ENET callback function. - * param userData The callback function parameter. - */ -void ENET_SetCallback(enet_handle_t *handle, enet_callback_t callback, void *userData) -{ - assert(handle != NULL); - - /* Set callback and userData. */ - handle->callback = callback; - handle->userData = userData; -} - -#if FSL_FEATURE_ENET_QUEUE > 1 -void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetRxIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetRxIrqId[instance]); -} - -void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_ring_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetTxIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetTxIrqId[instance]); -} -#else -void ENET_SetRxISRHandler(ENET_Type *base, enet_isr_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetRxIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetRxIrqId[instance]); -} - -void ENET_SetTxISRHandler(ENET_Type *base, enet_isr_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetTxIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetTxIrqId[instance]); -} -#endif - -void ENET_SetErrISRHandler(ENET_Type *base, enet_isr_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetErrIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetErrIrqId[instance]); -} - -#if defined(ENET_ENHANCEDBUFFERDESCRIPTOR_MODE) && ENET_ENHANCEDBUFFERDESCRIPTOR_MODE -void ENET_SetTsISRHandler(ENET_Type *base, enet_isr_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enetTsIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enetTsIrqId[instance]); -} - -#if (FSL_FEATURE_ENET_QUEUE > 1) && defined(ENET_1G) -void ENET_Set1588TimerISRHandler(ENET_Type *base, enet_isr_t ISRHandler) -{ - uint32_t instance = ENET_GetInstance(base); - - s_enet1588TimerIsr[instance] = ISRHandler; - (void)EnableIRQ(s_enet1588TimerIrqId[instance]); -} -#endif -#endif - -static void ENET_SetHandler(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig) -{ - uint8_t count; - uint32_t instance = ENET_GetInstance(base); - const enet_buffer_config_t *buffCfg = bufferConfig; - - /* Store transfer parameters in handle pointer. */ - (void)memset(handle, 0, sizeof(enet_handle_t)); - - handle->ringNum = - (config->ringNum > (uint8_t)FSL_FEATURE_ENET_QUEUE) ? (uint8_t)FSL_FEATURE_ENET_QUEUE : config->ringNum; - for (count = 0; count < handle->ringNum; count++) - { - assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen); - - handle->rxBdRing[count].rxBdBase = buffCfg->rxBdStartAddrAlign; - handle->rxBuffSizeAlign[count] = buffCfg->rxBuffSizeAlign; - handle->rxBdRing[count].rxRingLen = buffCfg->rxBdNumber; - handle->rxMaintainEnable[count] = buffCfg->rxMaintainEnable; - handle->txBdRing[count].txBdBase = buffCfg->txBdStartAddrAlign; - handle->txBuffSizeAlign[count] = buffCfg->txBuffSizeAlign; - handle->txBdRing[count].txRingLen = buffCfg->txBdNumber; - handle->txMaintainEnable[count] = buffCfg->txMaintainEnable; - handle->txDirtyRing[count].txDirtyBase = buffCfg->txFrameInfo; - handle->txDirtyRing[count].txRingLen = buffCfg->txBdNumber; - buffCfg++; - } - - /* Save the handle pointer in the global variables. */ - s_ENETHandle[instance] = handle; - - /* Set the IRQ handler when the interrupt is enabled. */ - if (0U != (config->interrupt & (uint32_t)ENET_TX_INTERRUPT)) - { - ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler); - } - if (0U != (config->interrupt & (uint32_t)ENET_RX_INTERRUPT)) - { - ENET_SetRxISRHandler(base, ENET_ReceiveIRQHandler); - } - if (0U != (config->interrupt & (uint32_t)ENET_ERR_INTERRUPT)) - { - ENET_SetErrISRHandler(base, ENET_ErrorIRQHandler); - } -} - -static void ENET_SetMacController(ENET_Type *base, - enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig, - uint8_t *macAddr, - uint32_t srcClock_Hz) -{ -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - /* Check the MII mode/speed/duplex setting. */ - if (config->miiSpeed == kENET_MiiSpeed1000M) - { - /* Only RGMII mode has the 1000M bit/s. The 1000M only support full duplex. */ - assert(config->miiMode == kENET_RgmiiMode); - assert(config->miiDuplex == kENET_MiiFullDuplex); - } -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - - uint32_t rcr = 0; - uint32_t tcr = 0; - uint32_t ecr = base->ECR; - uint32_t macSpecialConfig = config->macSpecialConfig; - uint32_t maxFrameLen = config->rxMaxFrameLen; - uint32_t configVal = 0; - - /* Maximum frame length check. */ - if ((0U != (macSpecialConfig & (uint32_t)kENET_ControlVLANTagEnable)) && (maxFrameLen <= ENET_FRAME_MAX_FRAMELEN)) - { - maxFrameLen = (ENET_FRAME_MAX_FRAMELEN + ENET_FRAME_VLAN_TAGLEN); -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - if (0U != (macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable)) - { - /* Double vlan tag (SVLAN) supported. */ - maxFrameLen += ENET_FRAME_VLAN_TAGLEN; - } - ecr |= - (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlSVLANEnable) != 0U) ? - (ENET_ECR_SVLANEN_MASK | ENET_ECR_SVLANDBL_MASK) : - 0U) | - (uint32_t)(((macSpecialConfig & (uint32_t)kENET_ControlVLANUseSecondTag) != 0U) ? ENET_ECR_VLANUSE2ND_MASK : - 0U); -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - } - - /* Configures MAC receive controller with user configure structure. */ - rcr = ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPayloadCheckEnable)) ? ENET_RCR_NLC_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_CFEN_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) ? ENET_RCR_FCE_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxPadRemoveEnable)) ? ENET_RCR_PADEN_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlRxBroadCastRejectEnable)) ? ENET_RCR_BC_REJ_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlPromiscuousEnable)) ? ENET_RCR_PROM_MASK : 0U) | - ENET_RCR_MAX_FL(maxFrameLen) | ENET_RCR_CRCFWD_MASK; - -/* Set the RGMII or RMII, MII mode and control register. */ -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - if (config->miiMode == kENET_RgmiiMode) - { - rcr |= ENET_RCR_RGMII_EN_MASK; - rcr &= ~ENET_RCR_MII_MODE_MASK; - } - else - { - rcr &= ~ENET_RCR_RGMII_EN_MASK; -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - rcr |= ENET_RCR_MII_MODE_MASK; - if (config->miiMode == kENET_RmiiMode) - { - rcr |= ENET_RCR_RMII_MODE_MASK; - } -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - } -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - /* Speed. */ - if (config->miiSpeed == kENET_MiiSpeed10M) - { - rcr |= ENET_RCR_RMII_10T_MASK; - } -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - if (config->miiSpeed == kENET_MiiSpeed1000M) - { - ecr |= ENET_ECR_SPEED_MASK; - } - else - { - ecr &= ~ENET_ECR_SPEED_MASK; - } -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - - /* Receive setting for half duplex. */ - if (config->miiDuplex == kENET_MiiHalfDuplex) - { - rcr |= ENET_RCR_DRT_MASK; - } - /* Sets internal loop only for MII mode. */ - if ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlMIILoopEnable)) && - (config->miiMode != kENET_RmiiMode)) - { - rcr |= ENET_RCR_LOOP_MASK; - rcr &= ~ENET_RCR_DRT_MASK; - } - base->RCR = rcr; - - /* Configures MAC transmit controller: duplex mode, mac address insertion. */ - tcr = base->TCR & ~(ENET_TCR_FDEN_MASK | ENET_TCR_ADDINS_MASK); - tcr |= ((kENET_MiiHalfDuplex != config->miiDuplex) ? (uint32_t)ENET_TCR_FDEN_MASK : 0U) | - ((0U != (macSpecialConfig & (uint32_t)kENET_ControlMacAddrInsert)) ? (uint32_t)ENET_TCR_ADDINS_MASK : 0U); - base->TCR = tcr; - - /* Configures receive and transmit accelerator. */ - base->TACC = config->txAccelerConfig; - base->RACC = config->rxAccelerConfig; - - /* Sets the pause duration and FIFO threshold for the flow control enabled case. */ - if (0U != (macSpecialConfig & (uint32_t)kENET_ControlFlowControlEnable)) - { - uint32_t reemReg; - base->OPD = config->pauseDuration; - reemReg = ENET_RSEM_RX_SECTION_EMPTY(config->rxFifoEmptyThreshold); -#if defined(FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD) && FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD - reemReg |= ENET_RSEM_STAT_SECTION_EMPTY(config->rxFifoStatEmptyThreshold); -#endif /* FSL_FEATURE_ENET_HAS_RECEIVE_STATUS_THRESHOLD */ - base->RSEM = reemReg; - } - - /* FIFO threshold setting for store and forward enable/disable case. */ - if (0U != (macSpecialConfig & (uint32_t)kENET_ControlStoreAndFwdDisable)) - { - /* Transmit fifo watermark settings. */ - configVal = ((uint32_t)config->txFifoWatermark) & ENET_TFWR_TFWR_MASK; - base->TFWR = configVal; - /* Receive fifo full threshold settings. */ - configVal = ((uint32_t)config->rxFifoFullThreshold) & ENET_RSFL_RX_SECTION_FULL_MASK; - base->RSFL = configVal; - } - else - { - /* Transmit fifo watermark settings. */ - base->TFWR = ENET_TFWR_STRFWD_MASK; - base->RSFL = 0; - } - - /* Enable store and forward when accelerator is enabled */ - if (0U != - (config->txAccelerConfig & ((uint32_t)kENET_TxAccelIpCheckEnabled | (uint32_t)kENET_TxAccelProtoCheckEnabled))) - { - base->TFWR = ENET_TFWR_STRFWD_MASK; - } - if (0U != ((config->rxAccelerConfig & - ((uint32_t)kENET_RxAccelIpCheckEnabled | (uint32_t)kENET_RxAccelProtoCheckEnabled)))) - { - base->RSFL = 0; - } - -/* Initializes the ring 0. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - base->TDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->txBdStartAddrAlign, kMEMORY_Local2DMA); - base->RDSR = MEMORY_ConvertMemoryMapAddress((uint32_t)bufferConfig->rxBdStartAddrAlign, kMEMORY_Local2DMA); -#else - base->TDSR = (uint32_t)bufferConfig->txBdStartAddrAlign; - base->RDSR = (uint32_t)bufferConfig->rxBdStartAddrAlign; -#endif - base->MRBR = (uint32_t)bufferConfig->rxBuffSizeAlign; - -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - const enet_buffer_config_t *buffCfg = bufferConfig; - - if (config->ringNum > 1U) - { - /* Initializes the ring 1. */ - buffCfg++; -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - base->TDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA); - base->RDSR1 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA); -#else - base->TDSR1 = (uint32_t)buffCfg->txBdStartAddrAlign; - base->RDSR1 = (uint32_t)buffCfg->rxBdStartAddrAlign; -#endif - base->MRBR1 = (uint32_t)buffCfg->rxBuffSizeAlign; - /* Enable the DMAC for ring 1 and with no rx classification set. */ - base->DMACFG[0] = ENET_DMACFG_DMA_CLASS_EN_MASK; - } - if (config->ringNum > 2U) - { - /* Initializes the ring 2. */ - buffCfg++; -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - base->TDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBdStartAddrAlign, kMEMORY_Local2DMA); - base->RDSR2 = MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBdStartAddrAlign, kMEMORY_Local2DMA); -#else - base->TDSR2 = (uint32_t)buffCfg->txBdStartAddrAlign; - base->RDSR2 = (uint32_t)buffCfg->rxBdStartAddrAlign; -#endif - base->MRBR2 = (uint32_t)buffCfg->rxBuffSizeAlign; - /* Enable the DMAC for ring 2 and with no rx classification set. */ - base->DMACFG[1] = ENET_DMACFG_DMA_CLASS_EN_MASK; - } - - /* Default the class/ring 1 and 2 are not enabled and the receive classification is disabled - * so we set the default transmit scheme with the round-robin mode. beacuse the legacy bd mode - * only support the round-robin mode. if the avb feature is required, just call the setup avb - * feature API. */ - base->QOS |= ENET_QOS_TX_SCHEME(1); -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - - /* Configures the Mac address. */ - ENET_SetMacAddr(base, macAddr); - - /* Initialize the SMI if uninitialized. */ - if (!ENET_GetSMI(base)) - { - ENET_SetSMI(base, srcClock_Hz, - ((0U != (config->macSpecialConfig & (uint32_t)kENET_ControlSMIPreambleDisable)) ? true : false)); - } - -/* Enables Ethernet interrupt, enables the interrupt coalsecing if it is required. */ -#if defined(FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE) && FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE - if (NULL != config->intCoalesceCfg) - { - uint32_t intMask = (ENET_EIMR_TXB_MASK | ENET_EIMR_RXB_MASK); - -#if FSL_FEATURE_ENET_QUEUE > 1 - uint8_t queue = 0; - intMask |= ENET_EIMR_TXB2_MASK | ENET_EIMR_RXB2_MASK | ENET_EIMR_TXB1_MASK | ENET_EIMR_RXB1_MASK; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - - /* Clear all buffer interrupts. */ - base->EIMR &= ~intMask; - -/* Set the interrupt coalescence. */ -#if FSL_FEATURE_ENET_QUEUE > 1 - for (queue = 0; queue < (uint8_t)FSL_FEATURE_ENET_QUEUE; queue++) - { - base->TXIC[queue] = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[queue]) | - config->intCoalesceCfg->txCoalesceTimeCount[queue] | ENET_TXIC_ICCS_MASK | - ENET_TXIC_ICEN_MASK; - base->RXIC[queue] = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[queue]) | - config->intCoalesceCfg->rxCoalesceTimeCount[queue] | ENET_RXIC_ICCS_MASK | - ENET_RXIC_ICEN_MASK; - } -#else - base->TXIC = ENET_TXIC_ICFT(config->intCoalesceCfg->txCoalesceFrameCount[0]) | - config->intCoalesceCfg->txCoalesceTimeCount[0] | ENET_TXIC_ICCS_MASK | ENET_TXIC_ICEN_MASK; - base->RXIC = ENET_RXIC_ICFT(config->intCoalesceCfg->rxCoalesceFrameCount[0]) | - config->intCoalesceCfg->rxCoalesceTimeCount[0] | ENET_RXIC_ICCS_MASK | ENET_RXIC_ICEN_MASK; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } -#endif /* FSL_FEATURE_ENET_HAS_INTERRUPT_COALESCE */ - ENET_EnableInterrupts(base, config->interrupt); - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* Sets the 1588 enhanced feature. */ - ecr |= ENET_ECR_EN1588_MASK; -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - /* Enables Ethernet module after all configuration except the buffer descriptor active. */ - ecr |= ENET_ECR_ETHEREN_MASK | ENET_ECR_DBSWP_MASK; - base->ECR = ecr; -} - -static void ENET_SetTxBufferDescriptors(enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig) -{ - assert(config != NULL); - assert(bufferConfig != NULL); - - /* Default single ring is supported. */ - uint8_t ringNum; - uint16_t count; - uint32_t txBuffSizeAlign; - uint8_t *txBuffer = NULL; - const enet_buffer_config_t *buffCfg = bufferConfig; - - /* Check the input parameters. */ - for (ringNum = 0; ringNum < config->ringNum; ringNum++) - { - if (buffCfg->txBdStartAddrAlign != NULL) - { - volatile enet_tx_bd_struct_t *curBuffDescrip = buffCfg->txBdStartAddrAlign; - txBuffSizeAlign = buffCfg->txBuffSizeAlign; - - if (buffCfg->txBufferAlign != NULL) - { -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - txBuffer = - (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->txBufferAlign, kMEMORY_Local2DMA); -#else - txBuffer = buffCfg->txBufferAlign; -#endif - } - - for (count = 0; count < buffCfg->txBdNumber; count++) - { - if (buffCfg->txBufferAlign != NULL) - { - /* Set data buffer address. */ - curBuffDescrip->buffer = (uint8_t *)((uint32_t)&txBuffer[count * txBuffSizeAlign]); - } - /* Initializes data length. */ - curBuffDescrip->length = 0; - /* Sets the crc. */ - curBuffDescrip->control = ENET_BUFFDESCRIPTOR_TX_TRANMITCRC_MASK; - /* Sets the last buffer descriptor with the wrap flag. */ - if (count == (buffCfg->txBdNumber - 1U)) - { - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_WRAP_MASK; - } - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* Enable transmit interrupt for store the transmit timestamp. */ - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_INTERRUPT_MASK; -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - /* Set the type of the frame when the credit-based scheme is used. */ - curBuffDescrip->controlExtend1 |= (uint16_t)(ENET_BD_FTYPE(ringNum)); -#endif /* FSL_FEATURE_ENET_HAS_AVB */ -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - /* Increase the index. */ - curBuffDescrip++; - } - } - buffCfg++; - } -} - -static void ENET_SetRxBufferDescriptors(enet_handle_t *handle, - const enet_config_t *config, - const enet_buffer_config_t *bufferConfig) -{ - assert(config != NULL); - assert(bufferConfig != NULL); - - /* Default single ring is supported. */ - uint8_t ringNum; - uint16_t count; - uint16_t rxBuffSizeAlign; - uint8_t *rxBuffer; - const enet_buffer_config_t *buffCfg = bufferConfig; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - uint32_t mask = ((uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt); -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Check the input parameters. */ - for (ringNum = 0; ringNum < config->ringNum; ringNum++) - { - assert(buffCfg->rxBuffSizeAlign >= ENET_RX_MIN_BUFFERSIZE); -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE -#if FSL_FEATURE_ENET_QUEUE > 1 - if (ringNum == 1U) - { - mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt); - } - else if (ringNum == 2U) - { - mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt); - } - else - { - /* Intentional empty */ - } -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - if ((buffCfg->rxBdStartAddrAlign != NULL) && (buffCfg->rxBufferAlign != NULL)) - { - volatile enet_rx_bd_struct_t *curBuffDescrip = buffCfg->rxBdStartAddrAlign; - rxBuffSizeAlign = buffCfg->rxBuffSizeAlign; -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - rxBuffer = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)buffCfg->rxBufferAlign, kMEMORY_Local2DMA); -#else - rxBuffer = buffCfg->rxBufferAlign; -#endif - -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (buffCfg->rxMaintainEnable) - { - /* Invalidate rx buffers before DMA transfer data into them. */ - DCACHE_InvalidateByRange((uint32_t)rxBuffer, ((uint32_t)buffCfg->rxBdNumber * rxBuffSizeAlign)); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - - for (count = 0; count < buffCfg->rxBdNumber; count++) - { - /* Set data buffer and the length. */ - curBuffDescrip->buffer = (uint8_t *)((uint32_t)&rxBuffer[count * rxBuffSizeAlign]); - curBuffDescrip->length = 0; - - /* Initializes the buffer descriptors with empty bit. */ - curBuffDescrip->control = ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - /* Sets the last buffer descriptor with the wrap flag. */ - if (count == (buffCfg->rxBdNumber - 1U)) - { - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - } - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - if (0U != (config->interrupt & mask)) - { - /* Enable receive interrupt. */ - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_RX_INTERRUPT_MASK; - } - else - { - curBuffDescrip->controlExtend1 = 0; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - /* Increase the index. */ - curBuffDescrip++; - } - } - buffCfg++; - } -} - -/*! - * @brief Activates ENET send for multiple tx rings. - * @note This must be called after the MAC configuration and - * state are ready. It must be called after the ENET_Init() and - * this should be called when the ENET receive required. - * - * @param base ENET peripheral base address. - * @param ringId The descriptor ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - * - */ -static void ENET_ActiveSend(ENET_Type *base, uint8_t ringId) -{ - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - volatile uint32_t *txDesActive = NULL; - - /* Ensure previous data update is completed with Data Synchronization Barrier before activing Tx BD. */ - __DSB(); - - switch (ringId) - { - case kENET_Ring0: - txDesActive = &(base->TDAR); - break; -#if FSL_FEATURE_ENET_QUEUE > 1 - case kENET_Ring1: - txDesActive = &(base->TDAR1); - break; - case kENET_Ring2: - txDesActive = &(base->TDAR2); - break; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - default: - txDesActive = &(base->TDAR); - break; - } - -#if defined(FSL_FEATURE_ENET_HAS_ERRATA_007885) && FSL_FEATURE_ENET_HAS_ERRATA_007885 - /* There is a TDAR race condition for mutliQ when the software sets TDAR - * and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles). - * This will cause the udma_tx and udma_tx_arbiter state machines to hang. - * Software workaround: introduces a delay by reading the relevant ENET_TDARn_TDAR 4 times - */ - for (uint8_t i = 0; i < 4U; i++) - { - if (*txDesActive == 0U) - { - break; - } - } -#endif - - /* Write to active tx descriptor */ - *txDesActive = 0; -} - -/*! - * brief Sets the ENET MII speed and duplex. - * - * This API is provided to dynamically change the speed and dulpex for MAC. - * - * param base ENET peripheral base address. - * param speed The speed of the RMII mode. - * param duplex The duplex of the RMII mode. - */ -void ENET_SetMII(ENET_Type *base, enet_mii_speed_t speed, enet_mii_duplex_t duplex) -{ - uint32_t rcr = base->RCR; - uint32_t tcr = base->TCR; - -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB - uint32_t ecr = base->ECR; - - if (kENET_MiiSpeed1000M == speed) - { - assert(duplex == kENET_MiiFullDuplex); - ecr |= ENET_ECR_SPEED_MASK; - } - else - { - ecr &= ~ENET_ECR_SPEED_MASK; - } - - base->ECR = ecr; -#endif /* FSL_FEATURE_ENET_HAS_AVB */ - - /* Sets speed mode. */ - if (kENET_MiiSpeed10M == speed) - { - rcr |= ENET_RCR_RMII_10T_MASK; - } - else - { - rcr &= ~ENET_RCR_RMII_10T_MASK; - } - /* Set duplex mode. */ - if (duplex == kENET_MiiHalfDuplex) - { - rcr |= ENET_RCR_DRT_MASK; - tcr &= ~ENET_TCR_FDEN_MASK; - } - else - { - rcr &= ~ENET_RCR_DRT_MASK; - tcr |= ENET_TCR_FDEN_MASK; - } - - base->RCR = rcr; - base->TCR = tcr; -} - -/*! - * brief Sets the ENET module Mac address. - * - * param base ENET peripheral base address. - * param macAddr The six-byte Mac address pointer. - * The pointer is allocated by application and input into the API. - */ -void ENET_SetMacAddr(ENET_Type *base, uint8_t *macAddr) -{ - uint32_t address; - - /* Set physical address lower register. */ - address = (uint32_t)(((uint32_t)macAddr[0] << 24U) | ((uint32_t)macAddr[1] << 16U) | ((uint32_t)macAddr[2] << 8U) | - (uint32_t)macAddr[3]); - base->PALR = address; - /* Set physical address high register. */ - address = (uint32_t)(((uint32_t)macAddr[4] << 8U) | ((uint32_t)macAddr[5])); - base->PAUR = address << ENET_PAUR_PADDR2_SHIFT; -} - -/*! - * brief Gets the ENET module Mac address. - * - * param base ENET peripheral base address. - * param macAddr The six-byte Mac address pointer. - * The pointer is allocated by application and input into the API. - */ -void ENET_GetMacAddr(ENET_Type *base, uint8_t *macAddr) -{ - assert(macAddr != NULL); - - uint32_t address; - - /* Get from physical address lower register. */ - address = base->PALR; - macAddr[0] = 0xFFU & (uint8_t)(address >> 24U); - macAddr[1] = 0xFFU & (uint8_t)(address >> 16U); - macAddr[2] = 0xFFU & (uint8_t)(address >> 8U); - macAddr[3] = 0xFFU & (uint8_t)address; - - /* Get from physical address high register. */ - address = (base->PAUR & ENET_PAUR_PADDR2_MASK) >> ENET_PAUR_PADDR2_SHIFT; - macAddr[4] = 0xFFU & (uint8_t)(address >> 8U); - macAddr[5] = 0xFFU & (uint8_t)address; -} - -/*! - * brief Sets the ENET SMI(serial management interface)- MII management interface. - * - * param base ENET peripheral base address. - * param srcClock_Hz This is the ENET module clock frequency. Normally it's the system clock. See clock distribution. - * param isPreambleDisabled The preamble disable flag. - * - true Enables the preamble. - * - false Disables the preamble. - */ -void ENET_SetSMI(ENET_Type *base, uint32_t srcClock_Hz, bool isPreambleDisabled) -{ - assert((srcClock_Hz / (2U * ENET_MDC_FREQUENCY)) != 0U); - - uint32_t clkCycle = 0; - uint32_t speed = 0; - uint32_t mscr = 0; - - /* Calculate the MII speed which controls the frequency of the MDC. */ - speed = srcClock_Hz / (2U * ENET_MDC_FREQUENCY) - 1U; - /* Calculate the hold time on the MDIO output. */ - clkCycle = (10U + ENET_NANOSECOND_ONE_SECOND / srcClock_Hz - 1U) / (ENET_NANOSECOND_ONE_SECOND / srcClock_Hz) - 1U; - /* Build the configuration for MDC/MDIO control. */ - mscr = - ENET_MSCR_MII_SPEED(speed) | ENET_MSCR_HOLDTIME(clkCycle) | (isPreambleDisabled ? ENET_MSCR_DIS_PRE_MASK : 0U); - base->MSCR = mscr; -} - -/*! - * brief Starts an SMI write command. - * - * Used for standard IEEE802.3 MDIO Clause 22 format. - * - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. Range from 0 ~ 31. - * param operation The write operation. - * param data The data written to PHY. - */ -void ENET_StartSMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_write_t operation, uint32_t data) -{ - uint32_t mmfr = 0; - - /* Build MII write command. */ - mmfr = ENET_MMFR_ST(1U) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | - ENET_MMFR_TA(2U) | (data & 0xFFFFU); - base->MMFR = mmfr; -} - -/*! - * brief Starts an SMI (Serial Management Interface) read command. - * - * Used for standard IEEE802.3 MDIO Clause 22 format. - * - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. Range from 0 ~ 31. - * param operation The read operation. - */ -void ENET_StartSMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, enet_mii_read_t operation) -{ - uint32_t mmfr = 0; - - /* Build MII read command. */ - mmfr = ENET_MMFR_ST(1U) | ENET_MMFR_OP(operation) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(phyReg) | ENET_MMFR_TA(2U); - base->MMFR = mmfr; -} - -#if defined(FSL_FEATURE_ENET_HAS_EXTEND_MDIO) && FSL_FEATURE_ENET_HAS_EXTEND_MDIO -/*! - * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write command. - * deprecated Do not use this function. It has been superceded by @ref ENET_StartExtC45SMIWriteReg and - * ENET_StartExtC45SMIWriteData. - * - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, - * the phyReg is a 21-bits combination of the devaddr (5 bits device address) - * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. - * param data The data written to PHY. - */ -void ENET_StartExtC45SMIWrite(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) -{ - uint32_t mmfr = 0; - - /* Parse the address from the input register. */ - uint16_t devAddr = (uint16_t)((phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU); - uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU); - - /* Address write firstly. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr); - base->MMFR = mmfr; - - /* Build MII write command. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2) | ENET_MMFR_DATA(data); - base->MMFR = mmfr; -} - -/*! - * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read command. - * deprecated Do not use this function. It has been superceded by @ref ENET_StartExtC45SMIWriteReg and - * ENET_StartExtC45SMIReadData. - * - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, - * the phyReg is a 21-bits combination of the devaddr (5 bits device address) - * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. - */ -void ENET_StartExtC45SMIRead(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg) -{ - uint32_t mmfr = 0; - - /* Parse the address from the input register. */ - uint16_t devAddr = (uint16_t)((phyReg >> ENET_MMFR_TA_SHIFT) & 0x1FU); - uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU); - - /* Address write firstly. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr); - base->MMFR = mmfr; - - /* Build MII read command. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2); - base->MMFR = mmfr; -} - -/*! - * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write register command. - * - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, - * the phyReg is a 21-bits combination of the devaddr (5 bits device address) - * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. - */ -void ENET_StartExtC45SMIWriteReg(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg) -{ - uint32_t mmfr = 0; - - /* Parse the address from the input register. */ - uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU); - uint16_t regAddr = (uint16_t)(phyReg & 0xFFFFU); - - /* Address write. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiAddrWrite_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2) | ENET_MMFR_DATA(regAddr); - base->MMFR = mmfr; -} - -/*! - * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI write data command. - * - * After writing MMFR register, we need to check whether the transmission is over. - * This is an example for whole precedure of clause 45 MDIO write. - * code - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * ENET_StartExtC45SMIWriteReg(base, phyAddr, phyReg); - * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U) - * { - * } - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * ENET_StartExtC45SMIWriteData(base, phyAddr, phyReg, data); - * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U) - * { - * } - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * endcode - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, - * the phyReg is a 21-bits combination of the devaddr (5 bits device address) - * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. - * param data The data written to PHY. - */ -void ENET_StartExtC45SMIWriteData(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg, uint32_t data) -{ - uint32_t mmfr = 0; - - /* Parse the address from the input register. */ - uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU); - - /* Build MII write command. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiWriteFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2) | ENET_MMFR_DATA(data); - base->MMFR = mmfr; -} - -/*! - * brief Starts the extended IEEE802.3 Clause 45 MDIO format SMI read data command. - * - * After writing MMFR register, we need to check whether the transmission is over. - * This is an example for whole precedure of clause 45 MDIO read. - * code - * uint32_t data; - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * ENET_StartExtC45SMIWriteReg(base, phyAddr, phyReg); - * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U) - * { - * } - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * ENET_StartExtC45SMIReadData(base, phyAddr, phyReg); - * while ((ENET_GetInterruptStatus(base) & ENET_EIR_MII_MASK) == 0U) - * { - * } - * ENET_ClearInterruptStatus(base, ENET_EIR_MII_MASK); - * data = ENET_ReadSMIData(base); - * endcode - * param base ENET peripheral base address. - * param phyAddr The PHY address. - * param phyReg The PHY register. For MDIO IEEE802.3 Clause 45, - * the phyReg is a 21-bits combination of the devaddr (5 bits device address) - * and the regAddr (16 bits phy register): phyReg = (devaddr << 16) | regAddr. - */ -void ENET_StartExtC45SMIReadData(ENET_Type *base, uint32_t phyAddr, uint32_t phyReg) -{ - uint32_t mmfr = 0; - - /* Parse the address from the input register. */ - uint16_t devAddr = (uint16_t)((phyReg >> 16U) & 0x1FU); - - /* Build MII read command. */ - mmfr = ENET_MMFR_ST(0) | ENET_MMFR_OP(kENET_MiiReadFrame_C45) | ENET_MMFR_PA(phyAddr) | ENET_MMFR_RA(devAddr) | - ENET_MMFR_TA(2); - base->MMFR = mmfr; -} -#endif /* FSL_FEATURE_ENET_HAS_EXTEND_MDIO */ - -static uint16_t ENET_IncreaseIndex(uint16_t index, uint16_t max) -{ - /* Increase the index. */ - index++; - if (index >= max) - { - index = 0; - } - return index; -} - -static inline bool ENET_TxDirtyRingAvailable(enet_tx_dirty_ring_t *txDirtyRing) -{ - return !txDirtyRing->isFull; -} - -/*! - * brief Gets the error statistics of a received frame for ENET specified ring. - * - * This API must be called after the ENET_GetRxFrameSize and before the ENET_ReadFrame(). - * If the ENET_GetRxFrameSize returns kStatus_ENET_RxFrameError, - * the ENET_GetRxErrBeforeReadFrame can be used to get the exact error statistics. - * This is an example. - * code - * status = ENET_GetRxFrameSize(&g_handle, &length, 0); - * if (status == kStatus_ENET_RxFrameError) - * { - * ENET_GetRxErrBeforeReadFrame(&g_handle, &eErrStatic, 0); - * ENET_ReadFrame(EXAMPLE_ENET, &g_handle, NULL, 0); - * } - * endcode - * param handle The ENET handler structure pointer. This is the same handler pointer used in the ENET_Init. - * param eErrorStatic The error statistics structure pointer. - * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - */ -void ENET_GetRxErrBeforeReadFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId) -{ - assert(handle != NULL); - assert(eErrorStatic != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - uint16_t control = 0; - enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId]; - volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - volatile enet_rx_bd_struct_t *cmpBuffDescrip = curBuffDescrip; - - do - { - /* The last buffer descriptor of a frame. */ - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)) - { - control = curBuffDescrip->control; - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_TRUNC_MASK)) - { - /* The receive truncate error. */ - eErrorStatic->statsRxTruncateErr++; - } - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_OVERRUN_MASK)) - { - /* The receive over run error. */ - eErrorStatic->statsRxOverRunErr++; - } - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LENVLIOLATE_MASK)) - { - /* The receive length violation error. */ - eErrorStatic->statsRxLenGreaterErr++; - } - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_NOOCTET_MASK)) - { - /* The receive alignment error. */ - eErrorStatic->statsRxAlignErr++; - } - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_CRC_MASK)) - { - /* The receive CRC error. */ - eErrorStatic->statsRxFcsErr++; - } -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - uint16_t controlExt = curBuffDescrip->controlExtend1; - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_MACERR_MASK)) - { - /* The MAC error. */ - eErrorStatic->statsRxMacErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_PHYERR_MASK)) - { - /* The PHY error. */ - eErrorStatic->statsRxPhyErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_RX_COLLISION_MASK)) - { - /* The receive collision error. */ - eErrorStatic->statsRxCollisionErr++; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - break; - } - - /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */ - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)) - { - curBuffDescrip = rxBdRing->rxBdBase; - } - else - { - curBuffDescrip++; - } - - } while (curBuffDescrip != cmpBuffDescrip); -} - -/*! - * brief Gets the size of the read frame for specified ring. - * - * This function gets a received frame size from the ENET buffer descriptors. - * note The FCS of the frame is automatically removed by MAC and the size is the length without the FCS. - * After calling ENET_GetRxFrameSize, ENET_ReadFrame() should be called to update the - * receive buffers if the result is not "kStatus_ENET_RxFrameEmpty". - * - * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. - * param length The length of the valid frame received. - * param ringId The ring index or ring number. - * retval kStatus_ENET_RxFrameEmpty No frame received. Should not call ENET_ReadFrame to read frame. - * retval kStatus_ENET_RxFrameError Data error happens. ENET_ReadFrame should be called with NULL data - * and NULL length to update the receive buffers. - * retval kStatus_Success Receive a frame Successfully then the ENET_ReadFrame - * should be called with the right data buffer and the captured data length input. - */ -status_t ENET_GetRxFrameSize(enet_handle_t *handle, uint32_t *length, uint8_t ringId) -{ - assert(handle != NULL); - assert(length != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - /* Reset the length to zero. */ - *length = 0; - - uint16_t validLastMask = ENET_BUFFDESCRIPTOR_RX_LAST_MASK | ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId]; - volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - uint16_t index = rxBdRing->rxGenIdx; - bool isReturn = false; - status_t result = kStatus_Success; - - /* Check the current buffer descriptor's empty flag. If empty means there is no frame received. */ - /* If this buffer descriptor is owned by application, return empty. Only need to check the first BD's owner if one - * frame in mutiple BDs. */ - if (0U != (curBuffDescrip->control & (ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK | ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK))) - { - isReturn = true; - result = kStatus_ENET_RxFrameEmpty; - } - else - { - do - { - /* Add check for abnormal case. */ - if (curBuffDescrip->length == 0U) - { - isReturn = true; - result = kStatus_ENET_RxFrameError; - break; - } - - /* Find the last buffer descriptor. */ - if ((curBuffDescrip->control & validLastMask) == ENET_BUFFDESCRIPTOR_RX_LAST_MASK) - { - isReturn = true; - /* The last buffer descriptor in the frame check the status of the received frame. */ - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_ERR_MASK)) - { - result = kStatus_ENET_RxFrameError; - break; - } -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - if (0U != (curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_RX_EXT_ERR_MASK)) - { - result = kStatus_ENET_RxFrameError; - break; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* FCS is removed by MAC. */ - *length = curBuffDescrip->length; - break; - } - /* Increase the buffer descriptor, if it is the last one, increase to first one of the ring buffer. */ - index = ENET_IncreaseIndex(index, rxBdRing->rxRingLen); - curBuffDescrip = rxBdRing->rxBdBase + index; - } while (index != rxBdRing->rxGenIdx); - } - - if (isReturn == false) - { - /* The frame is on processing - set to empty status to make application to receive it next time. */ - result = kStatus_ENET_RxFrameEmpty; - } - - return result; -} - -/*! - * brief Reads a frame from the ENET device. - * This function reads a frame (both the data and the length) from the ENET buffer descriptors. - * User can get timestamp through ts pointer if the ts is not NULL. - * Note that it doesn't store the timestamp in the receive timestamp queue. - * The ENET_GetRxFrameSize should be used to get the size of the prepared data buffer. - * This is an example: - * code - * uint32_t length; - * enet_handle_t g_handle; - * Comments: Get the received frame size firstly. - * status = ENET_GetRxFrameSize(&g_handle, &length, 0); - * if (length != 0) - * { - * Comments: Allocate memory here with the size of "length" - * uint8_t *data = memory allocate interface; - * if (!data) - * { - * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL); - * Comments: Add the console warning log. - * } - * else - * { - * status = ENET_ReadFrame(ENET, &g_handle, data, length, 0, NULL); - * Comments: Call stack input API to deliver the data to stack - * } - * } - * else if (status == kStatus_ENET_RxFrameError) - * { - * Comments: Update the received buffer when a error frame is received. - * ENET_ReadFrame(ENET, &g_handle, NULL, 0, 0, NULL); - * } - * endcode - * param base ENET peripheral base address. - * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. - * param data The data buffer provided by user to store the frame which memory size should be at least "length". - * param length The size of the data buffer which is still the length of the received frame. - * param ringId The ring index or ring number. - * param ts The timestamp address to store received timestamp. - * return The execute status, successful or failure. - */ -status_t ENET_ReadFrame( - ENET_Type *base, enet_handle_t *handle, uint8_t *data, uint32_t length, uint8_t ringId, uint32_t *ts) -{ - assert(handle != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - uint32_t len = 0; - uint32_t offset = 0; - uint16_t control; - bool isLastBuff = false; - enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId]; - volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - uint16_t index = rxBdRing->rxGenIdx; - status_t result = kStatus_Success; - uint32_t address; - uint32_t dest; - - /* For data-NULL input, only update the buffer descriptor. */ - if (data == NULL) - { - do - { - /* Update the control flag. */ - control = curBuffDescrip->control; - - /* Updates the receive buffer descriptors. */ - ENET_UpdateReadBuffers(base, handle, ringId); - - /* Find the last buffer descriptor for the frame. */ - if (0U != (control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)) - { - break; - } - curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - } while (index != rxBdRing->rxGenIdx); - } - else - { - while (!isLastBuff) - { -/* A frame on one buffer or several receive buffers are both considered. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->rxMaintainEnable[ringId]) - { - /* Add the cache invalidate maintain. */ - DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - - dest = (uint32_t)data + offset; - /* The last buffer descriptor of a frame. */ - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)) - { - /* This is a valid frame. */ - isLastBuff = true; - if (length == curBuffDescrip->length) - { - /* Copy the frame to user's buffer without FCS. */ - len = curBuffDescrip->length - offset; - (void)memcpy((uint32_t *)dest, (uint32_t *)address, len); -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* Get the timestamp if the ts isn't NULL. */ - if (ts != NULL) - { - *ts = curBuffDescrip->timestamp; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Updates the receive buffer descriptors. */ - ENET_UpdateReadBuffers(base, handle, ringId); - break; - } - else - { - /* Updates the receive buffer descriptors. */ - ENET_UpdateReadBuffers(base, handle, ringId); - } - } - else - { - /* Store a frame on several buffer descriptors. */ - isLastBuff = false; - /* Length check. */ - if (offset >= length) - { - result = kStatus_ENET_RxFrameFail; - break; - } - (void)memcpy((uint32_t *)dest, (uint32_t *)address, handle->rxBuffSizeAlign[ringId]); - offset += handle->rxBuffSizeAlign[ringId]; - - /* Updates the receive buffer descriptors. */ - ENET_UpdateReadBuffers(base, handle, ringId); - } - - /* Get the current buffer descriptor. */ - curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - } - } - - return result; -} - -static void ENET_UpdateReadBuffers(ENET_Type *base, enet_handle_t *handle, uint8_t ringId) -{ - assert(handle != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - volatile enet_rx_bd_struct_t *curBuffDescrip = - handle->rxBdRing[ringId].rxBdBase + handle->rxBdRing[ringId].rxGenIdx; - - /* Clears status. */ - curBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - /* Sets the receive buffer descriptor with the empty flag. */ - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - - /* Increase current buffer descriptor to the next one. */ - handle->rxBdRing[ringId].rxGenIdx = - ENET_IncreaseIndex(handle->rxBdRing[ringId].rxGenIdx, handle->rxBdRing[ringId].rxRingLen); - - /* Ensure previous data update is completed with Data Synchronization Barrier before activing Rx BD. */ - __DSB(); - - /* Actives the receive buffer descriptor. */ - switch (ringId) - { - case kENET_Ring0: - base->RDAR = ENET_RDAR_RDAR_MASK; - break; -#if FSL_FEATURE_ENET_QUEUE > 1 - case kENET_Ring1: - base->RDAR1 = ENET_RDAR1_RDAR_MASK; - break; - case kENET_Ring2: - base->RDAR2 = ENET_RDAR2_RDAR_MASK; - break; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - default: - assert(false); - base->RDAR = ENET_RDAR_RDAR_MASK; - break; - } -} - -/*! - * brief Transmits an ENET frame for specified ring. - * note The CRC is automatically appended to the data. Input the data - * to send without the CRC. - * - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. - * param data The data buffer provided by user to send. - * param length The length of the data to send. - * param ringId The ring index or ring number. - * param tsFlag Timestamp enable flag. - * param context Used by user to handle some events after transmit over. - * retval kStatus_Success Send frame succeed. - * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission. - * The transmit busy happens when the data send rate is over the MAC capacity. - * The waiting mechanism is recommended to be added after each call return with - * kStatus_ENET_TxFrameBusy. - */ -status_t ENET_SendFrame(ENET_Type *base, - enet_handle_t *handle, - const uint8_t *data, - uint32_t length, - uint8_t ringId, - bool tsFlag, - void *context) -{ - assert(handle != NULL); - assert(data != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - volatile enet_tx_bd_struct_t *curBuffDescrip; - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId]; - enet_frame_info_t *txDirty = NULL; - uint32_t len = 0; - uint32_t sizeleft = 0; - uint32_t address; - status_t result = kStatus_Success; - uint32_t src; - uint32_t configVal; - bool isReturn = false; - - /* Check the frame length. */ - if (length > ENET_FRAME_MAX_FRAMELEN) - { - result = kStatus_ENET_TxFrameOverLen; - } - else - { - /* Check if the transmit buffer is ready. */ - curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) - { - result = kStatus_ENET_TxFrameBusy; - } - /* Check txDirtyRing if need frameinfo in tx interrupt callback. */ - else if ((handle->TxReclaimEnable[ringId]) && !ENET_TxDirtyRingAvailable(txDirtyRing)) - { - result = kStatus_ENET_TxFrameBusy; - } - else - { - /* One transmit buffer is enough for one frame. */ - if (handle->txBuffSizeAlign[ringId] >= length) - { - /* Copy data to the buffer for uDMA transfer. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - (void)memcpy((void *)(uint32_t *)address, (const void *)(uint32_t *)(uint32_t)data, length); -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->txMaintainEnable[ringId]) - { - DCACHE_CleanByRange(address, length); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - /* Set data length. */ - curBuffDescrip->length = (uint16_t)length; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (tsFlag) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK); - } - -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); - - /* Increase the buffer descriptor address. */ - txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen); - - /* Add context to frame info ring */ - if (handle->TxReclaimEnable[ringId]) - { - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx; - txDirty->context = context; - txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen); - if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) - { - txDirtyRing->isFull = true; - } - txBdRing->txDescUsed++; - } - - /* Active the transmit buffer descriptor. */ - ENET_ActiveSend(base, ringId); - } - else - { - /* One frame requires more than one transmit buffers. */ - do - { -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (tsFlag) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK); - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Update the size left to be transmit. */ - sizeleft = length - len; -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - src = (uint32_t)data + len; - if (sizeleft > handle->txBuffSizeAlign[ringId]) - { - /* Data copy. */ - (void)memcpy((uint32_t *)address, (uint32_t *)src, handle->txBuffSizeAlign[ringId]); -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->txMaintainEnable[ringId]) - { - /* Add the cache clean maintain. */ - DCACHE_CleanByRange(address, handle->txBuffSizeAlign[ringId]); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - /* Data length update. */ - curBuffDescrip->length = handle->txBuffSizeAlign[ringId]; - len += handle->txBuffSizeAlign[ringId]; - /* Sets the control flag. */ - configVal = (uint32_t)curBuffDescrip->control; - configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; - configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; - curBuffDescrip->control = (uint16_t)configVal; - - if (handle->TxReclaimEnable[ringId]) - { - txBdRing->txDescUsed++; - } - /* Active the transmit buffer descriptor*/ - ENET_ActiveSend(base, ringId); - } - else - { - (void)memcpy((uint32_t *)address, (uint32_t *)src, sizeleft); -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->txMaintainEnable[ringId]) - { - /* Add the cache clean maintain. */ - DCACHE_CleanByRange(address, sizeleft); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - curBuffDescrip->length = (uint16_t)sizeleft; - /* Set Last buffer wrap flag. */ - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK; - - if (handle->TxReclaimEnable[ringId]) - { - /* Add context to frame info ring */ - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx; - txDirty->context = context; - txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen); - if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) - { - txDirtyRing->isFull = true; - } - txBdRing->txDescUsed++; - } - /* Active the transmit buffer descriptor. */ - ENET_ActiveSend(base, ringId); - isReturn = true; - break; - } - /* Increase and get the current buffer descriptor address. */ - txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen); - curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - - } while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)); - - if (isReturn == false) - { - result = kStatus_ENET_TxFrameBusy; - } - } - } - } - return result; -} - -/*! - * brief Enable or disable tx descriptors reclaim mechanism. - * note This function must be called when no pending send frame action. - * Set enable if you want to reclaim context or timestamp in interrupt. - * - * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. - * param isEnable Enable or disable flag. - * param ringId The ring index or ring number. - * retval kStatus_Success Succeed to enable/disable Tx reclaim. - * retval kStatus_Fail Fail to enable/disable Tx reclaim. - */ -status_t ENET_SetTxReclaim(enet_handle_t *handle, bool isEnable, uint8_t ringId) -{ - assert(handle != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId]; - - status_t result = kStatus_Success; - - /* If tx dirty ring is empty, can set this flag and reset txConsumIdx */ - if ((txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) && ENET_TxDirtyRingAvailable(txDirtyRing)) - { - if (isEnable) - { - handle->TxReclaimEnable[ringId] = true; - txBdRing->txConsumIdx = txBdRing->txGenIdx; - } - else - { - handle->TxReclaimEnable[ringId] = false; - } - } - else - { - result = kStatus_Fail; - } - return result; -} - -/*! - * brief Reclaim tx descriptors. - * This function is used to update the tx descriptor status and - * store the tx timestamp when the 1588 feature is enabled. - * This is called by the transmit interupt IRQ handler after the - * complete of a frame transmission. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. - * param ringId The ring index or ring number. - */ -static void ENET_ReclaimTxDescriptor(ENET_Type *base, enet_handle_t *handle, uint8_t ringId) -{ - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txConsumIdx; - enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId]; - enet_frame_info_t *txDirty = NULL; - - /* Need to update the first index for transmit buffer free. */ - while ((0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) && (txBdRing->txDescUsed > 0U)) - { - if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK) != 0U) - { - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txConsumIdx; - txDirtyRing->txConsumIdx = ENET_IncreaseIndex(txDirtyRing->txConsumIdx, txDirtyRing->txRingLen); - txDirtyRing->isFull = false; - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - if ((curBuffDescrip->controlExtend1 & ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK) != 0U) - { - enet_ptp_time_t *ts = &txDirty->timeStamp; - /* Get transmit time stamp second. */ - txDirty->isTsAvail = true; - ts->second = handle->msTimerSecond; - ts->nanosecond = curBuffDescrip->timestamp; - } -#endif - } - - /* For tx buffer free or requeue for each descriptor. - * The tx interrupt callback should free/requeue the tx buffer. */ - if (handle->callback != NULL) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, ringId, kENET_TxEvent, txDirty, handle->userData); -#else - handle->callback(base, handle, kENET_TxEvent, txDirty, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - - /* Clean the txDirty pointer after used */ - if (txDirty != NULL) - { - txDirty = NULL; - } - txBdRing->txDescUsed--; - - /* Update the index. */ - txBdRing->txConsumIdx = ENET_IncreaseIndex(txBdRing->txConsumIdx, txBdRing->txRingLen); - curBuffDescrip = txBdRing->txBdBase + txBdRing->txConsumIdx; - } -} - -/*! - * brief Get a receive buffer pointer of the ENET device for specified ring. - * - * This function can get the data address which stores frame. Then can analyze these data directly without doing any - * memory copy. When the frame locates in multiple BD buffer, need to repeat calling this function until isLastBuff=true - * (need to store the temp buf pointer everytime call this function). After finishing the analysis of this frame, - * call ENET_ReleaseRxBuffer to release rxbuff memory to DMA. - * This is an example: - * code - * uint32_t length; - * uint8_t *buf = NULL; - * uint32_t data_len = 0; - * bool isLastBuff = false; - * enet_handle_t g_handle; - * status_t status; - * status = ENET_GetRxFrameSize(&g_handle, &length, 0); - * if (length != 0) - * { - * ENET_GetRxBuffer(EXAMPLE_ENET, &g_handle, &buf, &data_len, 0, &isLastBuff, NULL); - * ENET_ReleaseRxBuffer(EXAMPLE_ENET, &g_handle, buf, 0); - * } - * endcode - * param base ENET peripheral base address. - * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. - * param buffer The data buffer pointer to store the frame. - * param length The size of the data buffer. If isLastBuff=false, it represents data length of this buffer. If - * isLastBuff=true, it represents data length of total frame. - * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - * param isLastBuff The flag represents whether this buffer is the last buffer to store frame. - * param ts The 1588 timestamp value, vaild in last buffer. - * retval kStatus_Success Get receive buffer succeed. - * retval kStatus_ENET_RxFrameFail Get receive buffer fails, it's owned by application, should wait app to release this - * buffer. - */ -status_t ENET_GetRxBuffer(ENET_Type *base, - enet_handle_t *handle, - void **buffer, - uint32_t *length, - uint8_t ringId, - bool *isLastBuff, - uint32_t *ts) -{ - assert(handle != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - assert(handle->rxBdRing[ringId].rxBdBase != NULL); - - enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId]; - volatile enet_rx_bd_struct_t *curBuffDescrip = rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - uint32_t address; - - /* Check if current rx BD is under usage by certain application */ - /* Buffer owner flag, 1: owned by application, 0: owned by driver */ - if ((curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK) == 0U) - { - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK; - } - else - { - return kStatus_ENET_RxFrameFail; - } - -/* A frame on one buffer or several receive buffers are both considered. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - address = MEMORY_ConvertMemoryMapAddress((uint32_t)curBuffDescrip->buffer, kMEMORY_DMA2Local); -#else - address = (uint32_t)curBuffDescrip->buffer; -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->rxMaintainEnable[ringId]) - { - /* Add the cache invalidate maintain. */ - DCACHE_InvalidateByRange(address, handle->rxBuffSizeAlign[ringId]); - } -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - - *buffer = (void *)(uint32_t *)address; - *length = curBuffDescrip->length; - - /* The last buffer descriptor of a frame. */ - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_LAST_MASK)) - { - /* This is a valid frame. */ - *isLastBuff = true; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - if (ts != NULL) - { - *ts = curBuffDescrip->timestamp; - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - } - else - { - *isLastBuff = false; - } - - /* Increase current buffer descriptor to the next one. */ - rxBdRing->rxGenIdx = ENET_IncreaseIndex(rxBdRing->rxGenIdx, rxBdRing->rxRingLen); - - return kStatus_Success; -} - -/*! - * brief Release receive buffer descriptor to DMA. - * - * This function can release specified BD owned by application, meanwhile it may rearrange the BD to let the no-owned - * BDs always in back of the index of DMA transfer. So for the situation that releasing order is not same as the getting - * order, the rearrangement makes all ready BDs can be used by DMA. - * note This function can't be interrupted by ENET_GetRxBuffer, so in application must make sure ENET_GetRxBuffer is - * called before or after this function. And this function itself isn't thread safe due to BD content exchanging. - * - * param base ENET peripheral base address. - * param handle The ENET handler structure. This is the same handler pointer used in the ENET_Init. - * param buffer The buffer address to store frame, using it to find the correspond BD and release it. - * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - */ -void ENET_ReleaseRxBuffer(ENET_Type *base, enet_handle_t *handle, void *buffer, uint8_t ringId) -{ - assert(handle != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - enet_rx_bd_ring_t *rxBdRing = &handle->rxBdRing[ringId]; - enet_rx_bd_struct_t *ownBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase; - enet_rx_bd_struct_t *blockBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase + rxBdRing->rxGenIdx; - enet_rx_bd_struct_t tempBuffDescrip; - uint16_t index = rxBdRing->rxGenIdx; - bool isReleaseBd = false; - -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - buffer = (void *)(uint32_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)(uint32_t *)buffer, kMEMORY_Local2DMA); -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - - do - { - /* Find the BD for releasing, do nothing if it's not owned by application. */ - if (buffer == ownBuffDescrip->buffer) - { - if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK)) - { - isReleaseBd = true; - break; - } - } - - if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)) - { - break; - } - ownBuffDescrip++; - } while (true); - - if (isReleaseBd) - { - /* Find the first BD owned by application after rxBdCurrent, isReleaseBd is true so there's at least one BD is - * owned by application */ - do - { - if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_SOFTOWNER1_MASK)) - { - break; - } - if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)) - { - blockBuffDescrip = (enet_rx_bd_struct_t *)(uint32_t)rxBdRing->rxBdBase; - } - else - { - blockBuffDescrip++; - } - index = ENET_IncreaseIndex(index, rxBdRing->rxRingLen); - } while (index != rxBdRing->rxGenIdx); - - /* If the BD ready for releasing isn't the first BD owned by application after rxBdCurrent then exchange the two - * BDs */ - if (blockBuffDescrip != ownBuffDescrip) - { - /* Exchange buffer descriptor content */ - tempBuffDescrip = *ownBuffDescrip; - *ownBuffDescrip = *blockBuffDescrip; - *blockBuffDescrip = tempBuffDescrip; - - /* Maintain the wrap flag */ - if (0U != (ownBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)) - { - ownBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_RX_WRAP_MASK); - blockBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - } - else if (0U != (blockBuffDescrip->control & ENET_BUFFDESCRIPTOR_RX_WRAP_MASK)) - { - blockBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_RX_WRAP_MASK); - ownBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - } - else - { - /* Intentional empty */ - } - - /* Clears status including the owner flag. */ - blockBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - /* Sets the receive buffer descriptor with the empty flag. */ - blockBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - } - else - { - /* Clears status including the owner flag. */ - ownBuffDescrip->control &= ENET_BUFFDESCRIPTOR_RX_WRAP_MASK; - /* Sets the receive buffer descriptor with the empty flag. */ - ownBuffDescrip->control |= ENET_BUFFDESCRIPTOR_RX_EMPTY_MASK; - } - - /* Ensure previous data update is completed with Data Synchronization Barrier before activing Rx BD. */ - __DSB(); - - /* Actives the receive buffer descriptor. */ - base->RDAR = ENET_RDAR_RDAR_MASK; - } -} - -/*! - * brief Transmits an ENET frame for specified ring with zero-copy. - * note The CRC is automatically appended to the data. Input the data - * to send without the CRC. The frame must store in continuous memeory - * and need to check the buffer start address alignment based on your - * device, otherwise it has issue or can't get highest DMA transmit speed. - * - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. - * param data The data buffer provided by user to send. - * param length The length of the data to send. - * param ringId The ring index or ring number. - * param tsFlag Timestamp enable flag. - * param context Used by user to handle some events after transmit over. - * retval kStatus_Success Send frame succeed. - * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission. - * The transmit busy happens when the data send rate is over the MAC capacity. - * The waiting mechanism is recommended to be added after each call return with - * kStatus_ENET_TxFrameBusy. - */ -status_t ENET_SendFrameZeroCopy(ENET_Type *base, - enet_handle_t *handle, - const uint8_t *data, - uint32_t length, - uint8_t ringId, - bool tsFlag, - void *context) -{ - assert(handle != NULL); - assert(data != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - volatile enet_tx_bd_struct_t *curBuffDescrip; - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId]; - enet_frame_info_t *txDirty = NULL; - uint32_t len = 0; - uint32_t sizeleft = 0; - status_t result = kStatus_Success; - uint8_t *data_temp; - uint32_t configVal; - bool isReturn = false; - - /* Check the frame length. */ - if (length > ENET_FRAME_MAX_FRAMELEN) - { - result = kStatus_ENET_TxFrameOverLen; - } - else - { - /* Check if the transmit buffer is ready. */ - curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) - { - result = kStatus_ENET_TxFrameBusy; - } - /* Check txDirtyRing if need frameinfo in tx interrupt callback. */ - else if (handle->TxReclaimEnable[ringId] && !ENET_TxDirtyRingAvailable(txDirtyRing)) - { - result = kStatus_ENET_TxFrameBusy; - } - else - { - /* One transmit buffer is enough for one frame. */ - if (handle->txBuffSizeAlign[ringId] >= length) - { - /* Copy data to the buffer for uDMA transfer. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA); -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - curBuffDescrip->buffer = (uint8_t *)(uint32_t)data; - /* Set data length. */ - curBuffDescrip->length = (uint16_t)length; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (tsFlag) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK); - } - -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); - - /* Increase the buffer descriptor address. */ - txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen); - - /* Add context to frame info ring */ - if (handle->TxReclaimEnable[ringId]) - { - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx; - txDirty->context = context; - txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen); - if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) - { - txDirtyRing->isFull = true; - } - txBdRing->txDescUsed++; - } - - /* Active the transmit buffer descriptor. */ - ENET_ActiveSend(base, ringId); - } - else - { - /* One frame requires more than one transmit buffers. */ - do - { -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if (tsFlag) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK); - } -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - /* Update the size left to be transmit. */ - sizeleft = length - len; -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA); -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - data_temp = (uint8_t *)(uint32_t)data + len; - if (sizeleft > handle->txBuffSizeAlign[ringId]) - { - /* Data copy. */ - curBuffDescrip->buffer = data_temp; - /* Data length update. */ - curBuffDescrip->length = handle->txBuffSizeAlign[ringId]; - len += handle->txBuffSizeAlign[ringId]; - /* Sets the control flag. */ - configVal = (uint32_t)curBuffDescrip->control; - configVal &= ~ENET_BUFFDESCRIPTOR_TX_LAST_MASK; - configVal |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; - curBuffDescrip->control = (uint16_t)configVal; - - if (handle->TxReclaimEnable[ringId]) - { - txBdRing->txDescUsed++; - } - /* Active the transmit buffer descriptor*/ - ENET_ActiveSend(base, ringId); - } - else - { - curBuffDescrip->buffer = data_temp; - curBuffDescrip->length = (uint16_t)sizeleft; - /* Set Last buffer wrap flag. */ - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK; - - if (handle->TxReclaimEnable[ringId]) - { - /* Add context to frame info ring */ - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx; - txDirty->context = context; - txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen); - if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) - { - txDirtyRing->isFull = true; - } - txBdRing->txDescUsed++; - } - /* Active the transmit buffer descriptor. */ - ENET_ActiveSend(base, ringId); - isReturn = true; - break; - } - /* Increase and get the current buffer descriptor address. */ - txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen); - curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - - } while (0U == (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)); - - if (isReturn == false) - { - result = kStatus_ENET_TxFrameBusy; - } - } - } - } - return result; -} - -/*! - * brief Set up ENET Tx buffer descriptor, preparing for one frame stores in scattered buffer. - * This function only set one Tx BD everytime calls, all ready data will be sent out with last flag sets or - * gets error. Send frame succeeds with last flag sets, then you can get context from frameInfo in callback. - * note The CRC is automatically appended to the data. Input the data to send without the CRC. And if doesn't - * succeed to call this function, user can't get context in frameInfo of callback. - * - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. This is the same handler pointer used in the ENET_Init. - * param data The data buffer provided by user to send. - * param length The length of the data to send. - * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - * param txFlag This function uses timestamp enable flag, last BD flag. - * param context Used by user to handle some events after transmit over. - * retval kStatus_Success Send frame succeed. - * retval kStatus_ENET_TxFrameOverLen Buffer length isn't enough to store data. - * retval kStatus_ENET_TxFrameBusy Transmit buffer descriptor is busy under transmission. - * The transmit busy happens when the data send rate is over the MAC capacity. - */ -status_t ENET_SetTxBuffer(ENET_Type *base, - enet_handle_t *handle, - const uint8_t *data, - uint32_t length, - uint8_t ringId, - uint8_t txFlag, - void *context) -{ - assert(handle != NULL); - assert(data != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - enet_tx_dirty_ring_t *txDirtyRing = &handle->txDirtyRing[ringId]; - enet_frame_info_t *txDirty = NULL; - volatile enet_tx_bd_struct_t *curBuffDescrip; - volatile enet_tx_bd_struct_t *tempBuffDescrip; - status_t result = kStatus_Success; - uint16_t index; - - /* Check the data length. */ - if (handle->txBuffSizeAlign[ringId] < length) - { - result = kStatus_ENET_TxFrameOverLen; - } - /* Check txDirtyRing if need frameinfo in tx interrupt callback. */ - else if (handle->TxReclaimEnable[ringId] && !ENET_TxDirtyRingAvailable(txDirtyRing)) - { - result = kStatus_ENET_TxFrameBusy; - } - else - { - /* Check if the transmit buffer is ready or ring with framinfo is full. */ - curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - if (0U != (curBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) - { - result = kStatus_ENET_TxFrameBusy; - } - else - { - /* Prepare data address for uDMA transfer. */ -#if defined(FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET) && FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET - data = (uint8_t *)MEMORY_ConvertMemoryMapAddress((uint32_t)data, kMEMORY_Local2DMA); -#endif /* FSL_FEATURE_MEMORY_HAS_ADDRESS_OFFSET */ - curBuffDescrip->buffer = (uint8_t *)(uint32_t)data; - - /* Set data length. */ - curBuffDescrip->length = (uint16_t)length; -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE - /* For enable the timestamp. */ - if ((txFlag & ENET_TX_TIMESTAMP_FLAG) != 0U) - { - curBuffDescrip->controlExtend1 |= ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK; - } - else - { - curBuffDescrip->controlExtend1 &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_TIMESTAMP_MASK); - } - -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - - if (handle->TxReclaimEnable[ringId]) - { - txBdRing->txDescUsed++; - } - /* If BD is full or last flag sets, send out all data */ - if ((txFlag & ENET_TX_LAST_BD_FLAG) != 0U) - { - /* Set all configurated BDs with own flag ready */ - tempBuffDescrip = curBuffDescrip; - index = txBdRing->txGenIdx; - do - { - if ((tempBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK) != 0U) - { - tempBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK); - tempBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; - } - index = ENET_IncreaseIndex(index, txBdRing->txRingLen); - tempBuffDescrip = txBdRing->txBdBase + index; - } while (tempBuffDescrip != curBuffDescrip); - - /* Add context to frame info ring */ - if (handle->TxReclaimEnable[ringId]) - { - txDirty = txDirtyRing->txDirtyBase + txDirtyRing->txGenIdx; - txDirty->context = context; - txDirtyRing->txGenIdx = ENET_IncreaseIndex(txDirtyRing->txGenIdx, txDirtyRing->txRingLen); - if (txDirtyRing->txGenIdx == txDirtyRing->txConsumIdx) - { - txDirtyRing->isFull = true; - } - } - - curBuffDescrip->control |= (ENET_BUFFDESCRIPTOR_TX_READY_MASK | ENET_BUFFDESCRIPTOR_TX_LAST_MASK); - - /* Active the transmit buffer descriptor. */ - ENET_ActiveSend(base, 0); - } - else - { - curBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_LAST_MASK); - /* Set owner flag, need to set Tx ready for all BDs with this flag after configurating last BD */ - curBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK; - } - - /* Increase the buffer descriptor address. */ - txBdRing->txGenIdx = ENET_IncreaseIndex(txBdRing->txGenIdx, txBdRing->txRingLen); - } - } - - /* If fails to send whole frame success, need to send out all left ready data in BDs, make sure. */ - if (result != kStatus_Success) - { - tempBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - index = txBdRing->txGenIdx; - do - { - if ((tempBuffDescrip->control & ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK) != 0U) - { - tempBuffDescrip->control &= (uint16_t)(~ENET_BUFFDESCRIPTOR_TX_SOFTOWENER1_MASK); - tempBuffDescrip->control |= ENET_BUFFDESCRIPTOR_TX_READY_MASK; - } - index = ENET_IncreaseIndex(index, txBdRing->txRingLen); - tempBuffDescrip = txBdRing->txBdBase + index; - } while (index != txBdRing->txGenIdx); - } - - return result; -} - -/*! - * brief Adds the ENET device to a multicast group. - * - * param base ENET peripheral base address. - * param address The six-byte multicast group address which is provided by application. - */ -void ENET_AddMulticastGroup(ENET_Type *base, uint8_t *address) -{ - assert(address != NULL); - - uint32_t crc = 0xFFFFFFFFU; - uint32_t count1 = 0; - uint32_t count2 = 0; - uint32_t configVal = 0; - - /* Calculates the CRC-32 polynomial on the multicast group address. */ - for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++) - { - uint8_t c = address[count1]; - for (count2 = 0; count2 < 0x08U; count2++) - { - if (0U != ((c ^ crc) & 1U)) - { - crc >>= 1U; - c >>= 1U; - crc ^= 0xEDB88320U; - } - else - { - crc >>= 1U; - c >>= 1U; - } - } - } - - /* Enable a multicast group address. */ - configVal = 1U; - configVal = configVal << ((crc >> 0x1AU) & 0x1FU); - - if (0U == ((crc >> 0x1FU) & 1U)) - { - base->GALR |= configVal; - } - else - { - base->GAUR |= configVal; - } -} - -/*! - * brief Moves the ENET device from a multicast group. - * - * param base ENET peripheral base address. - * param address The six-byte multicast group address which is provided by application. - */ -void ENET_LeaveMulticastGroup(ENET_Type *base, uint8_t *address) -{ - assert(address != NULL); - - uint32_t crc = 0xFFFFFFFFU; - uint32_t count1 = 0; - uint32_t count2 = 0; - uint32_t configVal = 0; - - /* Calculates the CRC-32 polynomial on the multicast group address. */ - for (count1 = 0; count1 < ENET_FRAME_MACLEN; count1++) - { - uint8_t c = address[count1]; - for (count2 = 0; count2 < 0x08U; count2++) - { - if (0U != ((c ^ crc) & 1U)) - { - crc >>= 1U; - c >>= 1U; - crc ^= 0xEDB88320U; - } - else - { - crc >>= 1U; - c >>= 1U; - } - } - } - - /* Set the hash table. */ - configVal = 1U; - configVal = ~(configVal << ((crc >> 0x1AU) & 0x1FU)); - if (0U == ((crc >> 0x1FU) & 1U)) - { - base->GALR &= configVal; - } - else - { - base->GAUR &= configVal; - } -} - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE -/*! - * brief Gets the ENET transmit frame statistics after the data send for specified ring. - * - * This interface gets the error statistics of the transmit frame. - * Because the error information is reported by the uDMA after the data delivery, this interface - * should be called after the data transmit API. It is recommended to call this function on - * transmit interrupt handler. After calling the ENET_SendFrame, the - * transmit interrupt notifies the transmit completion. - * - * param handle The PTP handler pointer. This is the same handler pointer used in the ENET_Init. - * param eErrorStatic The error statistics structure pointer. - * param ringId The ring index, range from 0 ~ FSL_FEATURE_ENET_QUEUE - 1. - * return The execute status. - */ -status_t ENET_GetTxErrAfterSendFrame(enet_handle_t *handle, enet_data_error_stats_t *eErrorStatic, uint8_t ringId) -{ - assert(handle != NULL); - assert(eErrorStatic != NULL); - assert(ringId < (uint8_t)FSL_FEATURE_ENET_QUEUE); - - uint16_t control = 0; - uint16_t controlExt = 0; - status_t result = kStatus_Success; - bool isReturn = false; - enet_tx_bd_ring_t *txBdRing = &handle->txBdRing[ringId]; - volatile enet_tx_bd_struct_t *curBuffDescrip = txBdRing->txBdBase + txBdRing->txGenIdx; - - do - { - /* Get the current dirty transmit buffer descriptor. */ - control = handle->txBdDirtyStatic[ringId]->control; - controlExt = handle->txBdDirtyStatic[ringId]->controlExtend0; - - /* Get the control status data, If the buffer descriptor has not been processed break out. */ - if (0U != (control & ENET_BUFFDESCRIPTOR_TX_READY_MASK)) - { - result = kStatus_ENET_TxFrameBusy; - isReturn = true; - break; - } - - /* Increase the transmit dirty static pointer. */ - if (0U != (handle->txBdDirtyStatic[ringId]->control & ENET_BUFFDESCRIPTOR_TX_WRAP_MASK)) - { - handle->txBdDirtyStatic[ringId] = txBdRing->txBdBase; - } - else - { - handle->txBdDirtyStatic[ringId]++; - } - - /* If the transmit buffer descriptor is ready and the last buffer descriptor, store packet statistic. */ - if (0U != (control & ENET_BUFFDESCRIPTOR_TX_LAST_MASK)) - { - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_ERR_MASK)) - { - /* Transmit error. */ - eErrorStatic->statsTxErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_EXCCOLLISIONERR_MASK)) - { - /* Transmit excess collision error. */ - eErrorStatic->statsTxExcessCollisionErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_LATECOLLISIONERR_MASK)) - { - /* Transmit late collision error. */ - eErrorStatic->statsTxLateCollisionErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_UNDERFLOWERR_MASK)) - { - /* Transmit under flow error. */ - eErrorStatic->statsTxUnderFlowErr++; - } - if (0U != (controlExt & ENET_BUFFDESCRIPTOR_TX_OVERFLOWERR_MASK)) - { - /* Transmit over flow error. */ - eErrorStatic->statsTxOverFlowErr++; - } - isReturn = true; - break; - } - - } while (handle->txBdDirtyStatic[ringId] != curBuffDescrip); - - if (isReturn == false) - { - result = kStatus_ENET_TxFrameFail; - } - return result; -} - -void ENET_Ptp1588ConfigureHandler(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig) -{ - assert(handle != NULL); - assert(ptpConfig != NULL); - uint8_t count; - - uint32_t mask = (uint32_t)kENET_TxBufferInterrupt; -#if FSL_FEATURE_ENET_QUEUE > 1 - mask |= (uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxBuffer2Interrupt; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - - for (count = 0; count < handle->ringNum; count++) - { - handle->txBdDirtyStatic[count] = handle->txBdRing[count].txBdBase; - } - - /* Setting the receive and transmit state for transaction. */ - handle->msTimerSecond = 0; - - /* Enables the time stamp interrupt and transmit frame interrupt to - * handle the time-stamp . */ - ENET_EnableInterrupts(base, (ENET_TS_INTERRUPT | ENET_TX_INTERRUPT)); - ENET_DisableInterrupts(base, mask); - - /* Set the IRQ handler when the interrupt is enabled. */ - ENET_SetTsISRHandler(base, ENET_TimeStampIRQHandler); - ENET_SetTxISRHandler(base, ENET_TransmitIRQHandler); -} - -/*! - * brief Configures the ENET PTP IEEE 1588 feature with the basic configuration. - * The function sets the clock for PTP 1588 timer and enables - * time stamp interrupts and transmit interrupts for PTP 1588 features. - * This API should be called when the 1588 feature is enabled - * or the ENET_ENHANCEDBUFFERDESCRIPTOR_MODE is defined. - * ENET_Init should be called before calling this API. - * - * note The PTP 1588 time-stamp second increase though time-stamp interrupt handler - * and the transmit time-stamp store is done through transmit interrupt handler. - * As a result, the TS interrupt and TX interrupt are enabled when you call this API. - * - * param base ENET peripheral base address. - * param handle ENET handler pointer. - * param ptpConfig The ENET PTP1588 configuration. - */ -void ENET_Ptp1588Configure(ENET_Type *base, enet_handle_t *handle, enet_ptp_config_t *ptpConfig) -{ - assert(handle != NULL); - assert(ptpConfig != NULL); - - /* Start the 1588 timer. */ - ENET_Ptp1588StartTimer(base, ptpConfig->ptp1588ClockSrc_Hz); - - ENET_Ptp1588ConfigureHandler(base, handle, ptpConfig); -} - -/*! - * brief Starts the ENET PTP 1588 Timer. - * This function is used to initialize the PTP timer. After the PTP starts, - * the PTP timer starts running. - * - * param base ENET peripheral base address. - * param ptpClkSrc The clock source of the PTP timer. - */ -void ENET_Ptp1588StartTimer(ENET_Type *base, uint32_t ptpClkSrc) -{ - /* Restart PTP 1588 timer, master clock. */ - base->ATCR = ENET_ATCR_RESTART_MASK; - - /* Initializes PTP 1588 timer. */ - base->ATINC = ENET_ATINC_INC(ENET_NANOSECOND_ONE_SECOND / ptpClkSrc); - base->ATPER = ENET_NANOSECOND_ONE_SECOND; - /* Sets periodical event and the event signal output assertion and Actives PTP 1588 timer. */ - base->ATCR = ENET_ATCR_PEREN_MASK | ENET_ATCR_PINPER_MASK | ENET_ATCR_EN_MASK; -} - -/*! - * brief Gets the current ENET time from the PTP 1588 timer. - * Interrupts are not disabled. - * - * param base ENET peripheral base address. - * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init. - * param ptpTime The PTP timer structure. - */ -void ENET_Ptp1588GetTimerNoIrqDisable(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime) -{ - uint16_t count = ENET_1588TIME_DELAY_COUNT; - - /* Get the current PTP time. */ - ptpTime->second = handle->msTimerSecond; - /* Get the nanosecond from the master timer. */ - base->ATCR |= ENET_ATCR_CAPTURE_MASK; - /* Add at least six clock cycle delay to get accurate time. - It's the requirement when the 1588 clock source is slower - than the register clock. - */ - while (0U != (count--)) - { - __NOP(); - } - /* Get the captured time. */ - ptpTime->nanosecond = base->ATVR; -} - -/*! - * brief Gets the current ENET time from the PTP 1588 timer. - * - * param base ENET peripheral base address. - * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init. - * param ptpTime The PTP timer structure. - */ -void ENET_Ptp1588GetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime) -{ - assert(handle != NULL); - assert(ptpTime != NULL); - uint32_t primask; - - /* Disables the interrupt. */ - primask = DisableGlobalIRQ(); - - ENET_Ptp1588GetTimerNoIrqDisable(base, handle, ptpTime); - - /* Get PTP timer wrap event. */ - if (0U != (base->EIR & (uint32_t)kENET_TsTimerInterrupt)) - { - ptpTime->second++; - } - - /* Enables the interrupt. */ - EnableGlobalIRQ(primask); -} - -/*! - * brief Sets the ENET PTP 1588 timer to the assigned time. - * - * param base ENET peripheral base address. - * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init. - * param ptpTime The timer to be set to the PTP timer. - */ -void ENET_Ptp1588SetTimer(ENET_Type *base, enet_handle_t *handle, enet_ptp_time_t *ptpTime) -{ - assert(handle != NULL); - assert(ptpTime != NULL); - - uint32_t primask; - - /* Disables the interrupt. */ - primask = DisableGlobalIRQ(); - - /* Sets PTP timer. */ - handle->msTimerSecond = ptpTime->second; - base->ATVR = ptpTime->nanosecond; - - /* Enables the interrupt. */ - EnableGlobalIRQ(primask); -} - -/*! - * brief Adjusts the ENET PTP 1588 timer. - * - * param base ENET peripheral base address. - * param corrIncrease The correction increment value. This value is added every time the correction - * timer expires. A value less than the PTP timer frequency(1/ptpClkSrc) slows down the timer, - * a value greater than the 1/ptpClkSrc speeds up the timer. - * param corrPeriod The PTP timer correction counter wrap-around value. This defines after how - * many timer clock the correction counter should be reset and trigger a correction - * increment on the timer. A value of 0 disables the correction counter and no correction occurs. - */ -void ENET_Ptp1588AdjustTimer(ENET_Type *base, uint32_t corrIncrease, uint32_t corrPeriod) -{ - /* Set correction for PTP timer increment. */ - base->ATINC = (base->ATINC & ~ENET_ATINC_INC_CORR_MASK) | (corrIncrease << ENET_ATINC_INC_CORR_SHIFT); - /* Set correction for PTP timer period. */ - base->ATCOR = (base->ATCOR & ~ENET_ATCOR_COR_MASK) | (corrPeriod << ENET_ATCOR_COR_SHIFT); -} - -#if defined(FSL_FEATURE_ENET_HAS_AVB) && FSL_FEATURE_ENET_HAS_AVB -/*! - * brief Sets the ENET AVB feature. - * - * ENET AVB feature configuration, set the Receive classification match and transmit - * bandwidth. This API is called when the AVB feature is required. - * - * Note: The AVB frames transmission scheme is credit-based tx scheme and it's only supported - * with the Enhanced buffer descriptors. so the AVB configuration should only done with - * Enhanced buffer descriptor. so when the AVB feature is required, please make sure the - * the "ENET_ENHANCEDBUFFERDESCRIPTOR_MODE" is defined. - * - * param base ENET peripheral base address. - * param handle ENET handler pointer. - * param config The ENET AVB feature configuration structure. - */ -void ENET_AVBConfigure(ENET_Type *base, enet_handle_t *handle, const enet_avb_config_t *config) -{ - assert(config != NULL); - - uint8_t count = 0; - - for (count = 0; count < (uint8_t)FSL_FEATURE_ENET_QUEUE - 1U; count++) - { - /* Set the AVB receive ring classification match when the match is not 0. */ - if (0U != (config->rxClassifyMatch[count])) - { - base->RCMR[count] = ((uint32_t)config->rxClassifyMatch[count] & 0xFFFFU) | ENET_RCMR_MATCHEN_MASK; - } - /* Set the dma controller for the extended ring. */ - base->DMACFG[count] |= ENET_DMACFG_IDLE_SLOPE(config->idleSlope[count]); - } - - /* Shall use the credit-based scheme for avb. */ - base->QOS &= ~ENET_QOS_TX_SCHEME_MASK; - base->QOS |= ENET_QOS_RX_FLUSH0_MASK; -} -#endif /* FSL_FETAURE_ENET_HAS_AVB */ -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - -#if FSL_FEATURE_ENET_QUEUE > 1 -/*! - * brief The transmit IRQ handler. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. - */ -void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId) -#else -/*! - * brief The transmit IRQ handler. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. - */ -void ENET_TransmitIRQHandler(ENET_Type *base, enet_handle_t *handle) -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ -{ - assert(handle != NULL); - uint32_t mask = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt; - uint32_t index = 0; - uint32_t irq; - -/* Check if the transmit interrupt happen. */ -#if FSL_FEATURE_ENET_QUEUE > 1 - switch (ringId) - { - case kENET_Ring1: - mask = ((uint32_t)kENET_TxFrame1Interrupt | (uint32_t)kENET_TxBuffer1Interrupt); - break; - case kENET_Ring2: - mask = ((uint32_t)kENET_TxFrame2Interrupt | (uint32_t)kENET_TxBuffer2Interrupt); - break; - default: - mask = (uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt; - break; - } - index = ringId; -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - - while (0U != (mask & base->EIR)) - { - irq = base->EIR; - - /* Clear the transmit interrupt event. */ - base->EIR = mask; - - /* Callback Handler. */ - if (handle->TxReclaimEnable[index] && (0U != (irq & (uint32_t)kENET_TxFrameInterrupt))) - { - ENET_ReclaimTxDescriptor(base, handle, (uint8_t)index); - } - else - { - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, index, kENET_TxEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_TxEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } - } -} - -#if FSL_FEATURE_ENET_QUEUE > 1 -/*! - * brief The receive IRQ handler. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. - */ -void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle, uint32_t ringId) -#else -/*! - * brief The receive IRQ handler. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. - */ -void ENET_ReceiveIRQHandler(ENET_Type *base, enet_handle_t *handle) -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ -{ - assert(handle != NULL); - uint32_t mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt; - -/* Check if the receive interrupt happen. */ -#if FSL_FEATURE_ENET_QUEUE > 1 - switch (ringId) - { - case kENET_Ring1: - mask = ((uint32_t)kENET_RxFrame1Interrupt | (uint32_t)kENET_RxBuffer1Interrupt); - break; - case kENET_Ring2: - mask = ((uint32_t)kENET_RxFrame2Interrupt | (uint32_t)kENET_RxBuffer2Interrupt); - break; - default: - mask = (uint32_t)kENET_RxFrameInterrupt | (uint32_t)kENET_RxBufferInterrupt; - break; - } -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - - while (0U != (mask & base->EIR)) - { - /* Clear the transmit interrupt event. */ - base->EIR = mask; - - /* Callback function. */ - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, ringId, kENET_RxEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_RxEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } -} - -/*! - * brief Some special IRQ handler including the error, mii, wakeup irq handler. - * - * param base ENET peripheral base address. - * param handle The ENET handler pointer. - */ -void ENET_ErrorIRQHandler(ENET_Type *base, enet_handle_t *handle) -{ - assert(handle != NULL); - - uint32_t errMask = (uint32_t)kENET_BabrInterrupt | (uint32_t)kENET_BabtInterrupt | (uint32_t)kENET_EBusERInterrupt | - (uint32_t)kENET_PayloadRxInterrupt | (uint32_t)kENET_LateCollisionInterrupt | - (uint32_t)kENET_RetryLimitInterrupt | (uint32_t)kENET_UnderrunInterrupt; - - /* Check if the error interrupt happen. */ - if (0U != ((uint32_t)kENET_WakeupInterrupt & base->EIR)) - { - /* Clear the wakeup interrupt. */ - base->EIR = (uint32_t)kENET_WakeupInterrupt; - /* wake up and enter the normal mode. */ - ENET_EnableSleepMode(base, false); - /* Callback function. */ - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, 0, kENET_WakeUpEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_WakeUpEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } - else - { - /* Clear the error interrupt event status. */ - errMask &= base->EIR; - base->EIR = errMask; - /* Callback function. */ - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, 0, kENET_ErrEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_ErrEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } - SDK_ISR_EXIT_BARRIER; -} - -#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE -/*! - * brief The IEEE 1588 PTP time stamp interrupt handler. - * - * param base ENET peripheral base address. - * param handle The ENET state pointer. This is the same state pointer used in the ENET_Init. - */ -void ENET_TimeStampIRQHandler(ENET_Type *base, enet_handle_t *handle) -{ - assert(handle != NULL); - - /* Check if the PTP time stamp interrupt happen. */ - if (0U != ((uint32_t)kENET_TsTimerInterrupt & base->EIR)) - { - /* Clear the time stamp interrupt. */ - base->EIR = (uint32_t)kENET_TsTimerInterrupt; - - /* Increase timer second counter. */ - handle->msTimerSecond++; - - /* Callback function. */ - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, 0, kENET_TimeStampEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_TimeStampEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } - - if (0U != ((uint32_t)kENET_TsAvailInterrupt & base->EIR)) - { - /* Clear the time stamp interrupt. */ - base->EIR = (uint32_t)kENET_TsAvailInterrupt; - /* Callback function. */ - if (NULL != handle->callback) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - handle->callback(base, handle, 0, kENET_TimeStampAvailEvent, NULL, handle->userData); -#else - handle->callback(base, handle, kENET_TimeStampAvailEvent, NULL, handle->userData); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ENET_ENHANCEDBUFFERDESCRIPTOR_MODE */ - -/*! - * brief the common IRQ handler for the tx/rx/error etc irq handler. - * - * This is used for the combined tx/rx/error interrupt for single/mutli-ring (frame 0). - * - * param base ENET peripheral base address. - */ -void ENET_CommonFrame0IRQHandler(ENET_Type *base) -{ - uint32_t event = base->EIR; - uint32_t instance = ENET_GetInstance(base); - - if (0U != (event & ((uint32_t)kENET_TxBufferInterrupt | (uint32_t)kENET_TxFrameInterrupt))) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - s_enetTxIsr[instance](base, s_ENETHandle[instance], 0); -#else - s_enetTxIsr[instance](base, s_ENETHandle[instance]); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - - if (0U != (event & ((uint32_t)kENET_RxBufferInterrupt | (uint32_t)kENET_RxFrameInterrupt))) - { -#if FSL_FEATURE_ENET_QUEUE > 1 - s_enetRxIsr[instance](base, s_ENETHandle[instance], 0); -#else - s_enetRxIsr[instance](base, s_ENETHandle[instance]); -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - } - - if (0U != (event & ENET_TS_INTERRUPT) && (NULL != s_enetTsIsr[instance])) - { - s_enetTsIsr[instance](base, s_ENETHandle[instance]); - } - if (0U != (event & ENET_ERR_INTERRUPT) && (NULL != s_enetErrIsr[instance])) - { - s_enetErrIsr[instance](base, s_ENETHandle[instance]); - } - SDK_ISR_EXIT_BARRIER; -} - -#if FSL_FEATURE_ENET_QUEUE > 1 -/*! - * brief the common IRQ handler for the tx/rx irq handler. - * - * This is used for the combined tx/rx interrupt for multi-ring (frame 1). - * - * param base ENET peripheral base address. - */ -void ENET_CommonFrame1IRQHandler(ENET_Type *base) -{ - uint32_t event = base->EIR; - uint32_t instance = ENET_GetInstance(base); - - if (0U != (event & ((uint32_t)kENET_TxBuffer1Interrupt | (uint32_t)kENET_TxFrame1Interrupt))) - { - s_enetTxIsr[instance](base, s_ENETHandle[instance], 1); - } - - if (0U != (event & ((uint32_t)kENET_RxBuffer1Interrupt | (uint32_t)kENET_RxFrame1Interrupt))) - { - s_enetRxIsr[instance](base, s_ENETHandle[instance], 1); - } - SDK_ISR_EXIT_BARRIER; -} - -/*! - * brief the common IRQ handler for the tx/rx irq handler. - * - * This is used for the combined tx/rx interrupt for multi-ring (frame 2). - * - * param base ENET peripheral base address. - */ -void ENET_CommonFrame2IRQHandler(ENET_Type *base) -{ - uint32_t event = base->EIR; - uint32_t instance = ENET_GetInstance(base); - - if (0U != (event & ((uint32_t)kENET_TxBuffer2Interrupt | (uint32_t)kENET_TxFrame2Interrupt))) - { - s_enetTxIsr[instance](base, s_ENETHandle[instance], 2); - } - - if (0U != (event & ((uint32_t)kENET_RxBuffer2Interrupt | (uint32_t)kENET_RxFrame2Interrupt))) - { - s_enetRxIsr[instance](base, s_ENETHandle[instance], 2); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* FSL_FEATURE_ENET_QUEUE > 1 */ - -#if defined(ENET) -void ENET_Transmit_IRQHandler(void) -{ - s_enetTxIsr[0](ENET, s_ENETHandle[0]); - SDK_ISR_EXIT_BARRIER; -} - -void ENET_Receive_IRQHandler(void) -{ - s_enetRxIsr[0](ENET, s_ENETHandle[0]); - SDK_ISR_EXIT_BARRIER; -} - -void ENET_Error_IRQHandler(void) -{ - s_enetErrIsr[0](ENET, s_ENETHandle[0]); - SDK_ISR_EXIT_BARRIER; -} - -void ENET_1588_Timer_IRQHandler(void) -{ - s_enetTsIsr[0](ENET, s_ENETHandle[0]); - SDK_ISR_EXIT_BARRIER; -} - -void ENET_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(ENET); - SDK_ISR_EXIT_BARRIER; - SDK_ISR_EXIT_BARRIER; -} - -#endif - -#if defined(ENET1) -void ENET1_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(ENET1); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ENET2) -void ENET2_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(ENET2); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CONNECTIVITY__ENET0) -void CONNECTIVITY_ENET0_FRAME0_EVENT_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET0); - SDK_ISR_EXIT_BARRIER; -} -#if FSL_FEATURE_ENET_QUEUE > 1 -void CONNECTIVITY_ENET0_FRAME1_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET0); - SDK_ISR_EXIT_BARRIER; -} -void CONNECTIVITY_ENET0_FRAME2_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET0); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif -#if defined(CONNECTIVITY__ENET1) -void CONNECTIVITY_ENET1_FRAME0_EVENT_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(CONNECTIVITY__ENET1); - SDK_ISR_EXIT_BARRIER; -} -#if FSL_FEATURE_ENET_QUEUE > 1 -void CONNECTIVITY_ENET1_FRAME1_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame1IRQHandler(CONNECTIVITY__ENET1); - SDK_ISR_EXIT_BARRIER; -} -void CONNECTIVITY_ENET1_FRAME2_INT_DriverIRQHandler(void) -{ - ENET_CommonFrame2IRQHandler(CONNECTIVITY__ENET1); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif -#if FSL_FEATURE_ENET_QUEUE > 1 -#if defined(ENET_1G) -void ENET_1G_DriverIRQHandler(void) -{ - ENET_CommonFrame0IRQHandler(ENET_1G); -/* Added for ARM errata 838869: storing immediate overlapping exception return operation - * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void ENET_MAC0_Tx_Rx_Done_0_DriverIRQHandler(void) -{ - ENET_CommonFrame1IRQHandler(ENET_1G); -/* Added for ARM errata 838869: storing immediate overlapping exception return operation - * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void ENET_MAC0_Tx_Rx_Done_1_DriverIRQHandler(void) -{ - ENET_CommonFrame2IRQHandler(ENET_1G); -/* Added for ARM errata 838869: storing immediate overlapping exception return operation - * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -void ENET_1G_1588_Timer_DriverIRQHandler(void) -{ - s_enet1588TimerIsr(ENET_1G, s_ENETHandle[1]); -/* Added for ARM errata 838869: storing immediate overlapping exception return operation - * might vector to incorrect interrupt, this affects Cortex-M4, Cortex-M4F. */ -#if defined __CORTEX_M && (__CORTEX_M == 4U) - __DSB(); -#endif -} -#endif -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c deleted file mode 100644 index 593cf87a50..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ewm.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017, 2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_ewm.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.ewm" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Initializes the EWM peripheral. - * - * This function is used to initialize the EWM. After calling, the EWM - * runs immediately according to the configuration. - * Note that, except for the interrupt enable control bit, other control bits and registers are write once after a - * CPU reset. Modifying them more than once generates a bus transfer error. - * - * This is an example. - * code - * ewm_config_t config; - * EWM_GetDefaultConfig(&config); - * config.compareHighValue = 0xAAU; - * EWM_Init(ewm_base,&config); - * endcode - * - * param base EWM peripheral base address - * param config The configuration of the EWM - */ -void EWM_Init(EWM_Type *base, const ewm_config_t *config) -{ - assert(NULL != config); - - uint8_t value = 0U; - -#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ - (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_EnableClock(kCLOCK_Ewm0); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -#endif - value = EWM_CTRL_EWMEN(config->enableEwm) | EWM_CTRL_ASSIN(config->setInputAssertLogic) | - EWM_CTRL_INEN(config->enableEwmInput) | EWM_CTRL_INTEN(config->enableInterrupt); -#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER - base->CLKPRESCALER = config->prescaler; -#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ - -#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT - base->CLKCTRL = (uint8_t)config->clockSource; -#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ - - base->CMPL = config->compareLowValue; - base->CMPH = config->compareHighValue; - base->CTRL = value; -} - -/*! - * brief Deinitializes the EWM peripheral. - * - * This function is used to shut down the EWM. - * - * param base EWM peripheral base address - */ -void EWM_Deinit(EWM_Type *base) -{ - EWM_DisableInterrupts(base, (uint32_t)kEWM_InterruptEnable); -#if !((defined(FSL_FEATURE_SOC_PCC_COUNT) && FSL_FEATURE_SOC_PCC_COUNT) && \ - (defined(FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE) && FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE)) -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(kCLOCK_Ewm0); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -#endif /* FSL_FEATURE_PCC_SUPPORT_EWM_CLOCK_REMOVE */ -} - -/*! - * brief Initializes the EWM configuration structure. - * - * This function initializes the EWM configuration structure to default values. The default - * values are as follows. - * code - * ewmConfig->enableEwm = true; - * ewmConfig->enableEwmInput = false; - * ewmConfig->setInputAssertLogic = false; - * ewmConfig->enableInterrupt = false; - * ewmConfig->ewm_lpo_clock_source_t = kEWM_LpoClockSource0; - * ewmConfig->prescaler = 0; - * ewmConfig->compareLowValue = 0; - * ewmConfig->compareHighValue = 0xFEU; - * endcode - * - * param config Pointer to the EWM configuration structure. - * see ewm_config_t - */ -void EWM_GetDefaultConfig(ewm_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableEwm = true; - config->enableEwmInput = false; - config->setInputAssertLogic = false; - config->enableInterrupt = false; -#if defined(FSL_FEATURE_EWM_HAS_CLOCK_SELECT) && FSL_FEATURE_EWM_HAS_CLOCK_SELECT - config->clockSource = kEWM_LpoClockSource0; -#endif /* FSL_FEATURE_EWM_HAS_CLOCK_SELECT*/ -#if defined(FSL_FEATURE_EWM_HAS_PRESCALER) && FSL_FEATURE_EWM_HAS_PRESCALER - config->prescaler = 0U; -#endif /* FSL_FEATURE_EWM_HAS_PRESCALER */ - config->compareLowValue = 0U; - config->compareHighValue = 0xFEU; -} - -/*! - * brief Services the EWM. - * - * This function resets the EWM counter to zero. - * - * param base EWM peripheral base address - */ -void EWM_Refresh(EWM_Type *base) -{ - uint32_t primaskValue = 0U; - - /* Disable the global interrupt to protect refresh sequence */ - primaskValue = DisableGlobalIRQ(); - base->SERV = (uint8_t)0xB4U; - base->SERV = (uint8_t)0x2CU; - EnableGlobalIRQ(primaskValue); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c deleted file mode 100644 index 682dae7492..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexcan.c +++ /dev/null @@ -1,3564 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexcan.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexcan" -#endif - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) -#define RXINTERMISSION (CAN_DBG1_CFSM(0x2f)) -#define TXINTERMISSION (CAN_DBG1_CFSM(0x14)) -#define BUSIDLE (CAN_DBG1_CFSM(0x02)) -#define CBN_VALUE3 (CAN_DBG1_CBN(0x03)) -#define DELAY_BUSIDLE (200) -#endif - -#define IDEAL_SP_LOW (750U) -#define IDEAL_SP_MID (800U) -#define IDEAL_SP_HIGH (875U) -#define IDEAL_SP_FACTOR (1000U) - -#define MAX_PROPSEG (CAN_CTRL1_PROPSEG_MASK >> CAN_CTRL1_PROPSEG_SHIFT) -#define MAX_PSEG1 (CAN_CTRL1_PSEG1_MASK >> CAN_CTRL1_PSEG1_SHIFT) -#define MAX_PSEG2 (CAN_CTRL1_PSEG2_MASK >> CAN_CTRL1_PSEG2_SHIFT) -#define MAX_RJW (CAN_CTRL1_RJW_MASK >> CAN_CTRL1_RJW_SHIFT) -#define MAX_PRESDIV (CAN_CTRL1_PRESDIV_MASK >> CAN_CTRL1_PRESDIV_SHIFT) -#define CTRL1_MAX_TIME_QUANTA (1U + MAX_PROPSEG + 1U + MAX_PSEG1 + 1U + MAX_PSEG2 + 1U) -#define CTRL1_MIN_TIME_QUANTA (8U) - -#define MAX_EPROPSEG (CAN_CBT_EPROPSEG_MASK >> CAN_CBT_EPROPSEG_SHIFT) -#define MAX_EPSEG1 (CAN_CBT_EPSEG1_MASK >> CAN_CBT_EPSEG1_SHIFT) -#define MAX_EPSEG2 (CAN_CBT_EPSEG2_MASK >> CAN_CBT_EPSEG2_SHIFT) -#define MAX_ERJW (CAN_CBT_ERJW_MASK >> CAN_CBT_ERJW_SHIFT) -#define MAX_EPRESDIV (CAN_CBT_EPRESDIV_MASK >> CAN_CBT_EPRESDIV_SHIFT) -#define CBT_MAX_TIME_QUANTA (1U + MAX_EPROPSEG + 1U + MAX_EPSEG1 + 1U + MAX_EPSEG2 + 1U) -#define CBT_MIN_TIME_QUANTA (8U) - -#define MAX_FPROPSEG (CAN_FDCBT_FPROPSEG_MASK >> CAN_FDCBT_FPROPSEG_SHIFT) -#define MAX_FPSEG1 (CAN_FDCBT_FPSEG1_MASK >> CAN_FDCBT_FPSEG1_SHIFT) -#define MAX_FPSEG2 (CAN_FDCBT_FPSEG2_MASK >> CAN_FDCBT_FPSEG2_SHIFT) -#define MAX_FRJW (CAN_FDCBT_FRJW_MASK >> CAN_FDCBT_FRJW_SHIFT) -#define MAX_FPRESDIV (CAN_FDCBT_FPRESDIV_MASK >> CAN_FDCBT_FPRESDIV_SHIFT) -#define FDCBT_MAX_TIME_QUANTA (1U + MAX_FPROPSEG + 0U + MAX_FPSEG1 + 1U + MAX_FPSEG2 + 1U) -#define FDCBT_MIN_TIME_QUANTA (5U) - -#define MAX_CANFD_BAUDRATE (8000000U) -#define MAX_CAN_BAUDRATE (1000000U) - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) -#define CAN_ESR1_FLTCONF_BUSOFF CAN_ESR1_FLTCONF(2U) -#endif - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -#ifndef CAN_CLOCK_CHECK_NO_AFFECTS -/* If no define such MACRO, it mean that the CAN in current device have no clock affect issue. */ -#define CAN_CLOCK_CHECK_NO_AFFECTS (true) -#endif /* CAN_CLOCK_CHECK_NO_AFFECTS */ -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief FlexCAN Internal State. */ -enum _flexcan_state -{ - kFLEXCAN_StateIdle = 0x0, /*!< MB/RxFIFO idle.*/ - kFLEXCAN_StateRxData = 0x1, /*!< MB receiving.*/ - kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/ - kFLEXCAN_StateTxData = 0x3, /*!< MB transmitting.*/ - kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/ - kFLEXCAN_StateRxFifo = 0x5, /*!< RxFIFO receiving.*/ -}; - -/*! @brief FlexCAN message buffer CODE for Rx buffers. */ -enum _flexcan_mb_code_rx -{ - kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/ - kFLEXCAN_RxMbFull = 0x2, /*!< MB is full.*/ - kFLEXCAN_RxMbEmpty = 0x4, /*!< MB is active and empty.*/ - kFLEXCAN_RxMbOverrun = 0x6, /*!< MB is overwritten into a full buffer.*/ - kFLEXCAN_RxMbBusy = 0x8, /*!< FlexCAN is updating the contents of the MB.*/ - /*! The CPU must not access the MB.*/ - kFLEXCAN_RxMbRanswer = 0xA, /*!< A frame was configured to recognize a Remote Request Frame */ - /*! and transmit a Response Frame in return.*/ - kFLEXCAN_RxMbNotUsed = 0xF, /*!< Not used.*/ -}; - -/*! @brief FlexCAN message buffer CODE FOR Tx buffers. */ -enum _flexcan_mb_code_tx -{ - kFLEXCAN_TxMbInactive = 0x8, /*!< MB is not active.*/ - kFLEXCAN_TxMbAbort = 0x9, /*!< MB is aborted.*/ - kFLEXCAN_TxMbDataOrRemote = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or */ - /*!< MB is a TX Remote Request Frame (when MB RTR = 1).*/ - kFLEXCAN_TxMbTanswer = 0xE, /*!< MB is a TX Response Request Frame from */ - /*! an incoming Remote Request Frame.*/ - kFLEXCAN_TxMbNotUsed = 0xF, /*!< Not used.*/ -}; - -/* Typedef for interrupt handler. */ -typedef void (*flexcan_isr_t)(CAN_Type *base, flexcan_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -#if !defined(NDEBUG) -/*! - * @brief Check if Message Buffer is occupied by Rx FIFO. - * - * This function check if Message Buffer is occupied by Rx FIFO. - * - * @param base FlexCAN peripheral base address. - * @param mbIdx The FlexCAN Message Buffer index. - */ -static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx); -#endif - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) -/*! - * @brief Get the first valid Message buffer ID of give FlexCAN instance. - * - * This function is a helper function for Errata 5641 workaround. - * - * @param base FlexCAN peripheral base address. - * @return The first valid Message Buffer Number. - */ -static uint8_t FLEXCAN_GetFirstValidMb(CAN_Type *base); -#endif - -/*! - * @brief Check if Message Buffer interrupt is enabled. - * - * This function check if Message Buffer interrupt is enabled. - * - * @param base FlexCAN peripheral base address. - * @param mbIdx The FlexCAN Message Buffer index. - * @return TRUE if the index MB interrupt mask enabled, FALSE if the index MB interrupt mask disabled. - * - */ -static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx); - -/*! - * @brief Reset the FlexCAN Instance. - * - * Restores the FlexCAN module to reset state, notice that this function - * will set all the registers to reset state so the FlexCAN module can not work - * after calling this API. - * - * @param base FlexCAN peripheral base address. - */ -static void FLEXCAN_Reset(CAN_Type *base); - -/*! - * @brief Set Baud Rate of FlexCAN. - * - * This function set the baud rate of FlexCAN. - * - * @param base FlexCAN peripheral base address. - * @param sourceClock_Hz Source Clock in Hz. - * @param baudRate_Bps Baud Rate in Bps. - * @param timingConfig FlexCAN timingConfig. - */ -static void FLEXCAN_SetBaudRate(CAN_Type *base, - uint32_t sourceClock_Hz, - uint32_t baudRate_Bps, - flexcan_timing_config_t timingConfig); -/*! - * @brief Calculates the segment values for a single bit time for classical CAN - * - * @param baudRate The data speed in bps - * @param tqNum Number of time quantas per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_GetSegments(uint32_t baudRate, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig); - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * @brief Set Baud Rate of FlexCAN FD frame. - * - * This function set the baud rate of FlexCAN FD frame. - * - * @param base FlexCAN peripheral base address. - * @param sourceClock_Hz Source Clock in Hz. - * @param baudRateFD_Bps FD frame Baud Rate in Bps. - * @param timingConfig FlexCAN timingConfig. - */ -static void FLEXCAN_SetFDBaudRate(CAN_Type *base, - uint32_t sourceClock_Hz, - uint32_t baudRateFD_Bps, - flexcan_timing_config_t timingConfig); - -/*! - * @brief Get Mailbox offset number by dword. - * - * This function gets the offset number of the specified mailbox. - * Mailbox is not consecutive between memory regions when payload is not 8 bytes - * so need to calculate the specified mailbox address. - * For example, in the first memory region, MB[0].CS address is 0x4002_4080. For 32 bytes - * payload frame, the second mailbox is ((1/12)*512 + 1%12*40)/4 = 10, meaning 10 dword - * after the 0x4002_4080, which is actually the address of mailbox MB[1].CS. - * - * @param base FlexCAN peripheral base address. - * @param mbIdx Mailbox index. - */ -static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx); - -/*! - * @brief Calculates the segment values for a single bit time for CANFD bus control baud Rate - * - * @param baudRate The canfd bus control speed in bps - * @param tqNum Number of time quanta per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_FDGetSegments(uint32_t baudRate, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig); - -/*! - * @brief Calculates the segment values for a single bit time for CANFD bus data baud Rate - * - * @param baudRatebrs The canfd bus data speed in bps - * @param tqNum Number of time quanta per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_FDGetSegmentswithBRS(uint32_t baudRatebrs, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig); - -/*! - * @brief Calculates the improved timing values by specific baudrates for CAN by CBT register - * - * @param baudRate The classical CAN speed in bps defined by user - * @param sourceClock_Hz The Source clock data speed in bps. Zero to disable baudrate switching - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if timing configuration found, FALSE if failed to find configuration - */ -static bool FLEXCAN_CalculateImprovedTimingValuesByCBT(uint32_t baudRate, - uint32_t sourceClock_Hz, - flexcan_timing_config_t *pTimingConfig); -#endif - -/*! - * @brief Check unhandle interrupt events - * - * @param base FlexCAN peripheral base address. - * @return TRUE if unhandled interrupt action exist, FALSE if no unhandlered interrupt action exist. - */ -static bool FLEXCAN_CheckUnhandleInterruptEvents(CAN_Type *base); - -/*! - * @brief Sub Handler Data Trasfered Events - * - * @param base FlexCAN peripheral base address. - * @param handle FlexCAN handle pointer. - * @param pResult Pointer to the Handle result. - * @return the status after handle each data transfered event. - */ -static status_t FLEXCAN_SubHandlerForDataTransfered(CAN_Type *base, flexcan_handle_t *handle, uint32_t *pResult); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Array of FlexCAN peripheral base address. */ -static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS; - -/* Array of FlexCAN IRQ number. */ -static const IRQn_Type s_flexcanRxWarningIRQ[] = CAN_Rx_Warning_IRQS; -static const IRQn_Type s_flexcanTxWarningIRQ[] = CAN_Tx_Warning_IRQS; -static const IRQn_Type s_flexcanWakeUpIRQ[] = CAN_Wake_Up_IRQS; -static const IRQn_Type s_flexcanErrorIRQ[] = CAN_Error_IRQS; -static const IRQn_Type s_flexcanBusOffIRQ[] = CAN_Bus_Off_IRQS; -static const IRQn_Type s_flexcanMbIRQ[] = CAN_ORed_Message_buffer_IRQS; - -/* Array of FlexCAN handle. */ -static flexcan_handle_t *s_flexcanHandle[ARRAY_SIZE(s_flexcanBases)]; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of FlexCAN clock name. */ -static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS; -#if defined(FLEXCAN_PERIPH_CLOCKS) -/* Array of FlexCAN serial clock name. */ -static const clock_ip_name_t s_flexcanPeriphClock[] = FLEXCAN_PERIPH_CLOCKS; -#endif /* FLEXCAN_PERIPH_CLOCKS */ -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/* FlexCAN ISR for transactional APIs. */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -static flexcan_isr_t s_flexcanIsr = (flexcan_isr_t)DefaultISR; -#else -static flexcan_isr_t s_flexcanIsr; -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Get the FlexCAN instance from peripheral base address. - * - * param base FlexCAN peripheral base address. - * return FlexCAN instance. - */ -uint32_t FLEXCAN_GetInstance(CAN_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_flexcanBases); instance++) - { - if (s_flexcanBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_flexcanBases)); - - return instance; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) -void FLEXCAN_EnterFreezeMode(CAN_Type *base) -{ - uint32_t u32TimeoutCount = 0U; - uint32_t u32TempMCR = 0U; - uint32_t u32TempIMASK1 = 0U; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint32_t u32TempIMASK2 = 0U; -#endif - - /* Step1: set FRZ enable in MCR. */ - base->MCR |= CAN_MCR_FRZ_MASK; - - /* Step2: to check if MDIS bit set in MCR. if yes, clear it. */ - if (0U != (base->MCR & CAN_MCR_MDIS_MASK)) - { - base->MCR &= ~CAN_MCR_MDIS_MASK; - } - - /* Step3: polling LPMACK. */ - u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT; - while ((0U == (base->MCR & CAN_MCR_LPMACK_MASK)) && (u32TimeoutCount > 0U)) - { - u32TimeoutCount--; - } - - /* Step4: to check FLTCONF in ESR1 register */ - if (0U == (base->ESR1 & CAN_ESR1_FLTCONF_BUSOFF)) - { - /* Step5B: Set Halt bits. */ - base->MCR |= CAN_MCR_HALT_MASK; - - /* Step6B: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set, timeout need more than 178 - * CAN bit length, so 20 multiply timeout is enough. */ - u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT * 20U; - while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U)) - { - u32TimeoutCount--; - } - } - else - { - /* backup MCR and IMASK register. Errata document not descript it, but we need backup for step 8A and 9A. */ - u32TempMCR = base->MCR; - u32TempIMASK1 = base->IMASK1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - u32TempIMASK2 = base->IMASK2; -#endif - - /* Step5A: Set the Soft Reset bit ((SOFTRST) in the MCR.*/ - base->MCR |= CAN_MCR_SOFTRST_MASK; - - /* Step6A: Poll the MCR register until the Soft Reset (SOFTRST) bit is cleared. */ - u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT; - while ((CAN_MCR_SOFTRST_MASK == (base->MCR & CAN_MCR_SOFTRST_MASK)) && (u32TimeoutCount > 0U)) - { - u32TimeoutCount--; - } - - /* Step7A: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set. */ - u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT; - while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U)) - { - u32TimeoutCount--; - } - - /* Step8A: reconfig MCR. */ - base->MCR = u32TempMCR; - - /* Step9A: reconfig IMASK. */ - base->IMASK1 = u32TempIMASK1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IMASK2 = u32TempIMASK2; -#endif - } -} -#elif (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_8341) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_8341) -void FLEXCAN_EnterFreezeMode(CAN_Type *base) -{ - uint32_t u32TimeoutCount = 0U; - uint32_t u32TempMCR = 0U; - uint32_t u32TempIMASK1 = 0U; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint32_t u32TempIMASK2 = 0U; -#endif - - /* Step1: set FRZ and HALT bit enable in MCR. */ - base->MCR |= CAN_MCR_FRZ_MASK; - base->MCR |= CAN_MCR_HALT_MASK; - - /* Step2: to check if MDIS bit set in MCR. if yes, clear it. */ - if (0U != (base->MCR & CAN_MCR_MDIS_MASK)) - { - base->MCR &= ~CAN_MCR_MDIS_MASK; - } - - /* Step3: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set. */ - u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT * 100U; - while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U)) - { - u32TimeoutCount--; - } - - /* Step4: check whether the timeout reached. if no skip step5 to step8. */ - if (0U == u32TimeoutCount) - { - /* backup MCR and IMASK register. Errata document not descript it, but we need backup for step 8A and 9A. */ - u32TempMCR = base->MCR; - u32TempIMASK1 = base->IMASK1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - u32TempIMASK2 = base->IMASK2; -#endif - /* Step5: Set the Soft Reset bit ((SOFTRST) in the MCR.*/ - base->MCR |= CAN_MCR_SOFTRST_MASK; - - /* Step6: Poll the MCR register until the Soft Reset (SOFTRST) bit is cleared. */ - while (CAN_MCR_SOFTRST_MASK == (base->MCR & CAN_MCR_SOFTRST_MASK)) - { - } - - /* Step7: reconfig MCR. */ - base->MCR = u32TempMCR; - - /* Step8: reconfig IMASK. */ - base->IMASK1 = u32TempIMASK1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IMASK2 = u32TempIMASK2; -#endif - } -} -#else -void FLEXCAN_EnterFreezeMode(CAN_Type *base) -{ - /* Set Freeze, Halt bits. */ - base->MCR |= CAN_MCR_FRZ_MASK; - base->MCR |= CAN_MCR_HALT_MASK; - while (0U == (base->MCR & CAN_MCR_FRZACK_MASK)) - { - } -} -#endif - -void FLEXCAN_ExitFreezeMode(CAN_Type *base) -{ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) - /* Enable to update in MCER. */ - base->CTRL2 |= CAN_CTRL2_ECRWRE_MASK; - base->MECR &= ~CAN_MECR_ECRWRDIS_MASK; -#endif - - /* Clear Freeze, Halt bits. */ - base->MCR &= ~CAN_MCR_HALT_MASK; - base->MCR &= ~CAN_MCR_FRZ_MASK; - - /* Wait until the FlexCAN Module exit freeze mode. */ - while (0U != (base->MCR & CAN_MCR_FRZACK_MASK)) - { - } -} - -#if !defined(NDEBUG) -static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx) -{ - uint8_t lastOccupiedMb; - bool fgRet; - - /* Is Rx FIFO enabled? */ - if (0U != (base->MCR & CAN_MCR_RFEN_MASK)) - { - /* Get RFFN value. */ - lastOccupiedMb = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT); - /* Calculate the number of last Message Buffer occupied by Rx FIFO. */ - lastOccupiedMb = ((lastOccupiedMb + 1U) * 2U) + 5U; - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - /* the first valid MB should be occupied by ERRATA 5461 or 5829. */ - lastOccupiedMb += 1U; -#endif - fgRet = (mbIdx <= lastOccupiedMb); - } - else - { -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - if (0U == mbIdx) - { - fgRet = true; - } - else -#endif - { - fgRet = false; - } - } - - return fgRet; -} -#endif - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) -static uint8_t FLEXCAN_GetFirstValidMb(CAN_Type *base) -{ - uint8_t firstValidMbNum; - - if (0U != (base->MCR & CAN_MCR_RFEN_MASK)) - { - firstValidMbNum = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT); - firstValidMbNum = ((firstValidMbNum + 1U) * 2U) + 6U; - } - else - { - firstValidMbNum = 0U; - } - - return firstValidMbNum; -} -#endif - -static bool FLEXCAN_IsMbIntEnabled(CAN_Type *base, uint8_t mbIdx) -{ - /* Assertion. */ - assert(mbIdx < (uint8_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)); - - uint32_t flag = 1U; - bool fgRet = false; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - if (mbIdx >= 32U) - { - fgRet = (0U != (base->IMASK2 & (flag << (mbIdx - 32U)))); - } - else -#endif - { - fgRet = (0U != (base->IMASK1 & (flag << mbIdx))); - } - - return fgRet; -} - -static void FLEXCAN_Reset(CAN_Type *base) -{ - /* The module must should be first exit from low power - * mode, and then soft reset can be applied. - */ - assert(0U == (base->MCR & CAN_MCR_MDIS_MASK)); - - uint8_t i; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) - if (0 != (FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(base))) - { - /* De-assert DOZE Enable Bit. */ - base->MCR &= ~CAN_MCR_DOZE_MASK; - } -#endif - - /* Wait until FlexCAN exit from any Low Power Mode. */ - while (0U != (base->MCR & CAN_MCR_LPMACK_MASK)) - { - } - - /* Assert Soft Reset Signal. */ - base->MCR |= CAN_MCR_SOFTRST_MASK; - /* Wait until FlexCAN reset completes. */ - while (0U != (base->MCR & CAN_MCR_SOFTRST_MASK)) - { - } - -/* Reset MCR register. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) && FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) - base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_WAKSRC_MASK | - CAN_MCR_MAXMB((uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1U); -#else - base->MCR |= - CAN_MCR_WRNEN_MASK | CAN_MCR_MAXMB((uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1U); -#endif - -/* Reset CTRL1 and CTRL2 register. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - /* SMP bit cannot be asserted when CAN FD is enabled */ - if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base)) - { - base->CTRL1 = 0x0; - } - else - { - base->CTRL1 = CAN_CTRL1_SMP_MASK; - } -#else - base->CTRL1 = CAN_CTRL1_SMP_MASK; -#endif - base->CTRL2 = CAN_CTRL2_TASD(0x16) | CAN_CTRL2_RRS_MASK | CAN_CTRL2_EACEN_MASK; - - /* Clean all individual Rx Mask of Message Buffers. */ - for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++) - { - base->RXIMR[i] = 0x3FFFFFFF; - } - - /* Clean Global Mask of Message Buffers. */ - base->RXMGMASK = 0x3FFFFFFF; - /* Clean Global Mask of Message Buffer 14. */ - base->RX14MASK = 0x3FFFFFFF; - /* Clean Global Mask of Message Buffer 15. */ - base->RX15MASK = 0x3FFFFFFF; - /* Clean Global Mask of Rx FIFO. */ - base->RXFGMASK = 0x3FFFFFFF; - - /* Clean all Message Buffer CS fields. */ - for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++) - { - base->MB[i].CS = 0x0; - } -} - -static void FLEXCAN_SetBaudRate(CAN_Type *base, - uint32_t sourceClock_Hz, - uint32_t baudRate_Bps, - flexcan_timing_config_t timingConfig) -{ - /* FlexCAN timing setting formula: - * quantum = 1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1); - */ - uint32_t quantum = (1U + ((uint32_t)timingConfig.phaseSeg1 + 1U) + ((uint32_t)timingConfig.phaseSeg2 + 1U) + - ((uint32_t)timingConfig.propSeg + 1U)); - uint32_t priDiv = baudRate_Bps * quantum; - - /* Assertion: Desired baud rate is too high. */ - assert(baudRate_Bps <= 1000000U); - /* Assertion: Source clock should greater than baud rate * quantum. */ - assert(priDiv <= sourceClock_Hz); - - if (0U == priDiv) - { - priDiv = 1; - } - - priDiv = (sourceClock_Hz / priDiv) - 1U; - - /* Desired baud rate is too low. */ - if (priDiv > 0xFFU) - { - priDiv = 0xFF; - } - - timingConfig.preDivider = (uint16_t)priDiv; - - /* Update actual timing characteristic. */ - FLEXCAN_SetTimingConfig(base, (const flexcan_timing_config_t *)(uint32_t)&timingConfig); -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -static void FLEXCAN_SetFDBaudRate(CAN_Type *base, - uint32_t sourceClock_Hz, - uint32_t baudRateFD_Bps, - flexcan_timing_config_t timingConfig) -{ - /* FlexCAN FD timing setting formula: - * quantum = 1 + (FPSEG1 + 1) + (FPSEG2 + 1) + FPROPSEG; - */ - uint32_t quantum = (1U + ((uint32_t)timingConfig.fphaseSeg1 + 1U) + ((uint32_t)timingConfig.fphaseSeg2 + 1U) + - (uint32_t)timingConfig.fpropSeg); - uint32_t priDiv = baudRateFD_Bps * quantum; - - /* Assertion: Desired baud rate is too high. */ - assert(baudRateFD_Bps <= 8000000U); - /* Assertion: Source clock should greater than baud rate * FLEXCAN_TIME_QUANTA_NUM. */ - assert(priDiv <= sourceClock_Hz); - - if (0U == priDiv) - { - priDiv = 1; - } - - priDiv = (sourceClock_Hz / priDiv) - 1U; - - /* Desired baud rate is too low. */ - if (priDiv > 0xFFU) - { - priDiv = 0xFF; - } - - timingConfig.fpreDivider = (uint16_t)priDiv; - - /* Update actual timing characteristic. */ - FLEXCAN_SetFDTimingConfig(base, (const flexcan_timing_config_t *)(uint32_t)&timingConfig); -} -#endif - -/*! - * brief Initializes a FlexCAN instance. - * - * This function initializes the FlexCAN module with user-defined settings. - * This example shows how to set up the flexcan_config_t parameters and how - * to call the FLEXCAN_Init function by passing in these parameters. - * code - * flexcan_config_t flexcanConfig; - * flexcanConfig.clkSrc = kFLEXCAN_ClkSrc0; - * flexcanConfig.baudRate = 1000000U; - * flexcanConfig.maxMbNum = 16; - * flexcanConfig.enableLoopBack = false; - * flexcanConfig.enableSelfWakeup = false; - * flexcanConfig.enableIndividMask = false; - * flexcanConfig.disableSelfReception = false; - * flexcanConfig.enableListenOnlyMode = false; - * flexcanConfig.enableDoze = false; - * flexcanConfig.timingConfig = timingConfig; - * FLEXCAN_Init(CAN0, &flexcanConfig, 8000000UL); - * endcode - * - * param base FlexCAN peripheral base address. - * param pConfig Pointer to the user-defined configuration structure. - * param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz. - */ -void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *pConfig, uint32_t sourceClock_Hz) -{ - /* Assertion. */ - assert(NULL != pConfig); - assert((pConfig->maxMbNum > 0U) && - (pConfig->maxMbNum <= (uint8_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))); - - uint32_t mcrTemp; - uint32_t ctrl1Temp; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance; -#endif - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - instance = FLEXCAN_GetInstance(base); - /* Enable FlexCAN clock. */ - (void)CLOCK_EnableClock(s_flexcanClock[instance]); - /* - * Check the CAN clock in this device whether affected by Other clock gate - * If it affected, we'd better to change other clock source, - * If user insist on using that clock source, user need open these gate at same time, - * In this scene, User need to care the power consumption. - */ - assert(CAN_CLOCK_CHECK_NO_AFFECTS); -#if defined(FLEXCAN_PERIPH_CLOCKS) - /* Enable FlexCAN serial clock. */ - (void)CLOCK_EnableClock(s_flexcanPeriphClock[instance]); -#endif /* FLEXCAN_PERIPH_CLOCKS */ -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(CAN_CTRL1_CLKSRC_MASK) -#if (defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE) && FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE) - if (0 == FSL_FEATURE_FLEXCAN_INSTANCE_SUPPORT_ENGINE_CLK_SEL_REMOVEn(base)) -#endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */ - { - /* Disable FlexCAN Module. */ - FLEXCAN_Enable(base, false); - - /* Protocol-Engine clock source selection, This bit must be set - * when FlexCAN Module in Disable Mode. - */ - base->CTRL1 = (kFLEXCAN_ClkSrc0 == pConfig->clkSrc) ? (base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK) : - (base->CTRL1 | CAN_CTRL1_CLKSRC_MASK); - } -#endif /* CAN_CTRL1_CLKSRC_MASK */ - - /* Enable FlexCAN Module for configuration. */ - FLEXCAN_Enable(base, true); - - /* Reset to known status. */ - FLEXCAN_Reset(base); - - /* Save current CTRL1 value and enable to enter Freeze mode(enabled by default). */ - ctrl1Temp = base->CTRL1; - - /* Save current MCR value and enable to enter Freeze mode(enabled by default). */ - mcrTemp = base->MCR; - - /* Enable Loop Back Mode? */ - ctrl1Temp = (pConfig->enableLoopBack) ? (ctrl1Temp | CAN_CTRL1_LPB_MASK) : (ctrl1Temp & ~CAN_CTRL1_LPB_MASK); - - /* Enable Timer Sync? */ - ctrl1Temp = (pConfig->enableTimerSync) ? (ctrl1Temp | CAN_CTRL1_TSYN_MASK) : (ctrl1Temp & ~CAN_CTRL1_TSYN_MASK); - - /* Enable Listen Only Mode? */ - ctrl1Temp = (pConfig->enableListenOnlyMode) ? ctrl1Temp | CAN_CTRL1_LOM_MASK : ctrl1Temp & ~CAN_CTRL1_LOM_MASK; - - /* Set the maximum number of Message Buffers */ - mcrTemp = (mcrTemp & ~CAN_MCR_MAXMB_MASK) | CAN_MCR_MAXMB((uint32_t)pConfig->maxMbNum - 1U); - - /* Enable Self Wake Up Mode and configure the wake up source. */ - mcrTemp = (pConfig->enableSelfWakeup) ? (mcrTemp | CAN_MCR_SLFWAK_MASK) : (mcrTemp & ~CAN_MCR_SLFWAK_MASK); - mcrTemp = (kFLEXCAN_WakeupSrcFiltered == pConfig->wakeupSrc) ? (mcrTemp | CAN_MCR_WAKSRC_MASK) : - (mcrTemp & ~CAN_MCR_WAKSRC_MASK); - - /* Enable Individual Rx Masking? */ - mcrTemp = (pConfig->enableIndividMask) ? (mcrTemp | CAN_MCR_IRMQ_MASK) : (mcrTemp & ~CAN_MCR_IRMQ_MASK); - - /* Disable Self Reception? */ - mcrTemp = (pConfig->disableSelfReception) ? mcrTemp | CAN_MCR_SRXDIS_MASK : mcrTemp & ~CAN_MCR_SRXDIS_MASK; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) - if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(base)) - { - /* Enable Doze Mode? */ - mcrTemp = (pConfig->enableDoze) ? (mcrTemp | CAN_MCR_DOZE_MASK) : (mcrTemp & ~CAN_MCR_DOZE_MASK); - } -#endif - - /* Write back CTRL1 Configuration to register. */ - base->CTRL1 = ctrl1Temp; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) - /* Enable to update in MCER. */ - base->CTRL2 |= CAN_CTRL2_ECRWRE_MASK; - base->MECR &= ~CAN_MECR_ECRWRDIS_MASK; -#endif - - /* Write back MCR Configuration to register. */ - base->MCR = mcrTemp; - - /* Baud Rate Configuration.*/ - FLEXCAN_SetBaudRate(base, sourceClock_Hz, pConfig->baudRate, pConfig->timingConfig); -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Initializes a FlexCAN instance. - * - * This function initializes the FlexCAN module with user-defined settings. - * This example shows how to set up the flexcan_config_t parameters and how - * to call the FLEXCAN_FDInit function by passing in these parameters. - * code - * flexcan_config_t flexcanConfig; - * flexcanConfig.clkSrc = kFLEXCAN_ClkSrc0; - * flexcanConfig.baudRate = 1000000U; - * flexcanConfig.baudRateFD = 2000000U; - * flexcanConfig.maxMbNum = 16; - * flexcanConfig.enableLoopBack = false; - * flexcanConfig.enableSelfWakeup = false; - * flexcanConfig.enableIndividMask = false; - * flexcanConfig.disableSelfReception = false; - * flexcanConfig.enableListenOnlyMode = false; - * flexcanConfig.enableDoze = false; - * flexcanConfig.timingConfig = timingConfig; - * FLEXCAN_FDInit(CAN0, &flexcanConfig, 8000000UL, kFLEXCAN_16BperMB, false); - * endcode - * - * param base FlexCAN peripheral base address. - * param pConfig Pointer to the user-defined configuration structure. - * param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz. - * param dataSize FlexCAN FD frame payload size. - * param brs If bitrate switch is enabled in FD mode. - */ -void FLEXCAN_FDInit( - CAN_Type *base, const flexcan_config_t *pConfig, uint32_t sourceClock_Hz, flexcan_mb_size_t dataSize, bool brs) -{ - assert((uint32_t)dataSize <= 3U); - - uint32_t fdctrl = 0U; - - /* Initialization of classical CAN. */ - FLEXCAN_Init(base, pConfig, sourceClock_Hz); - - /* Extra bitrate setting for CANFD. */ - FLEXCAN_SetFDBaudRate(base, sourceClock_Hz, pConfig->baudRateFD, pConfig->timingConfig); - - /* read FDCTRL register. */ - fdctrl = base->FDCTRL; - - /* Enable FD operation and set bitrate switch. */ - if (brs) - { - fdctrl |= CAN_FDCTRL_FDRATE_MASK; - } - else - { - fdctrl &= ~CAN_FDCTRL_FDRATE_MASK; - } - - if (brs && !(pConfig->enableLoopBack)) - { - /* Before use "|=" operation for multi-bits field, CPU should Clean previous Setting. */ - fdctrl = (fdctrl & ~CAN_FDCTRL_TDCOFF_MASK) | CAN_FDCTRL_TDCOFF(0x2U); - } - - /* Before use "|=" operation for multi-bits field, CPU should clean previous Setting. */ - fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR0_MASK) | CAN_FDCTRL_MBDSR0(dataSize); -#if defined(CAN_FDCTRL_MBDSR1_MASK) - fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR1_MASK) | CAN_FDCTRL_MBDSR1(dataSize); -#endif -#if defined(CAN_FDCTRL_MBDSR2_MASK) - fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR2_MASK) | CAN_FDCTRL_MBDSR2(dataSize); -#endif -#if defined(CAN_FDCTRL_MBDSR3_MASK) - fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR3_MASK) | CAN_FDCTRL_MBDSR3(dataSize); -#endif - - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - base->MCR |= CAN_MCR_FDEN_MASK; - - /* update the FDCTL register. */ - base->FDCTRL = fdctrl; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} -#endif - -/*! - * brief De-initializes a FlexCAN instance. - * - * This function disables the FlexCAN module clock and sets all register values - * to the reset value. - * - * param base FlexCAN peripheral base address. - */ -void FLEXCAN_Deinit(CAN_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance; -#endif - /* Reset all Register Contents. */ - FLEXCAN_Reset(base); - - /* Disable FlexCAN module. */ - FLEXCAN_Enable(base, false); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - instance = FLEXCAN_GetInstance(base); -#if defined(FLEXCAN_PERIPH_CLOCKS) - /* Disable FlexCAN serial clock. */ - (void)CLOCK_DisableClock(s_flexcanPeriphClock[instance]); -#endif /* FLEXCAN_PERIPH_CLOCKS */ - /* Disable FlexCAN clock. */ - (void)CLOCK_DisableClock(s_flexcanClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the default configuration structure. - * - * This function initializes the FlexCAN configuration structure to default values. The default - * values are as follows. - * flexcanConfig->clkSrc = kFLEXCAN_ClkSrc0; - * flexcanConfig->baudRate = 1000000U; - * flexcanConfig->baudRateFD = 2000000U; - * flexcanConfig->maxMbNum = 16; - * flexcanConfig->enableLoopBack = false; - * flexcanConfig->enableSelfWakeup = false; - * flexcanConfig->enableIndividMask = false; - * flexcanConfig->disableSelfReception = false; - * flexcanConfig->enableListenOnlyMode = false; - * flexcanConfig->enableDoze = false; - * flexcanConfig.timingConfig = timingConfig; - * - * param pConfig Pointer to the FlexCAN configuration structure. - */ -void FLEXCAN_GetDefaultConfig(flexcan_config_t *pConfig) -{ - /* Assertion. */ - assert(NULL != pConfig); - - /* Initializes the configure structure to zero. */ - (void)memset(pConfig, 0, sizeof(*pConfig)); - - /* Initialize FlexCAN Module config struct with default value. */ - pConfig->clkSrc = kFLEXCAN_ClkSrc0; - pConfig->baudRate = 1000000U; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - pConfig->baudRateFD = 2000000U; -#endif - pConfig->maxMbNum = 16; - pConfig->enableLoopBack = false; - pConfig->enableTimerSync = true; - pConfig->enableSelfWakeup = false; - pConfig->wakeupSrc = kFLEXCAN_WakeupSrcUnfiltered; - pConfig->enableIndividMask = false; - pConfig->disableSelfReception = false; - pConfig->enableListenOnlyMode = false; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) - pConfig->enableDoze = false; -#endif - /* Default protocol timing configuration, time quantum is 10. */ - pConfig->timingConfig.phaseSeg1 = 3; - pConfig->timingConfig.phaseSeg2 = 2; - pConfig->timingConfig.propSeg = 1; - pConfig->timingConfig.rJumpwidth = 1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - pConfig->timingConfig.fphaseSeg1 = 3; - pConfig->timingConfig.fphaseSeg2 = 3; - pConfig->timingConfig.fpropSeg = 1; - pConfig->timingConfig.frJumpwidth = 1; -#endif -} - -/*! - * brief Sets the FlexCAN protocol timing characteristic. - * - * This function gives user settings to CAN bus timing characteristic. - * The function is for an experienced user. For less experienced users, call - * the FLEXCAN_Init() and fill the baud rate field with a desired value. - * This provides the default timing characteristics to the module. - * - * Note that calling FLEXCAN_SetTimingConfig() overrides the baud rate set - * in FLEXCAN_Init(). - * - * param base FlexCAN peripheral base address. - * param pConfig Pointer to the timing configuration structure. - */ -void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *pConfig) -{ - /* Assertion. */ - assert(NULL != pConfig); - - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base)) - { - /* Cleaning previous Timing Setting. */ - base->CBT &= ~(CAN_CBT_EPRESDIV_MASK | CAN_CBT_ERJW_MASK | CAN_CBT_EPSEG1_MASK | CAN_CBT_EPSEG2_MASK | - CAN_CBT_EPROPSEG_MASK); - - /* Updating Timing Setting according to configuration structure. */ - base->CBT |= (CAN_CBT_EPRESDIV(pConfig->preDivider) | CAN_CBT_ERJW(pConfig->rJumpwidth) | - CAN_CBT_EPSEG1(pConfig->phaseSeg1) | CAN_CBT_EPSEG2(pConfig->phaseSeg2) | - CAN_CBT_EPROPSEG(pConfig->propSeg)); - } - else - { - /* Cleaning previous Timing Setting. */ - base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK | - CAN_CTRL1_PROPSEG_MASK); - - /* Updating Timing Setting according to configuration structure. */ - base->CTRL1 |= (CAN_CTRL1_PRESDIV(pConfig->preDivider) | CAN_CTRL1_RJW(pConfig->rJumpwidth) | - CAN_CTRL1_PSEG1(pConfig->phaseSeg1) | CAN_CTRL1_PSEG2(pConfig->phaseSeg2) | - CAN_CTRL1_PROPSEG(pConfig->propSeg)); - } -#else - /* Cleaning previous Timing Setting. */ - base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK | - CAN_CTRL1_PROPSEG_MASK); - - /* Updating Timing Setting according to configuration structure. */ - base->CTRL1 |= (CAN_CTRL1_PRESDIV(pConfig->preDivider) | CAN_CTRL1_RJW(pConfig->rJumpwidth) | - CAN_CTRL1_PSEG1(pConfig->phaseSeg1) | CAN_CTRL1_PSEG2(pConfig->phaseSeg2) | - CAN_CTRL1_PROPSEG(pConfig->propSeg)); -#endif - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Sets the FlexCAN FD protocol timing characteristic. - * - * This function gives user settings to CAN bus timing characteristic. - * The function is for an experienced user. For less experienced users, call - * the FLEXCAN_Init() and fill the baud rate field with a desired value. - * This provides the default timing characteristics to the module. - * - * Note that calling FLEXCAN_SetFDTimingConfig() overrides the baud rate set - * in FLEXCAN_Init(). - * - * param base FlexCAN peripheral base address. - * param pConfig Pointer to the timing configuration structure. - */ -void FLEXCAN_SetFDTimingConfig(CAN_Type *base, const flexcan_timing_config_t *pConfig) -{ - /* Assertion. */ - assert(NULL != pConfig); - - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - base->CBT |= CAN_CBT_BTF(1); - /* Cleaning previous Timing Setting. */ - base->FDCBT &= ~(CAN_FDCBT_FPRESDIV_MASK | CAN_FDCBT_FRJW_MASK | CAN_FDCBT_FPSEG1_MASK | CAN_FDCBT_FPSEG2_MASK | - CAN_FDCBT_FPROPSEG_MASK); - - /* Updating Timing Setting according to configuration structure. */ - base->FDCBT |= (CAN_FDCBT_FPRESDIV(pConfig->fpreDivider) | CAN_FDCBT_FRJW(pConfig->frJumpwidth) | - CAN_FDCBT_FPSEG1(pConfig->fphaseSeg1) | CAN_FDCBT_FPSEG2(pConfig->fphaseSeg2) | - CAN_FDCBT_FPROPSEG(pConfig->fpropSeg)); - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} -#endif - -/*! - * brief Sets the FlexCAN receive message buffer global mask. - * - * This function sets the global mask for the FlexCAN message buffer in a matching process. - * The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init(). - * - * param base FlexCAN peripheral base address. - * param mask Rx Message Buffer Global Mask value. - */ -void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask) -{ - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - /* Setting Rx Message Buffer Global Mask value. */ - base->RXMGMASK = mask; - base->RX14MASK = mask; - base->RX15MASK = mask; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} - -/*! - * brief Sets the FlexCAN receive FIFO global mask. - * - * This function sets the global mask for FlexCAN FIFO in a matching process. - * - * param base FlexCAN peripheral base address. - * param mask Rx Fifo Global Mask value. - */ -void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask) -{ - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - /* Setting Rx FIFO Global Mask value. */ - base->RXFGMASK = mask; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} - -/*! - * brief Sets the FlexCAN receive individual mask. - * - * This function sets the individual mask for the FlexCAN matching process. - * The configuration is only effective when the Rx individual mask is enabled in the FLEXCAN_Init(). - * If the Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer. - * If the Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to - * the Rx Filter with the same index. Note that only the first 32 - * individual masks can be used as the Rx FIFO filter mask. - * - * param base FlexCAN peripheral base address. - * param maskIdx The Index of individual Mask. - * param mask Rx Individual Mask value. - */ -void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask) -{ - assert(maskIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - /* Setting Rx Individual Mask value. */ - base->RXIMR[maskIdx] = mask; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} - -/*! - * brief Configures a FlexCAN transmit message buffer. - * - * This function aborts the previous transmission, cleans the Message Buffer, and - * configures it as a Transmit Message Buffer. - * - * param base FlexCAN peripheral base address. - * param mbIdx The Message Buffer index. - * param enable Enable/disable Tx Message Buffer. - * - true: Enable Tx Message Buffer. - * - false: Disable Tx Message Buffer. - */ -void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - /* Inactivate Message Buffer. */ - if (enable) - { - base->MB[mbIdx].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); - } - else - { - base->MB[mbIdx].CS = 0; - } - - /* Clean Message Buffer content. */ - base->MB[mbIdx].ID = 0x0; - base->MB[mbIdx].WORD0 = 0x0; - base->MB[mbIdx].WORD1 = 0x0; -} - -/*! - * @brief Calculates the segment values for a single bit time for classical CAN - * - * @param baudRate The data speed in bps - * @param tqNum Number of time quantas per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_GetSegments(uint32_t baudRate, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig) -{ - uint32_t ideal_sp; - uint32_t p1; - bool fgRet = false; - - /* Get ideal sample point. For the Bit field in CTRL1 register can't calculate higher ideal SP, we set it as the - * lowest one(75%).*/ - ideal_sp = IDEAL_SP_LOW; - - /* distribute time quanta. */ - p1 = tqNum * (uint32_t)ideal_sp; - pTimingConfig->propSeg = (uint8_t)(p1 / (uint32_t)IDEAL_SP_FACTOR - 2U); - if (pTimingConfig->propSeg <= (MAX_PSEG1 + MAX_PROPSEG)) - { - if (pTimingConfig->propSeg > MAX_PROPSEG) - { - pTimingConfig->phaseSeg1 = pTimingConfig->propSeg - MAX_PROPSEG; - pTimingConfig->propSeg = MAX_PROPSEG; - } - else - { - pTimingConfig->phaseSeg1 = 0; - } - - /* The value of prog Seg should be not larger than tqNum -4U. */ - if ((pTimingConfig->propSeg + pTimingConfig->phaseSeg1) < ((uint8_t)tqNum - 4U)) - { - pTimingConfig->phaseSeg2 = (uint8_t)tqNum - (pTimingConfig->phaseSeg1 + pTimingConfig->propSeg + 4U); - - if (pTimingConfig->phaseSeg2 <= MAX_PSEG1) - { - if ((pTimingConfig->phaseSeg1 < pTimingConfig->phaseSeg2) && - (pTimingConfig->propSeg > (pTimingConfig->phaseSeg2 - pTimingConfig->phaseSeg1))) - { - pTimingConfig->propSeg -= (pTimingConfig->phaseSeg2 - pTimingConfig->phaseSeg1); - pTimingConfig->phaseSeg1 = pTimingConfig->phaseSeg2; - } - - /* subtract one TQ for sync seg. */ - /* sjw is 20% of total TQ, rounded to nearest int. */ - pTimingConfig->rJumpwidth = ((uint8_t)tqNum + 4U) / 5U - 1U; - /* The max tqNum for CBT will reach to 129, ERJW would not be larger than 26. */ - /* Considering that max ERJW is 31, rJumpwidth will always be smaller than MAX_ERJW. */ - if (pTimingConfig->rJumpwidth > MAX_RJW) - { - pTimingConfig->rJumpwidth = MAX_RJW; - } - - fgRet = true; - } - } - } - - return fgRet; -} - -/*! - * @brief Calculates the improved timing values by specific baudrates for classical CAN - * - * @param baudRate The classical CAN speed in bps defined by user - * @param sourceClock_Hz The Source clock data speed in bps. Zero to disable baudrate switching - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if timing configuration found, FALSE if failed to find configuration - */ -bool FLEXCAN_CalculateImprovedTimingValues(uint32_t baudRate, - uint32_t sourceClock_Hz, - flexcan_timing_config_t *pTimingConfig) -{ - /* observe baud rate maximums. */ - assert(baudRate <= MAX_CAN_BAUDRATE); - - uint32_t clk; /* the clock is tqNumb x baudRateFD. */ - uint32_t tqNum; /* Numbers of TQ. */ - bool fgRet = false; - - /* Auto Improved Protocal timing for CTRL1. */ - tqNum = CTRL1_MAX_TIME_QUANTA; - do - { - clk = baudRate * tqNum; - if (clk > sourceClock_Hz) - { - continue; /* tqNum too large, clk has been exceed sourceClock_Hz. */ - } - - if ((sourceClock_Hz / clk * clk) != sourceClock_Hz) - { - continue; /* Non-supporting: the frequency of clock source is not divisible by target baud rate, the user - should change a divisible baud rate. */ - } - - pTimingConfig->preDivider = (uint16_t)(sourceClock_Hz / clk) - 1U; - if (pTimingConfig->preDivider > MAX_PRESDIV) - { - break; /* The frequency of source clock is too large or the baud rate is too small, the pre-divider could - not handle it. */ - } - - /* Try to get the best timing configuration. */ - if (FLEXCAN_GetSegments(baudRate, tqNum, pTimingConfig)) - { - fgRet = true; - break; - } - } while (--tqNum >= CTRL1_MIN_TIME_QUANTA); - - return fgRet; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx) -{ - uint32_t offset = 0; - uint32_t dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT; - switch (dataSize) - { - case (uint32_t)kFLEXCAN_8BperMB: - offset = (((uint32_t)mbIdx / 32U) * 512U + ((uint32_t)mbIdx % 32U) * 16U); - break; - case (uint32_t)kFLEXCAN_16BperMB: - offset = (((uint32_t)mbIdx / 21U) * 512U + ((uint32_t)mbIdx % 21U) * 24U); - break; - case (uint32_t)kFLEXCAN_32BperMB: - offset = (((uint32_t)mbIdx / 12U) * 512U + ((uint32_t)mbIdx % 12U) * 40U); - break; - case (uint32_t)kFLEXCAN_64BperMB: - offset = (((uint32_t)mbIdx / 7U) * 512U + ((uint32_t)mbIdx % 7U) * 72U); - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - assert(false); - break; - } - /* To get the dword aligned offset, need to divide by 4. */ - offset = offset / 4U; - return offset; -} - -/*! - * @brief Calculates the segment values for a single bit time for CANFD bus control baud Rate - * - * @param baudRate The canfd bus control speed in bps - * @param tqNum Number of time quanta per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_FDGetSegments(uint32_t baudRate, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig) -{ - uint32_t ideal_sp; - uint32_t p1; - bool fgRet = false; - - /* Get ideal sample point. */ - if (baudRate >= 1000000U) - { - ideal_sp = IDEAL_SP_LOW; - } - else if (baudRate >= 800000U) - { - ideal_sp = IDEAL_SP_MID; - } - else - { - ideal_sp = IDEAL_SP_HIGH; - } - - /* distribute time quanta. */ - p1 = tqNum * (uint32_t)ideal_sp; - pTimingConfig->propSeg = (uint8_t)(p1 / (uint32_t)IDEAL_SP_FACTOR - 2U); - if (pTimingConfig->propSeg <= (MAX_EPSEG1 + MAX_EPROPSEG)) - { - if (pTimingConfig->propSeg > MAX_EPROPSEG) - { - pTimingConfig->phaseSeg1 = pTimingConfig->propSeg - MAX_EPROPSEG; - pTimingConfig->propSeg = MAX_EPROPSEG; - } - else - { - pTimingConfig->phaseSeg1 = 0; - } - - /* The value of prog Seg should be not larger than tqNum -4U. */ - if ((pTimingConfig->propSeg + pTimingConfig->phaseSeg1) < ((uint8_t)tqNum - 4U)) - { - pTimingConfig->phaseSeg2 = (uint8_t)tqNum - (pTimingConfig->phaseSeg1 + pTimingConfig->propSeg + 4U); - - if (pTimingConfig->phaseSeg2 <= MAX_EPSEG2) - { - if ((pTimingConfig->phaseSeg1 < pTimingConfig->phaseSeg2) && - (pTimingConfig->propSeg > (pTimingConfig->phaseSeg2 - pTimingConfig->phaseSeg1))) - { - pTimingConfig->propSeg -= (pTimingConfig->phaseSeg2 - pTimingConfig->phaseSeg1); - pTimingConfig->phaseSeg1 = pTimingConfig->phaseSeg2; - } - - /* subtract one TQ for sync seg. */ - /* sjw is 20% of total TQ, rounded to nearest int. */ - pTimingConfig->rJumpwidth = ((uint8_t)tqNum + 4U) / 5U - 1U; - /* The max tqNum for CBT will reach to 129, ERJW would not be larger than 26. */ - /* Considering that max ERJW is 31, rJumpwidth will always be smaller than MAX_ERJW. */ - if (pTimingConfig->rJumpwidth > MAX_ERJW) - { - pTimingConfig->rJumpwidth = MAX_ERJW; - } - - fgRet = true; - } - } - } - - return fgRet; -} - -/*! - * @brief Calculates the segment values for a single bit time for CANFD bus data baud Rate - * - * @param baudRatebrs The canfd bus data speed in bps - * @param tqNum Number of time quanta per bit - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if Calculates the segment success, FALSE if Calculates the segment success - */ -static bool FLEXCAN_FDGetSegmentswithBRS(uint32_t baudRatebrs, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig) -{ - uint32_t ideal_sp; - uint32_t p1; - bool fgRet = false; - - /* get ideal sample point. */ - if (baudRatebrs >= 1000000U) - { - ideal_sp = IDEAL_SP_LOW; - } - else if (baudRatebrs >= 800000U) - { - ideal_sp = IDEAL_SP_MID; - } - else - { - ideal_sp = IDEAL_SP_HIGH; - } - - /* distribute time quanta. */ - p1 = tqNum * (uint32_t)ideal_sp; - pTimingConfig->fpropSeg = (uint8_t)(p1 / (uint32_t)IDEAL_SP_FACTOR - 1U); - if (pTimingConfig->fpropSeg <= (MAX_FPSEG1 + MAX_FPROPSEG)) - { - if (pTimingConfig->fpropSeg > MAX_FPROPSEG) - { - pTimingConfig->fphaseSeg1 = pTimingConfig->fpropSeg - MAX_FPROPSEG; - pTimingConfig->fpropSeg = MAX_FPROPSEG; - } - else - { - pTimingConfig->fphaseSeg1 = 0; - } - - /* The value of prog Seg should be not larger than tqNum -3U. */ - if ((pTimingConfig->fpropSeg + pTimingConfig->fphaseSeg1) < ((uint8_t)tqNum - 3U)) - { - pTimingConfig->fphaseSeg2 = (uint8_t)tqNum - (pTimingConfig->fphaseSeg1 + pTimingConfig->fpropSeg + 3U); - - if ((pTimingConfig->fphaseSeg1 < pTimingConfig->fphaseSeg2) && - (pTimingConfig->fpropSeg > (pTimingConfig->fphaseSeg2 - pTimingConfig->fphaseSeg1))) - { - pTimingConfig->fpropSeg -= (pTimingConfig->fphaseSeg2 - pTimingConfig->fphaseSeg1); - pTimingConfig->fphaseSeg1 = pTimingConfig->fphaseSeg2; - } - - /* subtract one TQ for sync seg. */ - /* sjw is 20% of total TQ, rounded to nearest int. */ - pTimingConfig->frJumpwidth = ((uint8_t)tqNum + 4U) / 5U - 1U; - - if (pTimingConfig->frJumpwidth > MAX_FRJW) - { - pTimingConfig->frJumpwidth = MAX_FRJW; - } - fgRet = true; - } - } - - return fgRet; -} - -/*! - * @brief Calculates the improved timing values by specific baudrates for CAN by CBT register - * - * @param baudRate The classical CAN speed in bps defined by user - * @param sourceClock_Hz The Source clock data speed in bps. Zero to disable baudrate switching - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if timing configuration found, FALSE if failed to find configuration - */ -static bool FLEXCAN_CalculateImprovedTimingValuesByCBT(uint32_t baudRate, - uint32_t sourceClock_Hz, - flexcan_timing_config_t *pTimingConfig) -{ - /* observe baud rate maximums. */ - assert(baudRate <= MAX_CAN_BAUDRATE); - - uint32_t clk; /* the clock is tqNumb x baudRateFD. */ - uint32_t tqNum; /* Numbers of TQ. */ - bool fgRet = false; - - tqNum = CBT_MAX_TIME_QUANTA; - /* Auto Improved Protocal timing. */ - do - { - clk = baudRate * tqNum; - if (clk > sourceClock_Hz) - { - continue; /* tqNum too large, clk has been exceed sourceClock_Hz. */ - } - - if ((sourceClock_Hz / clk * clk) != sourceClock_Hz) - { - continue; /* Non-supporting: the frequency of clock source is not divisible by target baud rate, the user - should change a divisible baud rate. */ - } - - pTimingConfig->preDivider = (uint16_t)(sourceClock_Hz / clk) - 1U; - if (pTimingConfig->preDivider > MAX_EPRESDIV) - { - break; /* The frequency of source clock is too large or the baud rate is too small, the pre-divider could - not handle it. */ - } - - /* Try to get the best timing configuration. */ - if (FLEXCAN_FDGetSegments(baudRate, tqNum, pTimingConfig)) - { - fgRet = true; - break; - } - } while (--tqNum >= CBT_MIN_TIME_QUANTA); - - return fgRet; -} - -/*! - * @brief Calculates the improved timing values by specific baudrates for CANFD - * - * @param baudRate The CANFD bus control speed in bps defined by user - * @param baudRateFD The CANFD bus data speed in bps defined by user - * @param sourceClock_Hz The Source clock data speed in bps. Zero to disable baudrate switching - * @param pTimingConfig Pointer to the FlexCAN timing configuration structure. - * - * @return TRUE if timing configuration found, FALSE if failed to find configuration - */ -bool FLEXCAN_FDCalculateImprovedTimingValues(uint32_t baudRate, - uint32_t baudRateFD, - uint32_t sourceClock_Hz, - flexcan_timing_config_t *pTimingConfig) -{ - /* observe baud rate maximums */ - assert(baudRate <= MAX_CAN_BAUDRATE); - assert(baudRateFD <= MAX_CANFD_BAUDRATE); - - uint32_t clk; - uint32_t tqNum; /* Numbers of TQ. */ - bool fgRet = false; - - if (FLEXCAN_CalculateImprovedTimingValuesByCBT(baudRate, sourceClock_Hz, pTimingConfig)) - { - if (0U != baudRateFD) - { - /* Auto Improved Protocal timing for CBT. */ - tqNum = FDCBT_MAX_TIME_QUANTA; - do - { - clk = baudRateFD * tqNum; - if (clk > sourceClock_Hz) - { - continue; /* tqNum too large, clk x tqNum has been exceed sourceClock_Hz. */ - } - - if ((sourceClock_Hz / clk * clk) != sourceClock_Hz) - { - continue; /* Non-supporting: the frequency of clock source is not divisible by target baud rate, - the user should change a divisible baud rate. */ - } - - pTimingConfig->fpreDivider = (uint16_t)(sourceClock_Hz / clk - 1U); - if (pTimingConfig->fpreDivider > MAX_FPRESDIV) - { - break; /* The frequency of source clock is too large or the baud rate is too small, the pre-divider - could not handle it. */ - } - - /* Get the best CANFD data bus timing configuration. */ - if (FLEXCAN_FDGetSegmentswithBRS(baudRateFD, tqNum, pTimingConfig)) - { - fgRet = true; - break; - } - } while (--tqNum >= FDCBT_MIN_TIME_QUANTA); - } - else - { - fgRet = true; /* User don't use Brs feature. */ - } - } - return fgRet; -} - -/*! - * brief Configures a FlexCAN transmit message buffer. - * - * This function aborts the previous transmission, cleans the Message Buffer, and - * configures it as a Transmit Message Buffer. - * - * param base FlexCAN peripheral base address. - * param mbIdx The Message Buffer index. - * param enable Enable/disable Tx Message Buffer. - * - true: Enable Tx Message Buffer. - * - false: Disable Tx Message Buffer. - */ -void FLEXCAN_SetFDTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - uint8_t cnt = 0; - uint8_t payload_dword = 1; - uint32_t dataSize; - dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT; - volatile uint32_t *mbAddr = &(base->MB[0].CS); - uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base)); -#endif - - /* Inactivate Message Buffer. */ - if (enable) - { - /* Inactivate by writing CS. */ - mbAddr[offset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive); - } - else - { - mbAddr[offset] = 0x0; - } - - /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64 - Bytes payload. */ - for (cnt = 0; cnt < (dataSize + 1U); cnt++) - { - payload_dword *= 2U; - } - - /* Clean ID. */ - mbAddr[offset + 1U] = 0x0U; - /* Clean Message Buffer content, DWORD by DWORD. */ - for (cnt = 0; cnt < payload_dword; cnt++) - { - mbAddr[offset + 2U + cnt] = 0x0U; - } - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive); -#endif -} -#endif /* FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE */ - -/*! - * brief Configures a FlexCAN Receive Message Buffer. - * - * This function cleans a FlexCAN build-in Message Buffer and configures it - * as a Receive Message Buffer. - * - * param base FlexCAN peripheral base address. - * param mbIdx The Message Buffer index. - * param pRxMbConfig Pointer to the FlexCAN Message Buffer configuration structure. - * param enable Enable/disable Rx Message Buffer. - * - true: Enable Rx Message Buffer. - * - false: Disable Rx Message Buffer. - */ -void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *pRxMbConfig, bool enable) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(((NULL != pRxMbConfig) || (false == enable))); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - uint32_t cs_temp = 0; - - /* Inactivate Message Buffer. */ - base->MB[mbIdx].CS = 0; - - /* Clean Message Buffer content. */ - base->MB[mbIdx].ID = 0x0; - base->MB[mbIdx].WORD0 = 0x0; - base->MB[mbIdx].WORD1 = 0x0; - - if (enable) - { - /* Setup Message Buffer ID. */ - base->MB[mbIdx].ID = pRxMbConfig->id; - - /* Setup Message Buffer format. */ - if (kFLEXCAN_FrameFormatExtend == pRxMbConfig->format) - { - cs_temp |= CAN_CS_IDE_MASK; - } - - /* Setup Message Buffer type. */ - if (kFLEXCAN_FrameTypeRemote == pRxMbConfig->type) - { - cs_temp |= CAN_CS_RTR_MASK; - } - - /* Activate Rx Message Buffer. */ - cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty); - base->MB[mbIdx].CS = cs_temp; - } -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Configures a FlexCAN Receive Message Buffer. - * - * This function cleans a FlexCAN build-in Message Buffer and configures it - * as a Receive Message Buffer. - * - * param base FlexCAN peripheral base address. - * param mbIdx The Message Buffer index. - * param pRxMbConfig Pointer to the FlexCAN Message Buffer configuration structure. - * param enable Enable/disable Rx Message Buffer. - * - true: Enable Rx Message Buffer. - * - false: Disable Rx Message Buffer. - */ -void FLEXCAN_SetFDRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *pRxMbConfig, bool enable) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(((NULL != pRxMbConfig) || (false == enable))); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - uint32_t cs_temp = 0; - uint8_t cnt = 0; - volatile uint32_t *mbAddr = &(base->MB[0].CS); - uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); - uint8_t payload_dword; - uint32_t dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT; - - /* Inactivate Message Buffer. */ - mbAddr[offset] = 0U; - - /* Clean Message Buffer content. */ - mbAddr[offset + 1U] = 0U; - /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64 - Bytes payload. */ - payload_dword = (2U << dataSize); - for (cnt = 0; cnt < payload_dword; cnt++) - { - mbAddr[offset + 2U + cnt] = 0x0; - } - - if (enable) - { - /* Setup Message Buffer ID. */ - mbAddr[offset + 1U] = pRxMbConfig->id; - - /* Setup Message Buffer format. */ - if (kFLEXCAN_FrameFormatExtend == pRxMbConfig->format) - { - cs_temp |= CAN_CS_IDE_MASK; - } - - /* Setup Message Buffer type. */ - if (kFLEXCAN_FrameTypeRemote == pRxMbConfig->type) - { - cs_temp |= CAN_CS_RTR_MASK; - } - - /* Activate Rx Message Buffer. */ - cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty); - mbAddr[offset] = cs_temp; - } -} -#endif - -/*! - * brief Configures the FlexCAN Rx FIFO. - * - * This function configures the Rx FIFO with given Rx FIFO configuration. - * - * param base FlexCAN peripheral base address. - * param pRxFifoConfig Pointer to the FlexCAN Rx FIFO configuration structure. - * param enable Enable/disable Rx FIFO. - * - true: Enable Rx FIFO. - * - false: Disable Rx FIFO. - */ -void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *pRxFifoConfig, bool enable) -{ - /* Assertion. */ - assert((NULL != pRxFifoConfig) || (false == enable)); - - volatile uint32_t *mbAddr; - uint8_t i, j, k, rffn = 0, numMbOccupy; - uint32_t setup_mb = 0; - - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - if (enable) - { - assert(pRxFifoConfig->idFilterNum <= 128U); - - /* Get the setup_mb value. */ - setup_mb = (uint8_t)((base->MCR & CAN_MCR_MAXMB_MASK) >> CAN_MCR_MAXMB_SHIFT); - setup_mb = (setup_mb < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) ? - setup_mb : - (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); - - /* Determine RFFN value. */ - for (i = 0; i <= 0xFU; i++) - { - if ((8U * (i + 1U)) >= pRxFifoConfig->idFilterNum) - { - rffn = i; - assert(((setup_mb - 8U) - (2U * rffn)) > 0U); - - base->CTRL2 = (base->CTRL2 & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(rffn); - break; - } - } - - /* caculate the Number of Mailboxes occupied by RX Legacy FIFO and the filter. */ - numMbOccupy = 6U + (rffn + 1U) * 2U; - - /* Copy ID filter table to Message Buffer Region (Fix MISRA_C-2012 Rule 18.1). */ - j = 0U; - for (i = 6U; i < numMbOccupy; i++) - { - /* Get address for current mail box. */ - mbAddr = &(base->MB[i].CS); - - /* One Mail box contain 4U DWORD registers. */ - for (k = 0; k < 4U; k++) - { - /* Fill all valid filter in the mail box occupied by filter. - * Disable unused Rx FIFO Filter, the other rest of register in the last Mail box occupied by fiter set - * as 0xffffffff. - */ - mbAddr[k] = (j < pRxFifoConfig->idFilterNum) ? (pRxFifoConfig->idFilterTable[j]) : 0xFFFFFFFFU; - - /* Try to fill next filter in current Mail Box. */ - j++; - } - } - - /* Setup ID Fitlter Type. */ - switch (pRxFifoConfig->idFilterType) - { - case kFLEXCAN_RxFifoFilterTypeA: - base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x0); - break; - case kFLEXCAN_RxFifoFilterTypeB: - base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x1); - break; - case kFLEXCAN_RxFifoFilterTypeC: - base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x2); - break; - case kFLEXCAN_RxFifoFilterTypeD: - /* All frames rejected. */ - base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x3); - break; - default: - /* All the cases have been listed above, the default clause should not be reached. */ - assert(false); - break; - } - - /* Setting Message Reception Priority. */ - base->CTRL2 = (pRxFifoConfig->priority == kFLEXCAN_RxFifoPrioHigh) ? (base->CTRL2 & ~CAN_CTRL2_MRP_MASK) : - (base->CTRL2 | CAN_CTRL2_MRP_MASK); - - /* Enable Rx Message FIFO. */ - base->MCR |= CAN_MCR_RFEN_MASK; - } - else - { - rffn = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT); - /* caculate the Number of Mailboxes occupied by RX Legacy FIFO and the filter. */ - numMbOccupy = 6U + (rffn + 1U) * 2U; - - /* Disable Rx Message FIFO. */ - base->MCR &= ~CAN_MCR_RFEN_MASK; - - /* Clean MB0 ~ MB5 and all MB occupied by ID filters (Fix MISRA_C-2012 Rule 18.1). */ - - for (i = 0; i < numMbOccupy; i++) - { - FLEXCAN_SetRxMbConfig(base, i, NULL, false); - } - } - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) -/*! - * brief Enables or disables the FlexCAN Rx FIFO DMA request. - * - * This function enables or disables the DMA feature of FlexCAN build-in Rx FIFO. - * - * param base FlexCAN peripheral base address. - * param enable true to enable, false to disable. - */ -void FLEXCAN_EnableRxFifoDMA(CAN_Type *base, bool enable) -{ - if (enable) - { - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - /* Enable FlexCAN DMA. */ - base->MCR |= CAN_MCR_DMA_MASK; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); - } - else - { - /* Enter Freeze Mode. */ - FLEXCAN_EnterFreezeMode(base); - - /* Disable FlexCAN DMA. */ - base->MCR &= ~CAN_MCR_DMA_MASK; - - /* Exit Freeze Mode. */ - FLEXCAN_ExitFreezeMode(base); - } -} -#endif /* FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA */ - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) -/*! - * FlexCAN: A frame with wrong ID or payload is transmitted into - * the CAN bus when the Message Buffer under transmission is - * either aborted or deactivated while the CAN bus is in the Bus Idle state - * - * This function to do workaround for ERR006032 - * - * param base FlexCAN peripheral base address. - * param mbIdx The FlexCAN Message Buffer index. - */ -static void FLEXCAN_ERRATA_6032(CAN_Type *base, volatile uint32_t *mbCSAddr) -{ - uint32_t dbg_temp = 0U; - uint32_t u32TempCS = 0U; - uint32_t u32Timeout = DELAY_BUSIDLE; - uint32_t u32TempIMASK1 = base->IMASK1; -/*after backup all interruption, disable ALL interruption*/ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint32_t u32TempIMASK2 = base->IMASK2; - base->IMASK2 = 0; -#endif - base->IMASK1 = 0; - dbg_temp = (uint32_t)(base->DBG1); - switch (dbg_temp & CAN_DBG1_CFSM_MASK) - { - case RXINTERMISSION: - if (CBN_VALUE3 == (dbg_temp & CAN_DBG1_CBN_MASK)) - { - /*wait until CFSM is different from RXINTERMISSION */ - while (RXINTERMISSION == (base->DBG1 & CAN_DBG1_CFSM_MASK)) - { - __NOP(); - } - } - break; - case TXINTERMISSION: - if (CBN_VALUE3 == (dbg_temp & CAN_DBG1_CBN_MASK)) - { - /*wait until CFSM is different from TXINTERMISSION*/ - while (TXINTERMISSION == (base->DBG1 & CAN_DBG1_CFSM_MASK)) - { - __NOP(); - } - } - break; - default: - /* To avoid MISRA-C 2012 rule 16.4 issue. */ - break; - } - /*Anyway, BUSIDLE need to delay*/ - if (BUSIDLE == (base->DBG1 & CAN_DBG1_CFSM_MASK)) - { - while (u32Timeout-- > 0U) - { - __NOP(); - } - - /*Write 0x0 into Code field of CS word.*/ - u32TempCS = (uint32_t)(*mbCSAddr); - u32TempCS &= ~CAN_CS_CODE_MASK; - *mbCSAddr = u32TempCS; - } - /*restore interruption*/ - base->IMASK1 = u32TempIMASK1; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - base->IMASK2 = u32TempIMASK2; -#endif -} -#endif - -/*! - * brief Writes a FlexCAN Message to the Transmit Message Buffer. - * - * This function writes a CAN Message to the specified Transmit Message Buffer - * and changes the Message Buffer state to start CAN Message transmit. After - * that the function returns immediately. - * - * param base FlexCAN peripheral base address. - * param mbIdx The FlexCAN Message Buffer index. - * param pTxFrame Pointer to CAN message frame to be sent. - * retval kStatus_Success - Write Tx Message Buffer Successfully. - * retval kStatus_Fail - Tx Message Buffer is currently in use. - */ -status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *pTxFrame) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(NULL != pTxFrame); - assert(pTxFrame->length <= 8U); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - uint32_t cs_temp = 0; - status_t status; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) - FLEXCAN_ERRATA_6032(base, &(base->MB[mbIdx].CS)); -#endif - /* Check if Message Buffer is available. */ - if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK)) - { - /* Inactive Tx Message Buffer. */ - base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive); - - /* Fill Message ID field. */ - base->MB[mbIdx].ID = pTxFrame->id; - - /* Fill Message Format field. */ - if ((uint32_t)kFLEXCAN_FrameFormatExtend == pTxFrame->format) - { - cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK; - } - - /* Fill Message Type field. */ - if ((uint32_t)kFLEXCAN_FrameTypeRemote == pTxFrame->type) - { - cs_temp |= CAN_CS_RTR_MASK; - } - - cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(pTxFrame->length); - - /* Load Message Payload. */ - base->MB[mbIdx].WORD0 = pTxFrame->dataWord0; - base->MB[mbIdx].WORD1 = pTxFrame->dataWord1; - - /* Activate Tx Message Buffer. */ - base->MB[mbIdx].CS = cs_temp; - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); - base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive); -#endif - - status = kStatus_Success; - } - else - { - /* Tx Message Buffer is activated, return immediately. */ - status = kStatus_Fail; - } - - return status; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Writes a FlexCAN FD Message to the Transmit Message Buffer. - * - * This function writes a CAN FD Message to the specified Transmit Message Buffer - * and changes the Message Buffer state to start CAN FD Message transmit. After - * that the function returns immediately. - * - * param base FlexCAN peripheral base address. - * param mbIdx The FlexCAN FD Message Buffer index. - * param pTxFrame Pointer to CAN FD message frame to be sent. - * retval kStatus_Success - Write Tx Message Buffer Successfully. - * retval kStatus_Fail - Tx Message Buffer is currently in use. - */ -status_t FLEXCAN_WriteFDTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_fd_frame_t *pTxFrame) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(NULL != pTxFrame); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - status_t status; - uint32_t cs_temp = 0; - uint8_t cnt = 0; - uint32_t can_cs = 0; - uint8_t payload_dword = 1; - uint32_t dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT; -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base)); -#endif - volatile uint32_t *mbAddr = &(base->MB[0].CS); - uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) - FLEXCAN_ERRATA_6032(base, &(mbAddr[offset])); -#endif - - can_cs = mbAddr[offset]; - /* Check if Message Buffer is available. */ - if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (can_cs & CAN_CS_CODE_MASK)) - { - /* Inactive Tx Message Buffer and Fill Message ID field. */ - mbAddr[offset] = (can_cs & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive); - mbAddr[offset + 1U] = pTxFrame->id; - - /* Fill Message Format field. */ - if ((uint32_t)kFLEXCAN_FrameFormatExtend == pTxFrame->format) - { - cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK; - } - - /* Fill Message Type field. */ - if ((uint32_t)kFLEXCAN_FrameTypeRemote == pTxFrame->type) - { - cs_temp |= CAN_CS_RTR_MASK; - } - - cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(pTxFrame->length) | CAN_CS_EDL(1) | - CAN_CS_BRS(pTxFrame->brs); - - /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64 - Bytes payload. */ - for (cnt = 0; cnt < (dataSize + 1U); cnt++) - { - payload_dword *= 2U; - } - - /* Load Message Payload and Activate Tx Message Buffer. */ - for (cnt = 0; cnt < payload_dword; cnt++) - { - mbAddr[offset + 2U + cnt] = pTxFrame->dataWord[cnt]; - } - mbAddr[offset] = cs_temp; - -#if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \ - (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829)) - mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive); - mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive); -#endif - - status = kStatus_Success; - } - else - { - /* Tx Message Buffer is activated, return immediately. */ - status = kStatus_Fail; - } - - return status; -} -#endif - -/*! - * brief Reads a FlexCAN Message from Receive Message Buffer. - * - * This function reads a CAN message from a specified Receive Message Buffer. - * The function fills a receive CAN message frame structure with - * just received data and activates the Message Buffer again. - * The function returns immediately. - * - * param base FlexCAN peripheral base address. - * param mbIdx The FlexCAN Message Buffer index. - * param pRxFrame Pointer to CAN message frame structure for reception. - * retval kStatus_Success - Rx Message Buffer is full and has been read successfully. - * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully. - * retval kStatus_Fail - Rx Message Buffer is empty. - */ -status_t FLEXCAN_ReadRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pRxFrame) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(NULL != pRxFrame); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - uint32_t cs_temp; - uint32_t rx_code; - status_t status; - - /* Read CS field of Rx Message Buffer to lock Message Buffer. */ - cs_temp = base->MB[mbIdx].CS; - /* Get Rx Message Buffer Code field. */ - rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT; - - /* Check to see if Rx Message Buffer is full. */ - if (((uint32_t)kFLEXCAN_RxMbFull == rx_code) || ((uint32_t)kFLEXCAN_RxMbOverrun == rx_code)) - { - /* Store Message ID. */ - pRxFrame->id = base->MB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK); - - /* Get the message ID and format. */ - pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend : - (uint8_t)kFLEXCAN_FrameFormatStandard; - - /* Get the message type. */ - pRxFrame->type = - (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData; - - /* Get the message length. */ - pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT); - - /* Get the time stamp. */ - pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - - /* Store Message Payload. */ - pRxFrame->dataWord0 = base->MB[mbIdx].WORD0; - pRxFrame->dataWord1 = base->MB[mbIdx].WORD1; - - /* Read free-running timer to unlock Rx Message Buffer. */ - (void)base->TIMER; - - if ((uint32_t)kFLEXCAN_RxMbFull == rx_code) - { - status = kStatus_Success; - } - else - { - status = kStatus_FLEXCAN_RxOverflow; - } - } - else - { - /* Read free-running timer to unlock Rx Message Buffer. */ - (void)base->TIMER; - - status = kStatus_Fail; - } - - return status; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Reads a FlexCAN FD Message from Receive Message Buffer. - * - * This function reads a CAN FD message from a specified Receive Message Buffer. - * The function fills a receive CAN FD message frame structure with - * just received data and activates the Message Buffer again. - * The function returns immediately. - * - * param base FlexCAN peripheral base address. - * param mbIdx The FlexCAN FD Message Buffer index. - * param pRxFrame Pointer to CAN FD message frame structure for reception. - * retval kStatus_Success - Rx Message Buffer is full and has been read successfully. - * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully. - * retval kStatus_Fail - Rx Message Buffer is empty. - */ -status_t FLEXCAN_ReadFDRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pRxFrame) -{ - /* Assertion. */ - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); - assert(NULL != pRxFrame); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - - status_t status; - uint32_t cs_temp; - uint8_t rx_code; - uint8_t cnt = 0; - uint32_t can_id = 0; - uint32_t dataSize; - dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT; - uint8_t payload_dword = 1; - volatile uint32_t *mbAddr = &(base->MB[0].CS); - uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); - - /* Read CS field of Rx Message Buffer to lock Message Buffer. */ - cs_temp = mbAddr[offset]; - can_id = mbAddr[offset + 1U]; - - /* Get Rx Message Buffer Code field. */ - rx_code = (uint8_t)((cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT); - - /* Check to see if Rx Message Buffer is full. */ - if (((uint8_t)kFLEXCAN_RxMbFull == rx_code) || ((uint8_t)kFLEXCAN_RxMbOverrun == rx_code)) - { - /* Store Message ID. */ - pRxFrame->id = can_id & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK); - - /* Get the message ID and format. */ - pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend : - (uint8_t)kFLEXCAN_FrameFormatStandard; - - /* Get the message type. */ - pRxFrame->type = - (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData; - - /* Get the message length. */ - pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT); - - /* Get the time stamp. */ - pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - - /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64 - Bytes payload. */ - for (cnt = 0; cnt < (dataSize + 1U); cnt++) - { - payload_dword *= 2U; - } - - /* Store Message Payload. */ - for (cnt = 0; cnt < payload_dword; cnt++) - { - pRxFrame->dataWord[cnt] = mbAddr[offset + 2U + cnt]; - } - - /* Read free-running timer to unlock Rx Message Buffer. */ - (void)base->TIMER; - - if ((uint32_t)kFLEXCAN_RxMbFull == rx_code) - { - status = kStatus_Success; - } - else - { - status = kStatus_FLEXCAN_RxOverflow; - } - } - else - { - /* Read free-running timer to unlock Rx Message Buffer. */ - (void)base->TIMER; - - status = kStatus_Fail; - } - - return status; -} -#endif - -/*! - * brief Reads a FlexCAN Message from Rx FIFO. - * - * This function reads a CAN message from the FlexCAN build-in Rx FIFO. - * - * param base FlexCAN peripheral base address. - * param pRxFrame Pointer to CAN message frame structure for reception. - * retval kStatus_Success - Read Message from Rx FIFO successfully. - * retval kStatus_Fail - Rx FIFO is not enabled. - */ -status_t FLEXCAN_ReadRxFifo(CAN_Type *base, flexcan_frame_t *pRxFrame) -{ - /* Assertion. */ - assert(NULL != pRxFrame); - - uint32_t cs_temp; - status_t status; - - /* Check if Rx FIFO is Enabled. */ - if (0U != (base->MCR & CAN_MCR_RFEN_MASK)) - { - /* Read CS field of Rx Message Buffer to lock Message Buffer. */ - cs_temp = base->MB[0].CS; - - /* Read data from Rx FIFO output port. */ - /* Store Message ID. */ - pRxFrame->id = base->MB[0].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK); - - /* Get the message ID and format. */ - pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend : - (uint8_t)kFLEXCAN_FrameFormatStandard; - - /* Get the message type. */ - pRxFrame->type = - (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData; - - /* Get the message length. */ - pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT); - - /* Get the time stamp. */ - pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - - /* Store Message Payload. */ - pRxFrame->dataWord0 = base->MB[0].WORD0; - pRxFrame->dataWord1 = base->MB[0].WORD1; - - /* Store ID Filter Hit Index. */ - pRxFrame->idhit = (uint16_t)(base->RXFIR & CAN_RXFIR_IDHIT_MASK); - - /* Read free-running timer to unlock Rx Message Buffer. */ - (void)base->TIMER; - - status = kStatus_Success; - } - else - { - status = kStatus_Fail; - } - - return status; -} - -/*! - * brief Performs a polling send transaction on the CAN bus. - * - * Note that a transfer handle does not need to be created before calling this API. - * - * param base FlexCAN peripheral base pointer. - * param mbIdx The FlexCAN Message Buffer index. - * param pTxFrame Pointer to CAN message frame to be sent. - * retval kStatus_Success - Write Tx Message Buffer Successfully. - * retval kStatus_Fail - Tx Message Buffer is currently in use. - */ -status_t FLEXCAN_TransferSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pTxFrame) -{ - status_t status; - - /* Write Tx Message Buffer to initiate a data sending. */ - if (kStatus_Success == FLEXCAN_WriteTxMb(base, mbIdx, (const flexcan_frame_t *)(uint32_t)pTxFrame)) - { -/* Wait until CAN Message send out. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx)) -#else - uint32_t u32flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx)) -#endif - { - } - -/* Clean Tx Message Buffer Flag. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx); -#else - FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx); -#endif - /*After TX MB tranfered success, update the Timestamp from MB[mbIdx].CS register*/ - pTxFrame->timestamp = (uint16_t)((base->MB[mbIdx].CS & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - - status = kStatus_Success; - } - else - { - status = kStatus_Fail; - } - - return status; -} - -/*! - * brief Performs a polling receive transaction on the CAN bus. - * - * Note that a transfer handle does not need to be created before calling this API. - * - * param base FlexCAN peripheral base pointer. - * param mbIdx The FlexCAN Message Buffer index. - * param pRxFrame Pointer to CAN message frame structure for reception. - * retval kStatus_Success - Rx Message Buffer is full and has been read successfully. - * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully. - * retval kStatus_Fail - Rx Message Buffer is empty. - */ -status_t FLEXCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pRxFrame) -{ -/* Wait until Rx Message Buffer non-empty. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx)) -#else - uint32_t u32flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx)) -#endif - { - } - -/* Clean Rx Message Buffer Flag. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx); -#else - FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx); -#endif - - /* Read Received CAN Message. */ - return FLEXCAN_ReadRxMb(base, mbIdx, pRxFrame); -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Performs a polling send transaction on the CAN bus. - * - * Note that a transfer handle does not need to be created before calling this API. - * - * param base FlexCAN peripheral base pointer. - * param mbIdx The FlexCAN FD Message Buffer index. - * param pTxFrame Pointer to CAN FD message frame to be sent. - * retval kStatus_Success - Write Tx Message Buffer Successfully. - * retval kStatus_Fail - Tx Message Buffer is currently in use. - */ -status_t FLEXCAN_TransferFDSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pTxFrame) -{ - status_t status; - - /* Write Tx Message Buffer to initiate a data sending. */ - if (kStatus_Success == FLEXCAN_WriteFDTxMb(base, mbIdx, (const flexcan_fd_frame_t *)(uint32_t)pTxFrame)) - { -/* Wait until CAN Message send out. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx)) -#else - uint32_t u32flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx)) -#endif - { - } - -/* Clean Tx Message Buffer Flag. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx); -#else - FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx); -#endif - /*After TX MB tranfered success, update the Timestamp from base->MB[offset for CANFD].CS register*/ - volatile uint32_t *mbAddr = &(base->MB[0].CS); - uint32_t offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); - pTxFrame->timestamp = (uint16_t)((mbAddr[offset] & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - - status = kStatus_Success; - } - else - { - status = kStatus_Fail; - } - - return status; -} - -/*! - * brief Performs a polling receive transaction on the CAN bus. - * - * Note that a transfer handle does not need to be created before calling this API. - * - * param base FlexCAN peripheral base pointer. - * param mbIdx The FlexCAN FD Message Buffer index. - * param pRxFrame Pointer to CAN FD message frame structure for reception. - * retval kStatus_Success - Rx Message Buffer is full and has been read successfully. - * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully. - * retval kStatus_Fail - Rx Message Buffer is empty. - */ -status_t FLEXCAN_TransferFDReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pRxFrame) -{ -/* Wait until Rx Message Buffer non-empty. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx)) -#else - uint32_t u32flag = 1; - while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx)) -#endif - { - } - -/* Clean Rx Message Buffer Flag. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx); -#else - FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx); -#endif - - /* Read Received CAN Message. */ - return FLEXCAN_ReadFDRxMb(base, mbIdx, pRxFrame); -} -#endif - -/*! - * brief Performs a polling receive transaction from Rx FIFO on the CAN bus. - * - * Note that a transfer handle does not need to be created before calling this API. - * - * param base FlexCAN peripheral base pointer. - * param pRxFrame Pointer to CAN message frame structure for reception. - * retval kStatus_Success - Read Message from Rx FIFO successfully. - * retval kStatus_Fail - Rx FIFO is not enabled. - */ -status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *pRxFrame) -{ - status_t rxFifoStatus; - - /* Wait until Rx FIFO non-empty. */ - while (0U == FLEXCAN_GetMbStatusFlags(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)) - { - } - - /* */ - rxFifoStatus = FLEXCAN_ReadRxFifo(base, pRxFrame); - - /* Clean Rx Fifo available flag. */ - FLEXCAN_ClearMbStatusFlags(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); - - return rxFifoStatus; -} - -/*! - * brief Initializes the FlexCAN handle. - * - * This function initializes the FlexCAN handle, which can be used for other FlexCAN - * transactional APIs. Usually, for a specified FlexCAN instance, - * call this API once to get the initialized handle. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param callback The callback function. - * param userData The parameter of the callback function. - */ -void FLEXCAN_TransferCreateHandle(CAN_Type *base, - flexcan_handle_t *handle, - flexcan_transfer_callback_t callback, - void *userData) -{ - assert(NULL != handle); - - uint8_t instance; - - /* Clean FlexCAN transfer handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Get instance from peripheral base address. */ - instance = (uint8_t)FLEXCAN_GetInstance(base); - - /* Save the context in global variables to support the double weak mechanism. */ - s_flexcanHandle[instance] = handle; - - /* Register Callback function. */ - handle->callback = callback; - handle->userData = userData; - - s_flexcanIsr = FLEXCAN_TransferHandleIRQ; - - /* We Enable Error & Status interrupt here, because this interrupt just - * report current status of FlexCAN module through Callback function. - * It is insignificance without a available callback function. - */ - if (handle->callback != NULL) - { - FLEXCAN_EnableInterrupts( - base, (uint32_t)kFLEXCAN_BusOffInterruptEnable | (uint32_t)kFLEXCAN_ErrorInterruptEnable | - (uint32_t)kFLEXCAN_RxWarningInterruptEnable | (uint32_t)kFLEXCAN_TxWarningInterruptEnable | - (uint32_t)kFLEXCAN_WakeUpInterruptEnable); - } - else - { - FLEXCAN_DisableInterrupts( - base, (uint32_t)kFLEXCAN_BusOffInterruptEnable | (uint32_t)kFLEXCAN_ErrorInterruptEnable | - (uint32_t)kFLEXCAN_RxWarningInterruptEnable | (uint32_t)kFLEXCAN_TxWarningInterruptEnable | - (uint32_t)kFLEXCAN_WakeUpInterruptEnable); - } - - /* Enable interrupts in NVIC. */ - (void)EnableIRQ((IRQn_Type)(s_flexcanRxWarningIRQ[instance])); - (void)EnableIRQ((IRQn_Type)(s_flexcanTxWarningIRQ[instance])); - (void)EnableIRQ((IRQn_Type)(s_flexcanWakeUpIRQ[instance])); - (void)EnableIRQ((IRQn_Type)(s_flexcanErrorIRQ[instance])); - (void)EnableIRQ((IRQn_Type)(s_flexcanBusOffIRQ[instance])); - (void)EnableIRQ((IRQn_Type)(s_flexcanMbIRQ[instance])); -} - -/*! - * brief Sends a message using IRQ. - * - * This function sends a message using IRQ. This is a non-blocking function, which returns - * right away. When messages have been sent out, the send callback function is called. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param pMbXfer FlexCAN Message Buffer transfer structure. See the #flexcan_mb_transfer_t. - * retval kStatus_Success Start Tx Message Buffer sending process successfully. - * retval kStatus_Fail Write Tx Message Buffer failed. - * retval kStatus_FLEXCAN_TxBusy Tx Message Buffer is in use. - */ -status_t FLEXCAN_TransferSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer) -{ - /* Assertion. */ - assert(NULL != handle); - assert(NULL != pMbXfer); - assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx)); -#endif - - status_t status; - - /* Check if Message Buffer is idle. */ - if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx]) - { - /* Distinguish transmit type. */ - if ((uint32_t)kFLEXCAN_FrameTypeRemote == pMbXfer->frame->type) - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxRemote; - } - else - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxData; - } - - if (kStatus_Success == - FLEXCAN_WriteTxMb(base, pMbXfer->mbIdx, (const flexcan_frame_t *)(uint32_t)pMbXfer->frame)) - { -/* Enable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx); -#endif - status = kStatus_Success; - } - else - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateIdle; - status = kStatus_Fail; - } - } - else - { - status = kStatus_FLEXCAN_TxBusy; - } - - return status; -} - -/*! - * brief Receives a message using IRQ. - * - * This function receives a message using IRQ. This is non-blocking function, which returns - * right away. When the message has been received, the receive callback function is called. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param pMbXfer FlexCAN Message Buffer transfer structure. See the #flexcan_mb_transfer_t. - * retval kStatus_Success - Start Rx Message Buffer receiving process successfully. - * retval kStatus_FLEXCAN_RxBusy - Rx Message Buffer is in use. - */ -status_t FLEXCAN_TransferReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer) -{ - status_t status; - - /* Assertion. */ - assert(NULL != handle); - assert(NULL != pMbXfer); - assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx)); -#endif - - /* Check if Message Buffer is idle. */ - if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx]) - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateRxData; - - /* Register Message Buffer. */ - handle->mbFrameBuf[pMbXfer->mbIdx] = pMbXfer->frame; - -/* Enable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx); -#endif - - status = kStatus_Success; - } - else - { - status = kStatus_FLEXCAN_RxBusy; - } - - return status; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Sends a message using IRQ. - * - * This function sends a message using IRQ. This is a non-blocking function, which returns - * right away. When messages have been sent out, the send callback function is called. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param pMbXfer FlexCAN FD Message Buffer transfer structure. See the #flexcan_mb_transfer_t. - * retval kStatus_Success Start Tx Message Buffer sending process successfully. - * retval kStatus_Fail Write Tx Message Buffer failed. - * retval kStatus_FLEXCAN_TxBusy Tx Message Buffer is in use. - */ -status_t FLEXCAN_TransferFDSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer) -{ - /* Assertion. */ - assert(NULL != handle); - assert(NULL != pMbXfer); - assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx)); -#endif - - status_t status; - - /* Check if Message Buffer is idle. */ - if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx]) - { - /* Distinguish transmit type. */ - if ((uint32_t)kFLEXCAN_FrameTypeRemote == pMbXfer->framefd->type) - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxRemote; - } - else - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxData; - } - - if (kStatus_Success == - FLEXCAN_WriteFDTxMb(base, pMbXfer->mbIdx, (const flexcan_fd_frame_t *)(uint32_t)pMbXfer->framefd)) - { -/* Enable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx); -#endif - - status = kStatus_Success; - } - else - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateIdle; - status = kStatus_Fail; - } - } - else - { - status = kStatus_FLEXCAN_TxBusy; - } - - return status; -} - -/*! - * brief Receives a message using IRQ. - * - * This function receives a message using IRQ. This is non-blocking function, which returns - * right away. When the message has been received, the receive callback function is called. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param pMbXfer FlexCAN FD Message Buffer transfer structure. See the #flexcan_mb_transfer_t. - * retval kStatus_Success - Start Rx Message Buffer receiving process successfully. - * retval kStatus_FLEXCAN_RxBusy - Rx Message Buffer is in use. - */ -status_t FLEXCAN_TransferFDReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer) -{ - /* Assertion. */ - assert(NULL != handle); - assert(NULL != pMbXfer); - assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx)); -#endif - - status_t status; - - /* Check if Message Buffer is idle. */ - if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx]) - { - handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateRxData; - - /* Register Message Buffer. */ - handle->mbFDFrameBuf[pMbXfer->mbIdx] = pMbXfer->framefd; - -/* Enable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx); -#endif - - status = kStatus_Success; - } - else - { - status = kStatus_FLEXCAN_RxBusy; - } - - return status; -} -#endif - -/*! - * brief Receives a message from Rx FIFO using IRQ. - * - * This function receives a message using IRQ. This is a non-blocking function, which returns - * right away. When all messages have been received, the receive callback function is called. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param pFifoXfer FlexCAN Rx FIFO transfer structure. See the ref flexcan_fifo_transfer_t. - * retval kStatus_Success - Start Rx FIFO receiving process successfully. - * retval kStatus_FLEXCAN_RxFifoBusy - Rx FIFO is currently in use. - */ -status_t FLEXCAN_TransferReceiveFifoNonBlocking(CAN_Type *base, - flexcan_handle_t *handle, - flexcan_fifo_transfer_t *pFifoXfer) -{ - /* Assertion. */ - assert(NULL != handle); - assert(NULL != pFifoXfer); - - status_t status; - - /* Check if Message Buffer is idle. */ - if ((uint8_t)kFLEXCAN_StateIdle == handle->rxFifoState) - { - handle->rxFifoState = (uint8_t)kFLEXCAN_StateRxFifo; - - /* Register Message Buffer. */ - handle->rxFifoFrameBuf = pFifoXfer->frame; - - /* Enable Message Buffer Interrupt. */ - FLEXCAN_EnableMbInterrupts(base, (uint32_t)kFLEXCAN_RxFifoOverflowFlag | (uint32_t)kFLEXCAN_RxFifoWarningFlag | - (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); - - status = kStatus_Success; - } - else - { - status = kStatus_FLEXCAN_RxFifoBusy; - } - - return status; -} - -/*! - * brief Aborts the interrupt driven message send process. - * - * This function aborts the interrupt driven message send process. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param mbIdx The FlexCAN Message Buffer index. - */ -void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx) -{ - uint16_t timestamp; - - /* Assertion. */ - assert(NULL != handle); - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - -/* Disable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx); -#endif - - /* Update the TX frame 's time stamp by MB[mbIdx].cs. */ - timestamp = (uint16_t)((base->MB[mbIdx].CS & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - handle->timestamp[mbIdx] = timestamp; - - /* Clean Message Buffer. */ - FLEXCAN_SetTxMbConfig(base, mbIdx, true); - - handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle; -} - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) -/*! - * brief Aborts the interrupt driven message send process. - * - * This function aborts the interrupt driven message send process. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param mbIdx The FlexCAN FD Message Buffer index. - */ -void FLEXCAN_TransferFDAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx) -{ - volatile uint32_t *mbAddr; - uint32_t offset; - uint16_t timestamp; - - /* Assertion. */ - assert(NULL != handle); - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - -/* Disable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx); -#endif - - /* Update the TX frame 's time stamp by base->MB[offset for CANFD].CS. */ - mbAddr = &(base->MB[0].CS); - offset = FLEXCAN_GetFDMailboxOffset(base, mbIdx); - timestamp = (uint16_t)((mbAddr[offset] & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT); - handle->timestamp[mbIdx] = timestamp; - - /* Clean Message Buffer. */ - FLEXCAN_SetFDTxMbConfig(base, mbIdx, true); - - handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle; -} - -/*! - * brief Aborts the interrupt driven message receive process. - * - * This function aborts the interrupt driven message receive process. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param mbIdx The FlexCAN FD Message Buffer index. - */ -void FLEXCAN_TransferFDAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx) -{ - /* Assertion. */ - assert(NULL != handle); - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - -/* Disable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx); -#else - uint32_t u32mask = 1; - FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx); -#endif - - /* Un-register handle. */ - handle->mbFDFrameBuf[mbIdx] = NULL; - handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle; -} -#endif - -/*! - * brief Aborts the interrupt driven message receive process. - * - * This function aborts the interrupt driven message receive process. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - * param mbIdx The FlexCAN Message Buffer index. - */ -void FLEXCAN_TransferAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx) -{ - /* Assertion. */ - assert(NULL != handle); - assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK)); -#if !defined(NDEBUG) - assert(!FLEXCAN_IsMbOccupied(base, mbIdx)); -#endif - -/* Disable Message Buffer Interrupt. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64mask = 1; - FLEXCAN_DisableMbInterrupts(base, (u64mask << mbIdx)); -#else - uint32_t u32mask = 1; - FLEXCAN_DisableMbInterrupts(base, (u32mask << mbIdx)); -#endif - - /* Un-register handle. */ - handle->mbFrameBuf[mbIdx] = NULL; - handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle; -} - -/*! - * brief Aborts the interrupt driven message receive from Rx FIFO process. - * - * This function aborts the interrupt driven message receive from Rx FIFO process. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - */ -void FLEXCAN_TransferAbortReceiveFifo(CAN_Type *base, flexcan_handle_t *handle) -{ - /* Assertion. */ - assert(NULL != handle); - - /* Check if Rx FIFO is enabled. */ - if (0U != (base->MCR & CAN_MCR_RFEN_MASK)) - { - /* Disable Rx Message FIFO Interrupts. */ - FLEXCAN_DisableMbInterrupts(base, (uint32_t)kFLEXCAN_RxFifoOverflowFlag | (uint32_t)kFLEXCAN_RxFifoWarningFlag | - (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); - - /* Un-register handle. */ - handle->rxFifoFrameBuf = NULL; - } - - handle->rxFifoState = (uint8_t)kFLEXCAN_StateIdle; -} - -/*! - * brief Gets the detail index of Mailbox's Timestamp by handle. - * - * Then function can only be used when calling non-blocking Data transfer (TX/RX) API, - * After TX/RX data transfer done (User can get the status by handler's callback function), - * we can get the detail index of Mailbox's timestamp by handle, - * Detail non-blocking data transfer API (TX/RX) contain. - * -FLEXCAN_TransferSendNonBlocking - * -FLEXCAN_TransferFDSendNonBlocking - * -FLEXCAN_TransferReceiveNonBlocking - * -FLEXCAN_TransferFDReceiveNonBlocking - * -FLEXCAN_TransferReceiveFifoNonBlocking - * - * param handle FlexCAN handle pointer. - * param mbIdx The FlexCAN FD Message Buffer index. - * return the index of mailbox 's timestamp stored in the handle. - * - */ -uint32_t FLEXCAN_GetTimeStamp(flexcan_handle_t *handle, uint8_t mbIdx) -{ - /* Assertion. */ - assert(NULL != handle); - - return (uint32_t)(handle->timestamp[mbIdx]); -} - -static bool FLEXCAN_CheckUnhandleInterruptEvents(CAN_Type *base) -{ - uint64_t tempmask; - uint64_t tempflag; - bool fgRet = false; - - /* Checking exist error flag. */ - if (0U == (FLEXCAN_GetStatusFlags(base) & - ((uint32_t)kFLEXCAN_TxWarningIntFlag | (uint32_t)kFLEXCAN_RxWarningIntFlag | - (uint32_t)kFLEXCAN_BusOffIntFlag | (uint32_t)kFLEXCAN_ErrorIntFlag | (uint32_t)kFLEXCAN_WakeUpIntFlag))) - { - tempmask = (uint64_t)base->IMASK1; - tempflag = (uint64_t)base->IFLAG1; - -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - /* Checking whether exist MB interrupt status and legacy RX FIFO interrupt status. */ - tempmask |= ((uint64_t)base->IMASK2) << 32; - tempflag |= ((uint64_t)base->IFLAG2) << 32; -#endif - fgRet = (0U != (tempmask & tempflag)); - } - else - { - fgRet = true; - } - - return fgRet; -} - -static status_t FLEXCAN_SubHandlerForDataTransfered(CAN_Type *base, flexcan_handle_t *handle, uint32_t *pResult) -{ - status_t status = kStatus_FLEXCAN_UnHandled; - uint32_t result = 0xFFU; - - /* For this implementation, we solve the Message with lowest MB index first. */ - for (result = 0U; result < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++) - { - /* Get the lowest unhandled Message Buffer */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - if (0U != FLEXCAN_GetMbStatusFlags(base, u64flag << result)) -#else - uint32_t u32flag = 1; - if (0U != FLEXCAN_GetMbStatusFlags(base, u32flag << result)) -#endif - { - if (FLEXCAN_IsMbIntEnabled(base, (uint8_t)result)) - { - break; - } - } - } - - /* find Message to deal with. */ - if (result < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) - { - /* Solve Legacy Rx FIFO interrupt. */ - if (((uint8_t)kFLEXCAN_StateIdle != handle->rxFifoState) && (result <= (uint32_t)CAN_IFLAG1_BUF7I_SHIFT)) - { - uint32_t u32mask = 1; - switch (u32mask << result) - { - case kFLEXCAN_RxFifoOverflowFlag: - status = kStatus_FLEXCAN_RxFifoOverflow; - break; - - case kFLEXCAN_RxFifoWarningFlag: - status = kStatus_FLEXCAN_RxFifoWarning; - break; - - case kFLEXCAN_RxFifoFrameAvlFlag: - status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf); - if (kStatus_Success == status) - { - /* Align the current (index 0) rxfifo timestamp to the timestamp array by handle. */ - handle->timestamp[0] = handle->rxFifoFrameBuf->timestamp; - status = kStatus_FLEXCAN_RxFifoIdle; - } - FLEXCAN_TransferAbortReceiveFifo(base, handle); - break; - - default: - status = kStatus_FLEXCAN_UnHandled; - break; - } - } - else - { - /* Get current State of Message Buffer. */ - switch (handle->mbState[result]) - { - /* Solve Rx Data Frame. */ - case (uint8_t)kFLEXCAN_StateRxData: -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - if (0U != (base->MCR & CAN_MCR_FDEN_MASK)) - { - status = FLEXCAN_ReadFDRxMb(base, (uint8_t)result, handle->mbFDFrameBuf[result]); - if (kStatus_Success == status) - { - /* Align the current index of RX MB timestamp to the timestamp array by handle. */ - handle->timestamp[result] = handle->mbFDFrameBuf[result]->timestamp; - status = kStatus_FLEXCAN_RxIdle; - } - } - else -#endif - { - status = FLEXCAN_ReadRxMb(base, (uint8_t)result, handle->mbFrameBuf[result]); - if (kStatus_Success == status) - { - /* Align the current index of RX MB timestamp to the timestamp array by handle. */ - handle->timestamp[result] = handle->mbFrameBuf[result]->timestamp; - status = kStatus_FLEXCAN_RxIdle; - } - } -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - if (0U != (base->MCR & CAN_MCR_FDEN_MASK)) - { - FLEXCAN_TransferFDAbortReceive(base, handle, (uint8_t)result); - } - else -#endif - { - FLEXCAN_TransferAbortReceive(base, handle, (uint8_t)result); - } - break; - - /* Sove Rx Remote Frame. User need to Read the frame in Mail box in time by Read from MB API. */ - case (uint8_t)kFLEXCAN_StateRxRemote: - status = kStatus_FLEXCAN_RxRemote; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - if (0U != (base->MCR & CAN_MCR_FDEN_MASK)) - { - FLEXCAN_TransferFDAbortReceive(base, handle, (uint8_t)result); - } - else -#endif - { - FLEXCAN_TransferAbortReceive(base, handle, (uint8_t)result); - } - break; - - /* Solve Tx Data Frame. */ - case (uint8_t)kFLEXCAN_StateTxData: - status = kStatus_FLEXCAN_TxIdle; -#if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) - if (0U != (base->MCR & CAN_MCR_FDEN_MASK)) - { - FLEXCAN_TransferFDAbortSend(base, handle, (uint8_t)result); - } - else -#endif - { - FLEXCAN_TransferAbortSend(base, handle, (uint8_t)result); - } - break; - - /* Solve Tx Remote Frame. */ - case (uint8_t)kFLEXCAN_StateTxRemote: - handle->mbState[result] = (uint8_t)kFLEXCAN_StateRxRemote; - status = kStatus_FLEXCAN_TxSwitchToRx; - break; - - default: - status = kStatus_FLEXCAN_UnHandled; - break; - } - } - - /* Clear resolved Message Buffer IRQ. */ -#if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0) - uint64_t u64flag = 1; - FLEXCAN_ClearMbStatusFlags(base, u64flag << result); -#else - uint32_t u32flag = 1; - FLEXCAN_ClearMbStatusFlags(base, u32flag << result); -#endif - } - - *pResult = result; - - return status; -} - -/*! - * brief FlexCAN IRQ handle function. - * - * This function handles the FlexCAN Error, the Message Buffer, and the Rx FIFO IRQ request. - * - * param base FlexCAN peripheral base address. - * param handle FlexCAN handle pointer. - */ -void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle) -{ - /* Assertion. */ - assert(NULL != handle); - - status_t status; - uint32_t result = 0xFFU; - uint32_t EsrStatus = 0U; - - do - { - /* Get Current FlexCAN Module Error and Status. */ - EsrStatus = FLEXCAN_GetStatusFlags(base); - - /* To handle FlexCAN Error and Status Interrupt first. */ - if (0U != (EsrStatus & ((uint32_t)kFLEXCAN_TxWarningIntFlag | (uint32_t)kFLEXCAN_RxWarningIntFlag | - (uint32_t)kFLEXCAN_BusOffIntFlag | (uint32_t)kFLEXCAN_ErrorIntFlag))) - { - status = kStatus_FLEXCAN_ErrorStatus; - /* Clear FlexCAN Error and Status Interrupt. */ - FLEXCAN_ClearStatusFlags(base, (uint32_t)kFLEXCAN_TxWarningIntFlag | (uint32_t)kFLEXCAN_RxWarningIntFlag | - (uint32_t)kFLEXCAN_BusOffIntFlag | (uint32_t)kFLEXCAN_ErrorIntFlag); - result = EsrStatus; - } - else if (0U != (EsrStatus & (uint32_t)kFLEXCAN_WakeUpIntFlag)) - { - status = kStatus_FLEXCAN_WakeUp; - FLEXCAN_ClearStatusFlags(base, (uint32_t)kFLEXCAN_WakeUpIntFlag); - } - else - { - /* to handle real data transfer. */ - status = FLEXCAN_SubHandlerForDataTransfered(base, handle, &result); - } - - /* Calling Callback Function if has one. */ - if (handle->callback != NULL) - { - handle->callback(base, handle, status, result, handle->userData); - } - } while (FLEXCAN_CheckUnhandleInterruptEvents(base)); -} - -#if defined(CAN0) -void CAN0_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[0]); - - s_flexcanIsr(CAN0, s_flexcanHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CAN1) -void CAN1_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[1]); - - s_flexcanIsr(CAN1, s_flexcanHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CAN2) -void CAN2_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[2]); - - s_flexcanIsr(CAN2, s_flexcanHandle[2]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CAN3) -void CAN3_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[3]); - - s_flexcanIsr(CAN3, s_flexcanHandle[3]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CAN4) -void CAN4_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[4]); - - s_flexcanIsr(CAN4, s_flexcanHandle[4]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__CAN0) -void DMA_FLEXCAN0_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]); - - s_flexcanIsr(DMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__CAN1) -void DMA_FLEXCAN1_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]); - - s_flexcanIsr(DMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__CAN2) -void DMA_FLEXCAN2_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]); - - s_flexcanIsr(DMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__CAN0) -void ADMA_FLEXCAN0_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]); - - s_flexcanIsr(ADMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__CAN1) -void ADMA_FLEXCAN1_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]); - - s_flexcanIsr(ADMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__CAN2) -void ADMA_FLEXCAN2_INT_DriverIRQHandler(void) -{ - assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]); - - s_flexcanIsr(ADMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]); - SDK_ISR_EXIT_BARRIER; -} -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio.c deleted file mode 100644 index af14b5e28f..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio" -#endif - -/*< @brief user configurable flexio handle count. */ -#define FLEXIO_HANDLE_COUNT 2 - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to flexio bases for each instance. */ -FLEXIO_Type *const s_flexioBases[] = FLEXIO_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to flexio clocks for each instance. */ -const clock_ip_name_t s_flexioClocks[] = FLEXIO_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*< @brief pointer to array of FLEXIO handle. */ -static void *s_flexioHandle[FLEXIO_HANDLE_COUNT]; - -/*< @brief pointer to array of FLEXIO IP types. */ -static void *s_flexioType[FLEXIO_HANDLE_COUNT]; - -/*< @brief pointer to array of FLEXIO Isr. */ -static flexio_isr_t s_flexioIsr[FLEXIO_HANDLE_COUNT]; - -/******************************************************************************* - * Codes - ******************************************************************************/ - -/*! - * brief Get instance number for FLEXIO module. - * - * param base FLEXIO peripheral base address. - */ -uint32_t FLEXIO_GetInstance(FLEXIO_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_flexioBases); instance++) - { - if (s_flexioBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_flexioBases)); - - return instance; -} - -/*! - * brief Configures the FlexIO with a FlexIO configuration. The configuration structure - * can be filled by the user or be set with default values by FLEXIO_GetDefaultConfig(). - * - * Example - code - flexio_config_t config = { - .enableFlexio = true, - .enableInDoze = false, - .enableInDebug = true, - .enableFastAccess = false - }; - FLEXIO_Configure(base, &config); - endcode - * - * param base FlexIO peripheral base address - * param userConfig pointer to flexio_config_t structure -*/ -void FLEXIO_Init(FLEXIO_Type *base, const flexio_config_t *userConfig) -{ - uint32_t ctrlReg = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_EnableClock(s_flexioClocks[FLEXIO_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - FLEXIO_Reset(base); - - ctrlReg = base->CTRL; - ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(userConfig->enableFlexio)); - if (!userConfig->enableInDoze) - { - ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; - } - - base->CTRL = ctrlReg; -} - -/*! - * brief Gates the FlexIO clock. Call this API to stop the FlexIO clock. - * - * note After calling this API, call the FLEXO_Init to use the FlexIO module. - * - * param base FlexIO peripheral base address - */ -void FLEXIO_Deinit(FLEXIO_Type *base) -{ - FLEXIO_Enable(base, false); -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(s_flexioClocks[FLEXIO_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the default configuration to configure the FlexIO module. The configuration - * can used directly to call the FLEXIO_Configure(). - * - * Example: - code - flexio_config_t config; - FLEXIO_GetDefaultConfig(&config); - endcode - * - * param userConfig pointer to flexio_config_t structure -*/ -void FLEXIO_GetDefaultConfig(flexio_config_t *userConfig) -{ - assert(userConfig != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(userConfig, 0, sizeof(*userConfig)); - - userConfig->enableFlexio = true; - userConfig->enableInDoze = false; - userConfig->enableInDebug = true; - userConfig->enableFastAccess = false; -} - -/*! - * brief Resets the FlexIO module. - * - * param base FlexIO peripheral base address - */ -void FLEXIO_Reset(FLEXIO_Type *base) -{ - /*do software reset, software reset operation affect all other FLEXIO registers except CTRL*/ - base->CTRL |= FLEXIO_CTRL_SWRST_MASK; - base->CTRL = 0; -} - -/*! - * brief Gets the shifter buffer address for the DMA transfer usage. - * - * param base FlexIO peripheral base address - * param type Shifter type of flexio_shifter_buffer_type_t - * param index Shifter index - * return Corresponding shifter buffer index - */ -uint32_t FLEXIO_GetShifterBufferAddress(FLEXIO_Type *base, flexio_shifter_buffer_type_t type, uint8_t index) -{ - assert(index < FLEXIO_SHIFTBUF_COUNT); - - uint32_t address = 0; - - switch (type) - { - case kFLEXIO_ShifterBuffer: - address = (uint32_t) & (base->SHIFTBUF[index]); - break; - - case kFLEXIO_ShifterBufferBitSwapped: - address = (uint32_t) & (base->SHIFTBUFBIS[index]); - break; - - case kFLEXIO_ShifterBufferByteSwapped: - address = (uint32_t) & (base->SHIFTBUFBYS[index]); - break; - - case kFLEXIO_ShifterBufferBitByteSwapped: - address = (uint32_t) & (base->SHIFTBUFBBS[index]); - break; - -#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_BYTE_SWAP - case kFLEXIO_ShifterBufferNibbleByteSwapped: - address = (uint32_t) & (base->SHIFTBUFNBS[index]); - break; - -#endif -#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_HALF_WORD_SWAP - case kFLEXIO_ShifterBufferHalfWordSwapped: - address = (uint32_t) & (base->SHIFTBUFHWS[index]); - break; - -#endif -#if defined(FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP) && FSL_FEATURE_FLEXIO_HAS_SHFT_BUFFER_NIBBLE_SWAP - case kFLEXIO_ShifterBufferNibbleSwapped: - address = (uint32_t) & (base->SHIFTBUFNIS[index]); - break; - -#endif - default: - address = (uint32_t) & (base->SHIFTBUF[index]); - break; - } - return address; -} - -/*! - * brief Configures the shifter with the shifter configuration. The configuration structure - * covers both the SHIFTCTL and SHIFTCFG registers. To configure the shifter to the proper - * mode, select which timer controls the shifter to shift, whether to generate start bit/stop - * bit, and the polarity of start bit and stop bit. - * - * Example - code - flexio_shifter_config_t config = { - .timerSelect = 0, - .timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive, - .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, - .pinPolarity = kFLEXIO_PinActiveLow, - .shifterMode = kFLEXIO_ShifterModeTransmit, - .inputSource = kFLEXIO_ShifterInputFromPin, - .shifterStop = kFLEXIO_ShifterStopBitHigh, - .shifterStart = kFLEXIO_ShifterStartBitLow - }; - FLEXIO_SetShifterConfig(base, &config); - endcode - * - * param base FlexIO peripheral base address - * param index Shifter index - * param shifterConfig Pointer to flexio_shifter_config_t structure -*/ -void FLEXIO_SetShifterConfig(FLEXIO_Type *base, uint8_t index, const flexio_shifter_config_t *shifterConfig) -{ - base->SHIFTCFG[index] = FLEXIO_SHIFTCFG_INSRC(shifterConfig->inputSource) -#if FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH - | FLEXIO_SHIFTCFG_PWIDTH(shifterConfig->parallelWidth) -#endif /* FSL_FEATURE_FLEXIO_HAS_PARALLEL_WIDTH */ - | FLEXIO_SHIFTCFG_SSTOP(shifterConfig->shifterStop) | - FLEXIO_SHIFTCFG_SSTART(shifterConfig->shifterStart); - - base->SHIFTCTL[index] = - FLEXIO_SHIFTCTL_TIMSEL(shifterConfig->timerSelect) | FLEXIO_SHIFTCTL_TIMPOL(shifterConfig->timerPolarity) | - FLEXIO_SHIFTCTL_PINCFG(shifterConfig->pinConfig) | FLEXIO_SHIFTCTL_PINSEL(shifterConfig->pinSelect) | - FLEXIO_SHIFTCTL_PINPOL(shifterConfig->pinPolarity) | FLEXIO_SHIFTCTL_SMOD(shifterConfig->shifterMode); -} - -/*! - * brief Configures the timer with the timer configuration. The configuration structure - * covers both the TIMCTL and TIMCFG registers. To configure the timer to the proper - * mode, select trigger source for timer and the timer pin output and the timing for timer. - * - * Example - code - flexio_timer_config_t config = { - .triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(0), - .triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow, - .triggerSource = kFLEXIO_TimerTriggerSourceInternal, - .pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection, - .pinSelect = 0, - .pinPolarity = kFLEXIO_PinActiveHigh, - .timerMode = kFLEXIO_TimerModeDual8BitBaudBit, - .timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset, - .timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput, - .timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput, - .timerDisable = kFLEXIO_TimerDisableOnTimerCompare, - .timerEnable = kFLEXIO_TimerEnableOnTriggerHigh, - .timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable, - .timerStart = kFLEXIO_TimerStartBitEnabled - }; - FLEXIO_SetTimerConfig(base, &config); - endcode - * - * param base FlexIO peripheral base address - * param index Timer index - * param timerConfig Pointer to the flexio_timer_config_t structure -*/ -void FLEXIO_SetTimerConfig(FLEXIO_Type *base, uint8_t index, const flexio_timer_config_t *timerConfig) -{ - base->TIMCFG[index] = - FLEXIO_TIMCFG_TIMOUT(timerConfig->timerOutput) | FLEXIO_TIMCFG_TIMDEC(timerConfig->timerDecrement) | - FLEXIO_TIMCFG_TIMRST(timerConfig->timerReset) | FLEXIO_TIMCFG_TIMDIS(timerConfig->timerDisable) | - FLEXIO_TIMCFG_TIMENA(timerConfig->timerEnable) | FLEXIO_TIMCFG_TSTOP(timerConfig->timerStop) | - FLEXIO_TIMCFG_TSTART(timerConfig->timerStart); - - base->TIMCMP[index] = FLEXIO_TIMCMP_CMP(timerConfig->timerCompare); - - base->TIMCTL[index] = FLEXIO_TIMCTL_TRGSEL(timerConfig->triggerSelect) | - FLEXIO_TIMCTL_TRGPOL(timerConfig->triggerPolarity) | - FLEXIO_TIMCTL_TRGSRC(timerConfig->triggerSource) | - FLEXIO_TIMCTL_PINCFG(timerConfig->pinConfig) | FLEXIO_TIMCTL_PINSEL(timerConfig->pinSelect) | - FLEXIO_TIMCTL_PINPOL(timerConfig->pinPolarity) | FLEXIO_TIMCTL_TIMOD(timerConfig->timerMode); -} - -/*! - * brief Registers the handle and the interrupt handler for the FlexIO-simulated peripheral. - * - * param base Pointer to the FlexIO simulated peripheral type. - * param handle Pointer to the handler for FlexIO simulated peripheral. - * param isr FlexIO simulated peripheral interrupt handler. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_RegisterHandleIRQ(void *base, void *handle, flexio_isr_t isr) -{ - assert(base != NULL); - assert(handle != NULL); - assert(isr != NULL); - - uint8_t index; - - /* Find the an empty handle pointer to store the handle. */ - for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++) - { - if (s_flexioHandle[index] == NULL) - { - /* Register FLEXIO simulated driver base, handle and isr. */ - s_flexioType[index] = base; - s_flexioHandle[index] = handle; - s_flexioIsr[index] = isr; - break; - } - } - - if (index == (uint8_t)FLEXIO_HANDLE_COUNT) - { - return kStatus_OutOfRange; - } - else - { - return kStatus_Success; - } -} - -/*! - * brief Unregisters the handle and the interrupt handler for the FlexIO-simulated peripheral. - * - * param base Pointer to the FlexIO simulated peripheral type. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_UnregisterHandleIRQ(void *base) -{ - assert(base != NULL); - - uint8_t index; - - /* Find the index from base address mappings. */ - for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++) - { - if (s_flexioType[index] == base) - { - /* Unregister FLEXIO simulated driver handle and isr. */ - s_flexioType[index] = NULL; - s_flexioHandle[index] = NULL; - s_flexioIsr[index] = NULL; - break; - } - } - - if (index == (uint8_t)FLEXIO_HANDLE_COUNT) - { - return kStatus_OutOfRange; - } - else - { - return kStatus_Success; - } -} - -void FLEXIO_CommonIRQHandler(void) -{ - uint8_t index; - - for (index = 0U; index < (uint8_t)FLEXIO_HANDLE_COUNT; index++) - { - if (s_flexioHandle[index] != NULL) - { - s_flexioIsr[index](s_flexioType[index], s_flexioHandle[index]); - } - } - SDK_ISR_EXIT_BARRIER; -} - -void FLEXIO_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} - -void FLEXIO0_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} - -void FLEXIO1_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} - -void UART2_FLEXIO_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} - -void FLEXIO2_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} - -void FLEXIO3_DriverIRQHandler(void) -{ - FLEXIO_CommonIRQHandler(); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera.c deleted file mode 100644 index 3f5fb2ffd3..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_camera.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_camera" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Codes - ******************************************************************************/ - -static uint32_t FLEXIO_CAMERA_GetInstance(FLEXIO_CAMERA_Type *base) -{ - return FLEXIO_GetInstance(base->flexioBase); -} - -/*! - * brief Gets the default configuration to configure the FlexIO Camera. The configuration - * can be used directly for calling the FLEXIO_CAMERA_Init(). - * Example: - code - flexio_camera_config_t config; - FLEXIO_CAMERA_GetDefaultConfig(&userConfig); - endcode - * param config Pointer to the flexio_camera_config_t structure -*/ -void FLEXIO_CAMERA_GetDefaultConfig(flexio_camera_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enablecamera = false; - config->enableInDoze = false; - config->enableInDebug = false; - config->enableFastAccess = false; -} - -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO Camera. - * - * param base Pointer to FLEXIO_CAMERA_Type structure - * param config Pointer to flexio_camera_config_t structure - */ -void FLEXIO_CAMERA_Init(FLEXIO_CAMERA_Type *base, const flexio_camera_config_t *config) -{ - assert((base != NULL) && (config != NULL)); - assert(base->shifterCount > 0U); - - uint32_t i = 0U; - volatile uint32_t controlVal = 0U; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_CAMERA_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - flexio_shifter_config_t shifterConfig; - flexio_timer_config_t timerConfig; - - /* Clear the shifterConfig & timerConfig struct. */ - (void)memset(&shifterConfig, 0, sizeof(shifterConfig)); - (void)memset(&timerConfig, 0, sizeof(timerConfig)); - - /* Configure flexio camera */ - controlVal = base->flexioBase->CTRL; - controlVal &= - ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - controlVal |= (FLEXIO_CTRL_DBGE(config->enableInDebug) | FLEXIO_CTRL_FASTACC(config->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(config->enablecamera)); - if (!config->enableInDoze) - { - controlVal |= FLEXIO_CTRL_DOZEN_MASK; - } - base->flexioBase->CTRL = controlVal; - - /* FLEXIO_CAMERA shifter config */ - shifterConfig.timerSelect = base->timerIdx; - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinSelect = base->datPinStartIdx; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.parallelWidth = FLEXIO_CAMERA_PARALLEL_DATA_WIDTH - 1U; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromNextShifterOutput; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - /* Configure the shifters as FIFO buffer. */ - for (i = base->shifterStartIdx; i < (base->shifterStartIdx + base->shifterCount - 1U); i++) - { - FLEXIO_SetShifterConfig(base->flexioBase, (uint8_t)i, &shifterConfig); - } - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - FLEXIO_SetShifterConfig(base->flexioBase, (uint8_t)i, &shifterConfig); - - /* FLEXIO_CAMERA timer config, the PCLK's clk is source of timer to drive the shifter, the HREF is the selecting - * signal for available data. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->hrefPinIdx); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->pclkPinIdx; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; - timerConfig.timerReset = kFLEXIO_TimerResetOnTimerTriggerRisingEdge; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - timerConfig.timerCompare = 8U * base->shifterCount - 1U; - - FLEXIO_SetTimerConfig(base->flexioBase, (uint8_t)base->timerIdx, &timerConfig); - /* Clear flags. */ - FLEXIO_ClearShifterErrorFlags(base->flexioBase, (((1UL << (base->shifterCount)) - 1U) << (base->shifterStartIdx))); - FLEXIO_ClearTimerStatusFlags(base->flexioBase, 1UL << (base->timerIdx)); -} - -/*! - * brief Resets the FLEXIO_CAMERA shifer and timer config. - * - * note After calling this API, call FLEXO_CAMERA_Init to use the FlexIO Camera module. - * - * param base Pointer to FLEXIO_CAMERA_Type structure - */ -void FLEXIO_CAMERA_Deinit(FLEXIO_CAMERA_Type *base) -{ - base->flexioBase->SHIFTCFG[base->shifterStartIdx] = 0; - base->flexioBase->SHIFTCTL[base->shifterStartIdx] = 0; - base->flexioBase->TIMCFG[base->timerIdx] = 0; - base->flexioBase->TIMCMP[base->timerIdx] = 0; - base->flexioBase->TIMCTL[base->timerIdx] = 0; - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = (1UL << base->shifterStartIdx); - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIdx); -} - -/*! - * brief Gets the FlexIO Camera status flags. - * - * param base Pointer to FLEXIO_CAMERA_Type structure - * return FlexIO shifter status flags - * arg FLEXIO_SHIFTSTAT_SSF_MASK - * arg 0 - */ -uint32_t FLEXIO_CAMERA_GetStatusFlags(FLEXIO_CAMERA_Type *base) -{ - uint32_t status = 0; - status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) >> (base->shifterStartIdx)) & - ((1U << (base->shifterCount)) - 1U)); - return status; -} - -/*! - * brief Clears the receive buffer full flag manually. - * - * param base Pointer to the device. - * param mask status flag - * The parameter can be any combination of the following values: - * arg kFLEXIO_CAMERA_RxDataRegFullFlag - * arg kFLEXIO_CAMERA_RxErrorFlag - */ -void FLEXIO_CAMERA_ClearStatusFlags(FLEXIO_CAMERA_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_CAMERA_RxDataRegFullFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, ((1UL << (base->shifterCount)) - 1U) - << (base->shifterStartIdx)); - } - if ((mask & (uint32_t)kFLEXIO_CAMERA_RxErrorFlag) != 0U) - { /* Clear error flags if they are asserted to make sure the buffer would be available. */ - FLEXIO_ClearShifterErrorFlags(base->flexioBase, ((1UL << (base->shifterCount)) - 1U) - << (base->shifterStartIdx)); - } -} - -/*! - * brief Switches on the interrupt for receive buffer full event. - * - * param base Pointer to the device. - */ -void FLEXIO_CAMERA_EnableInterrupt(FLEXIO_CAMERA_Type *base) -{ - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << (base->shifterStartIdx)); -} - -/*! - * brief Switches off the interrupt for receive buffer full event. - * - * param base Pointer to the device. - * - */ -void FLEXIO_CAMERA_DisableInterrupt(FLEXIO_CAMERA_Type *base) -{ - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << (base->shifterStartIdx)); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera_edma.c deleted file mode 100644 index 12bb77b020..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_camera_edma.c +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_camera_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_camera_edma" -#endif - -/*<! Structure definition for camera_edma_private_handle_t. The structure is private. */ -typedef struct _flexio_camera_edma_private_handle -{ - FLEXIO_CAMERA_Type *base; - flexio_camera_edma_handle_t *handle; -} flexio_camera_edma_private_handle_t; - -/* CAMERA EDMA transfer handle. */ -enum _flexio_camera_edma_tansfer_states -{ - kFLEXIO_CAMERA_RxIdle, /* RX idle. */ - kFLEXIO_CAMERA_RxBusy /* RX busy. */ -}; - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*< @brief user configurable flexio camera handle count. */ -#define FLEXIO_CAMERA_HANDLE_COUNT 1 - -/*<! Private handle only used for internally. */ -static flexio_camera_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_CAMERA_HANDLE_COUNT]; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief FLEXIO CAMERA EDMA receive finished callback function. - * - * This function is called when FLEXIO CAMERA EDMA receive finished. It disables the CAMERA - * RX EDMA request and sends @ref kStatus_FLEXIO_CAMERA_RxIdle to CAMERA callback. - * - * @param handle The EDMA handle. - * @param param Callback function parameter. - */ -static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle, - void *param, - bool transferDone, - uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void FLEXIO_CAMERA_TransferReceiveEDMACallback(edma_handle_t *handle, - void *param, - bool transferDone, - uint32_t tcds) -{ - flexio_camera_edma_private_handle_t *cameraPrivateHandle = (flexio_camera_edma_private_handle_t *)param; - - /* Avoid the warning for unused variables. */ - handle = handle; - tcds = tcds; - - if (transferDone) - { - FLEXIO_CAMERA_TransferAbortReceiveEDMA(cameraPrivateHandle->base, cameraPrivateHandle->handle); - - if (cameraPrivateHandle->handle->callback != NULL) - { - cameraPrivateHandle->handle->callback(cameraPrivateHandle->base, cameraPrivateHandle->handle, - kStatus_FLEXIO_CAMERA_RxIdle, cameraPrivateHandle->handle->userData); - } - } -} -/*! - * brief Initializes the Camera handle, which is used in transactional functions. - * - * param base Pointer to the FLEXIO_CAMERA_Type. - * param handle Pointer to flexio_camera_edma_handle_t structure. - * param callback The callback function. - * param userData The parameter of the callback function. - * param rxEdmaHandle User requested DMA handle for RX DMA transfer. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO Camera eDMA type/handle table out of range. - */ -status_t FLEXIO_CAMERA_TransferCreateHandleEDMA(FLEXIO_CAMERA_Type *base, - flexio_camera_edma_handle_t *handle, - flexio_camera_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *rxEdmaHandle) -{ - assert(handle != NULL); - - uint8_t index; - - /* Find the an empty handle pointer to store the handle. */ - for (index = 0U; index < (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT; index++) - { - if (s_edmaPrivateHandle[index].base == NULL) - { - s_edmaPrivateHandle[index].base = base; - s_edmaPrivateHandle[index].handle = handle; - break; - } - } - - if (index == (uint8_t)FLEXIO_CAMERA_HANDLE_COUNT) - { - return kStatus_OutOfRange; - } - - s_edmaPrivateHandle[index].base = base; - s_edmaPrivateHandle[index].handle = handle; - - (void)memset(handle, 0, sizeof(*handle)); - - handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxIdle; - handle->rxEdmaHandle = rxEdmaHandle; - - handle->callback = callback; - handle->userData = userData; - - /* Configure RX. */ - if (rxEdmaHandle != NULL) - { - EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_CAMERA_TransferReceiveEDMACallback, &s_edmaPrivateHandle); - } - - return kStatus_Success; -} - -/*! - * brief Receives data using eDMA. - * - * This function receives data using eDMA. This is a non-blocking function, which returns - * right away. When all data is received, the receive callback function is called. - * - * param base Pointer to the FLEXIO_CAMERA_Type. - * param handle Pointer to the flexio_camera_edma_handle_t structure. - * param xfer Camera eDMA transfer structure, see #flexio_camera_transfer_t. - * retval kStatus_Success if succeeded, others failed. - * retval kStatus_CAMERA_RxBusy Previous transfer on going. - */ -status_t FLEXIO_CAMERA_TransferReceiveEDMA(FLEXIO_CAMERA_Type *base, - flexio_camera_edma_handle_t *handle, - flexio_camera_transfer_t *xfer) -{ - assert(handle->rxEdmaHandle != NULL); - - edma_transfer_config_t xferConfig; - status_t status; - - /* If previous RX not finished. */ - if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState) - { - status = kStatus_FLEXIO_CAMERA_RxBusy; - } - else - { - handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxBusy; - - /* Prepare transfer. */ - EDMA_PrepareTransfer(&xferConfig, (uint32_t *)FLEXIO_CAMERA_GetRxBufferAddress(base), 32, - (uint32_t *)xfer->dataAddress, 32, 32, xfer->dataNum, kEDMA_PeripheralToMemory); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO CAMERA handle */ - handle->nbytes = 32; - - /* Submit transfer. */ - (void)EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); - EDMA_StartTransfer(handle->rxEdmaHandle); - /* Enable CAMERA RX EDMA. */ - FLEXIO_CAMERA_EnableRxDMA(base, true); - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the receive data which used the eDMA. - * - * This function aborts the receive data which used the eDMA. - * - * param base Pointer to the FLEXIO_CAMERA_Type. - * param handle Pointer to the flexio_camera_edma_handle_t structure. - */ -void FLEXIO_CAMERA_TransferAbortReceiveEDMA(FLEXIO_CAMERA_Type *base, flexio_camera_edma_handle_t *handle) -{ - assert(handle->rxEdmaHandle != NULL); - - /* Disable CAMERA RX EDMA. */ - FLEXIO_CAMERA_EnableRxDMA(base, false); - - /* Stop transfer. */ - EDMA_StopTransfer(handle->rxEdmaHandle); - - handle->rxState = (uint8_t)kFLEXIO_CAMERA_RxIdle; -} - -/*! - * brief Gets the remaining bytes to be received. - * - * This function gets the number of bytes still not received. - * - * param base Pointer to the FLEXIO_CAMERA_Type. - * param handle Pointer to the flexio_camera_edma_handle_t structure. - * param count Number of bytes sent so far by the non-blocking transaction. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_InvalidArgument The count parameter is invalid. - */ -status_t FLEXIO_CAMERA_TransferGetReceiveCountEDMA(FLEXIO_CAMERA_Type *base, - flexio_camera_edma_handle_t *handle, - size_t *count) -{ - assert(handle->rxEdmaHandle != NULL); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - if ((uint8_t)kFLEXIO_CAMERA_RxBusy == handle->rxState) - { - *count = (handle->rxSize - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel)); - } - else - { - *count = handle->rxSize; - } - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2c_master.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2c_master.c deleted file mode 100644 index 43b5bc1b88..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2c_master.c +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_i2c_master.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_i2c_master" -#endif - -/*! @brief FLEXIO I2C transfer state */ -enum _flexio_i2c_master_transfer_states -{ - kFLEXIO_I2C_Idle = 0x0U, /*!< I2C bus idle */ - kFLEXIO_I2C_Start = 0x1U, /*!< I2C start phase */ - kFLEXIO_I2C_SendCommand = 0x2U, /*!< Send command byte phase */ - kFLEXIO_I2C_SendData = 0x3U, /*!< Send data transfer phase*/ - kFLEXIO_I2C_ReceiveDataBegin = 0x4U, /*!< Receive data begin transfer phase*/ - kFLEXIO_I2C_ReceiveData = 0x5U, /*!< Receive data transfer phase*/ -}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Set up master transfer, send slave address and decide the initial - * transfer state. - * - * @param base pointer to FLEXIO_I2C_Type structure - * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state - * @param transfer pointer to flexio_i2c_master_transfer_t structure - */ -static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - flexio_i2c_master_transfer_t *xfer); - -/*! - * @brief Master run transfer state machine to perform a byte of transfer. - * - * @param base pointer to FLEXIO_I2C_Type structure - * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state - * @param statusFlags flexio i2c hardware status - * @retval kStatus_Success Successfully run state machine - * @retval kStatus_FLEXIO_I2C_Nak Receive Nak during transfer - */ -static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - uint32_t statusFlags); - -/*! - * @brief Complete transfer, disable interrupt and call callback. - * - * @param base pointer to FLEXIO_I2C_Type structure - * @param handle pointer to flexio_i2c_master_handle_t structure which stores the transfer state - * @param status flexio transfer status - */ -static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - status_t status); - -/******************************************************************************* - * Codes - ******************************************************************************/ - -static uint32_t FLEXIO_I2C_GetInstance(FLEXIO_I2C_Type *base) -{ - return FLEXIO_GetInstance(base->flexioBase); -} - -static status_t FLEXIO_I2C_MasterTransferInitStateMachine(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - flexio_i2c_master_transfer_t *xfer) -{ - bool needRestart; - uint32_t byteCount; - - /* Init the handle member. */ - handle->transfer.slaveAddress = xfer->slaveAddress; - handle->transfer.direction = xfer->direction; - handle->transfer.subaddress = xfer->subaddress; - handle->transfer.subaddressSize = xfer->subaddressSize; - handle->transfer.data = xfer->data; - handle->transfer.dataSize = xfer->dataSize; - handle->transfer.flags = xfer->flags; - handle->transferSize = xfer->dataSize; - - /* Initial state, i2c start state. */ - handle->state = (uint8_t)kFLEXIO_I2C_Start; - - /* Clear all status before transfer. */ - FLEXIO_I2C_MasterClearStatusFlags(base, (uint32_t)kFLEXIO_I2C_ReceiveNakFlag); - - /* Calculate whether need to send re-start. */ - needRestart = (handle->transfer.subaddressSize != 0U) && (handle->transfer.direction == kFLEXIO_I2C_Read); - handle->needRestart = needRestart; - - /* Calculate total byte count in a frame. */ - byteCount = 1U; - - if (!needRestart) - { - byteCount += handle->transfer.dataSize; - } - - if (handle->transfer.subaddressSize != 0U) - { - byteCount += handle->transfer.subaddressSize; - } - - /* Configure data count. */ - if (FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)byteCount) != kStatus_Success) - { - return kStatus_InvalidArgument; - } - - /* Configure timer1 disable condition. */ - uint32_t tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]]; - tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; - tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPreTimerDisable); - base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig; - -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; - while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) - { - } -#endif - - return kStatus_Success; -} - -static status_t FLEXIO_I2C_MasterTransferRunStateMachine(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - uint32_t statusFlags) -{ -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U) - { - /* Clear receive nak flag. */ - FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - - if ((!((handle->state == (uint8_t)kFLEXIO_I2C_SendData) && (handle->transfer.dataSize == 0U))) && - (!(((handle->state == (uint8_t)kFLEXIO_I2C_ReceiveData) || - (handle->state == (uint8_t)kFLEXIO_I2C_ReceiveDataBegin)) && - (handle->transfer.dataSize == 1U)))) - { - (void)FLEXIO_I2C_MasterReadByte(base); - - FLEXIO_I2C_MasterAbortStop(base); - - /* Delay one clk cycle to ensure the bus is idle. */ - SDK_DelayAtLeastUs(1000000UL / base->baudrate, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); - - handle->state = (uint8_t)kFLEXIO_I2C_Idle; - - return kStatus_FLEXIO_I2C_Nak; - } - } - - if (((statusFlags & (uint8_t)kFLEXIO_I2C_RxFullFlag) != 0U) && (handle->state != (uint8_t)kFLEXIO_I2C_ReceiveData)) - { - (void)FLEXIO_I2C_MasterReadByte(base); - } - - switch (handle->state) - { - /* Initial state, i2c start state. */ - case (uint8_t)kFLEXIO_I2C_Start: - /* Send address byte first. */ - if (handle->needRestart) - { - FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Write); - } - else - { - FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, handle->transfer.direction); - } - if (handle->transfer.subaddressSize == 0U) - { - if (handle->transfer.direction == kFLEXIO_I2C_Write) - { - /* Next state, send data. */ - handle->state = (uint8_t)kFLEXIO_I2C_SendData; - } - else - { - /* Next state, receive data begin. */ - handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin; - } - } - else - { - /* Next state, send command byte. */ - handle->state = (uint8_t)kFLEXIO_I2C_SendCommand; - } - break; - - /* Check address only needed for transfer with subaddress */ - case (uint8_t)kFLEXIO_I2C_SendCommand: - if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U) - { - if (handle->transfer.subaddressSize > 0U) - { - handle->transfer.subaddressSize--; - FLEXIO_I2C_MasterWriteByte( - base, ((handle->transfer.subaddress) >> (8U * handle->transfer.subaddressSize))); - - if (handle->transfer.subaddressSize == 0U) - { - /* Load re-start in advance. */ - if (handle->transfer.direction == kFLEXIO_I2C_Read) - { -#if I2C_RETRY_TIMES - while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & - (1UL << base->shifterIndex[0]))) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == - (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) - { - } -#endif - FLEXIO_I2C_MasterRepeatedStart(base); - } - } - } - else - { - if (handle->transfer.direction == kFLEXIO_I2C_Write) - { - /* Send first byte of data. */ - if (handle->transfer.dataSize > 0U) - { - /* Next state, send data. */ - handle->state = (uint8_t)kFLEXIO_I2C_SendData; - - FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); - handle->transfer.data++; - handle->transfer.dataSize--; - } - else - { - FLEXIO_I2C_MasterStop(base); - -#if I2C_RETRY_TIMES - while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) - { - } -#endif - (void)FLEXIO_I2C_MasterReadByte(base); - - handle->state = (uint8_t)kFLEXIO_I2C_Idle; - } - } - else - { - (void)FLEXIO_I2C_MasterSetTransferCount(base, (uint16_t)(handle->transfer.dataSize + 1U)); - FLEXIO_I2C_MasterStart(base, handle->transfer.slaveAddress, kFLEXIO_I2C_Read); - - /* Next state, receive data begin. */ - handle->state = (uint8_t)kFLEXIO_I2C_ReceiveDataBegin; - } - } - } - break; - - /* Send command byte. */ - case (uint8_t)kFLEXIO_I2C_SendData: - if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U) - { - /* Send one byte of data. */ - if (handle->transfer.dataSize > 0U) - { - FLEXIO_I2C_MasterWriteByte(base, *handle->transfer.data); - - handle->transfer.data++; - handle->transfer.dataSize--; - } - else - { - FLEXIO_I2C_MasterStop(base); - -#if I2C_RETRY_TIMES - while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) - { - } -#endif - (void)FLEXIO_I2C_MasterReadByte(base); - - handle->state = (uint8_t)kFLEXIO_I2C_Idle; - } - } - break; - - case (uint8_t)kFLEXIO_I2C_ReceiveDataBegin: - if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U) - { - handle->state = (uint8_t)kFLEXIO_I2C_ReceiveData; - /* Send nak at the last receive byte. */ - if (handle->transfer.dataSize == 1U) - { - FLEXIO_I2C_MasterEnableAck(base, false); -#if I2C_RETRY_TIMES - while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) - { - } -#endif - FLEXIO_I2C_MasterStop(base); - } - else - { - FLEXIO_I2C_MasterEnableAck(base, true); - } - } - else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U) - { - /* Read one byte of data. */ - FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); - } - else - { - ; /* Avoid MISRA 2012 rule 15.7 */ - } - break; - - case (uint8_t)kFLEXIO_I2C_ReceiveData: - if ((statusFlags & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U) - { - *handle->transfer.data = FLEXIO_I2C_MasterReadByte(base); - handle->transfer.data++; - if (0U != handle->transfer.dataSize--) - { - if (handle->transfer.dataSize == 0U) - { - FLEXIO_I2C_MasterDisableInterrupts(base, (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable); - handle->state = (uint8_t)kFLEXIO_I2C_Idle; - /* Return nak if ReceiveNakFlag is not set */ - if ((statusFlags & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) == 0U) - { - return kStatus_FLEXIO_I2C_Nak; - } - } - - /* Send nak at the last receive byte. */ - if (handle->transfer.dataSize == 1U) - { - FLEXIO_I2C_MasterEnableAck(base, false); -#if I2C_RETRY_TIMES - while ( - (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) - { - } -#endif - FLEXIO_I2C_MasterStop(base); - } - } - } - else if ((statusFlags & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U) - { - if (handle->transfer.dataSize > 1U) - { - FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); - } - } - else - { - ; /* Avoid MISRA 2012 rule 15.7 */ - } - break; - - default: - /* Add comment to avoid MISRA violation */ - break; - } - - return kStatus_Success; -} - -static void FLEXIO_I2C_MasterTransferComplete(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - status_t status) -{ - FLEXIO_I2C_MasterDisableInterrupts( - base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable); - - if (handle->completionCallback != NULL) - { - handle->completionCallback(base, handle, status, handle->userData); - } -} - -#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS -/*! - * brief Make sure the bus isn't already pulled down. - * - * Check the FLEXIO pin status to see whether either of SDA and SCL pin is pulled down. - * - * param base Pointer to FLEXIO_I2C_Type structure.. - * retval kStatus_Success - * retval kStatus_FLEXIO_I2C_Busy - */ -status_t FLEXIO_I2C_CheckForBusyBus(FLEXIO_I2C_Type *base) -{ - uint32_t mask; - /* If in certain loops the SDA/SCL is continuously pulled down, then return bus busy status. */ - /* The loop count is determined by maximum CPU clock frequency */ - for (uint32_t i = 0U; i < SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY / 600000U; ++i) - { - mask = 1UL << base->SDAPinIndex | 1UL << base->SCLPinIndex; - if ((FLEXIO_ReadPinInput(base->flexioBase) & mask) == mask) - { - return kStatus_Success; - } - } - return kStatus_FLEXIO_I2C_Busy; -} -#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/ - -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, and configures the FlexIO I2C - * hardware configuration. - * - * Example - code - FLEXIO_I2C_Type base = { - .flexioBase = FLEXIO, - .SDAPinIndex = 0, - .SCLPinIndex = 1, - .shifterIndex = {0,1}, - .timerIndex = {0,1} - }; - flexio_i2c_master_config_t config = { - .enableInDoze = false, - .enableInDebug = true, - .enableFastAccess = false, - .baudRate_Bps = 100000 - }; - FLEXIO_I2C_MasterInit(base, &config, srcClock_Hz); - endcode - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param masterConfig Pointer to flexio_i2c_master_config_t structure. - * param srcClock_Hz FlexIO source clock in Hz. - * retval kStatus_Success Initialization successful - * retval kStatus_InvalidArgument The source clock exceed upper range limitation -*/ -status_t FLEXIO_I2C_MasterInit(FLEXIO_I2C_Type *base, flexio_i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) -{ - assert((base != NULL) && (masterConfig != NULL)); - - flexio_shifter_config_t shifterConfig; - flexio_timer_config_t timerConfig; - uint32_t controlVal = 0; - uint16_t timerDiv = 0; - status_t result = kStatus_Success; - - (void)memset(&shifterConfig, 0, sizeof(shifterConfig)); - (void)memset(&timerConfig, 0, sizeof(timerConfig)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2C_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Do hardware configuration. */ - /* 1. Configure the shifter 0 for tx. */ - shifterConfig.timerSelect = base->timerIndex[2]; - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - shifterConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; - shifterConfig.pinSelect = base->SDAPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveLow; - shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); - - /* 2. Configure the shifter 1 for rx. */ - shifterConfig.timerSelect = base->timerIndex[2]; - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinSelect = base->SDAPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); - - /*3. Configure the timer 0 and timer 1 for generating bit clock. */ - /* timer 1 is used to config baudrate */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOpenDrainOrBidirection; - timerConfig.pinSelect = base->SCLPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinEqualToTimerOutput; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - - /* Set TIMCMP = (baud rate divider / 2) - 1. */ - timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps) / 2U - 1U; - /* Calculate and assign the actual baudrate. */ - base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U)); - - timerConfig.timerCompare = timerDiv; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); - - /* timer 0 is used to config total shift clock edges */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->SCLPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - - /* Set TIMCMP when confinguring transfer bytes. */ - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); - - /* 4. Configure the timer 2 for controlling shifters. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->SCLPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveLow; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; - timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerCompare; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - - /* Set TIMCMP[15:0] = (number of bits x 2) - 1. */ - timerConfig.timerCompare = 8U * 2U - 1U; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[2], &timerConfig); - - /* Configure FLEXIO I2C Master. */ - controlVal = base->flexioBase->CTRL; - controlVal &= - ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - controlVal |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); - if (!masterConfig->enableInDoze) - { - controlVal |= FLEXIO_CTRL_DOZEN_MASK; - } - - base->flexioBase->CTRL = controlVal; - /* Disable internal IRQs. */ - FLEXIO_I2C_MasterDisableInterrupts( - base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable); - return result; -} - -/*! - * brief De-initializes the FlexIO I2C master peripheral. Calling this API Resets the FlexIO I2C master - * shifer and timer config, module can't work unless the FLEXIO_I2C_MasterInit is called. - * - * param base pointer to FLEXIO_I2C_Type structure. - */ -void FLEXIO_I2C_MasterDeinit(FLEXIO_I2C_Type *base) -{ - base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[0]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[0]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[0]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[1]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[1]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[1]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[2]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[2]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[2]] = 0; - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[0]); - base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[1]); - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex[0]); - base->flexioBase->TIMSTAT = (1UL << base->timerIndex[1]); - base->flexioBase->TIMSTAT = (1UL << base->timerIndex[2]); -} - -/*! - * brief Gets the default configuration to configure the FlexIO module. The configuration - * can be used directly for calling the FLEXIO_I2C_MasterInit(). - * - * Example: - code - flexio_i2c_master_config_t config; - FLEXIO_I2C_MasterGetDefaultConfig(&config); - endcode - * param masterConfig Pointer to flexio_i2c_master_config_t structure. -*/ -void FLEXIO_I2C_MasterGetDefaultConfig(flexio_i2c_master_config_t *masterConfig) -{ - assert(masterConfig != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(masterConfig, 0, sizeof(*masterConfig)); - - masterConfig->enableMaster = true; - masterConfig->enableInDoze = false; - masterConfig->enableInDebug = true; - masterConfig->enableFastAccess = false; - - /* Default baud rate at 100kbps. */ - masterConfig->baudRate_Bps = 100000U; -} - -/*! - * brief Gets the FlexIO I2C master status flags. - * - * param base Pointer to FLEXIO_I2C_Type structure - * return Status flag, use status flag to AND #_flexio_i2c_master_status_flags can get the related status. - */ - -uint32_t FLEXIO_I2C_MasterGetStatusFlags(FLEXIO_I2C_Type *base) -{ - uint32_t status = 0; - - status = - ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]); - status |= - (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) - << 1U); - status |= - (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) - << 2U); - - return status; -} - -/*! - * brief Clears the FlexIO I2C master status flags. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param mask Status flag. - * The parameter can be any combination of the following values: - * arg kFLEXIO_I2C_RxFullFlag - * arg kFLEXIO_I2C_ReceiveNakFlag - */ - -void FLEXIO_I2C_MasterClearStatusFlags(FLEXIO_I2C_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]); - } - - if ((mask & (uint32_t)kFLEXIO_I2C_RxFullFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - } - - if ((mask & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U) - { - FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Enables the FlexIO i2c master interrupt requests. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param mask Interrupt source. - * Currently only one interrupt request source: - * arg kFLEXIO_I2C_TransferCompleteInterruptEnable - */ -void FLEXIO_I2C_MasterEnableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Disables the FlexIO I2C master interrupt requests. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param mask Interrupt source. - */ -void FLEXIO_I2C_MasterDisableInterrupts(FLEXIO_I2C_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Sets the FlexIO I2C master transfer baudrate. - * - * param base Pointer to FLEXIO_I2C_Type structure - * param baudRate_Bps the baud rate value in HZ - * param srcClock_Hz source clock in HZ - */ -void FLEXIO_I2C_MasterSetBaudRate(FLEXIO_I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) -{ - uint16_t timerDiv = 0; - FLEXIO_Type *flexioBase = base->flexioBase; - - /* Set TIMCMP = (baud rate divider / 2) - 1.*/ - timerDiv = (uint16_t)((srcClock_Hz / baudRate_Bps) / 2U - 1U); - - flexioBase->TIMCMP[base->timerIndex[1]] = timerDiv; - - /* Calculate and assign the actual baudrate. */ - base->baudrate = srcClock_Hz / (2U * ((uint32_t)timerDiv + 1U)); -} - -/*! - * brief Sets the number of bytes to be transferred from a start signal to a stop signal. - * - * note Call this API before a transfer begins because the timer generates a number of clocks according - * to the number of bytes that need to be transferred. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param count Number of bytes need to be transferred from a start signal to a re-start/stop signal - * retval kStatus_Success Successfully configured the count. - * retval kStatus_InvalidArgument Input argument is invalid. - */ -status_t FLEXIO_I2C_MasterSetTransferCount(FLEXIO_I2C_Type *base, uint16_t count) -{ - /* Calculate whether the transfer count is larger than the max value compare register can achieve */ - if (count > ((0xFFFFUL - 1UL) / (16UL + 1UL + 1UL))) - { - return kStatus_InvalidArgument; - } - - uint32_t timerConfig = 0U; - FLEXIO_Type *flexioBase = base->flexioBase; - - flexioBase->TIMCMP[base->timerIndex[0]] = (uint32_t)count * 18U + 1U; - timerConfig = flexioBase->TIMCFG[base->timerIndex[0]]; - timerConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; - timerConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare); - flexioBase->TIMCFG[base->timerIndex[0]] = timerConfig; - - return kStatus_Success; -} - -/*! - * brief Sends START + 7-bit address to the bus. - * - * note This API should be called when the transfer configuration is ready to send a START signal - * and 7-bit address to the bus. This is a non-blocking API, which returns directly after the address - * is put into the data register but the address transfer is not finished on the bus. Ensure that - * the kFLEXIO_I2C_RxFullFlag status is asserted before calling this API. - * param base Pointer to FLEXIO_I2C_Type structure. - * param address 7-bit address. - * param direction transfer direction. - * This parameter is one of the values in flexio_i2c_direction_t: - * arg kFLEXIO_I2C_Write: Transmit - * arg kFLEXIO_I2C_Read: Receive - */ - -void FLEXIO_I2C_MasterStart(FLEXIO_I2C_Type *base, uint8_t address, flexio_i2c_direction_t direction) -{ - uint32_t data; - - data = ((uint32_t)address) << 1U | ((direction == kFLEXIO_I2C_Read) ? 1U : 0U); - - FLEXIO_I2C_MasterWriteByte(base, data); -} - -/*! - * brief Sends the repeated start signal on the bus. - * - * param base Pointer to FLEXIO_I2C_Type structure. - */ -void FLEXIO_I2C_MasterRepeatedStart(FLEXIO_I2C_Type *base) -{ - /* Prepare for RESTART condition, no stop.*/ - FLEXIO_I2C_MasterWriteByte(base, 0xFFFFFFFFU); -} - -/*! - * brief Sends the stop signal on the bus. - * - * param base Pointer to FLEXIO_I2C_Type structure. - */ -void FLEXIO_I2C_MasterStop(FLEXIO_I2C_Type *base) -{ - /* Prepare normal stop. */ - (void)FLEXIO_I2C_MasterSetTransferCount(base, 0x0U); - FLEXIO_I2C_MasterWriteByte(base, 0x0U); -} - -/*! - * brief Sends the stop signal when transfer is still on-going. - * - * param base Pointer to FLEXIO_I2C_Type structure. - */ -void FLEXIO_I2C_MasterAbortStop(FLEXIO_I2C_Type *base) -{ - uint32_t tmpConfig; - - /* Prepare abort stop. */ - /* Disable timer 0. */ - tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[0]]; - tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; - tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge); - base->flexioBase->TIMCFG[base->timerIndex[0]] = tmpConfig; - - /* Disable timer 1. */ - tmpConfig = base->flexioBase->TIMCFG[base->timerIndex[1]]; - tmpConfig &= ~FLEXIO_TIMCFG_TIMDIS_MASK; - tmpConfig |= FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnPinBothEdge); - base->flexioBase->TIMCFG[base->timerIndex[1]] = tmpConfig; -} - -/*! - * brief Configures the sent ACK/NAK for the following byte. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param enable True to configure send ACK, false configure to send NAK. - */ -void FLEXIO_I2C_MasterEnableAck(FLEXIO_I2C_Type *base, bool enable) -{ - uint32_t tmpConfig = 0; - - tmpConfig = base->flexioBase->SHIFTCFG[base->shifterIndex[0]]; - tmpConfig &= ~FLEXIO_SHIFTCFG_SSTOP_MASK; - if (enable) - { - tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitLow); - } - else - { - tmpConfig |= FLEXIO_SHIFTCFG_SSTOP(kFLEXIO_ShifterStopBitHigh); - } - base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = tmpConfig; -} - -/*! - * brief Sends a buffer of data in bytes. - * - * note This function blocks via polling until all bytes have been sent. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param txBuff The data bytes to send. - * param txSize The number of data bytes to send. - * retval kStatus_Success Successfully write data. - * retval kStatus_FLEXIO_I2C_Nak Receive NAK during writing data. - * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags. - */ -status_t FLEXIO_I2C_MasterWriteBlocking(FLEXIO_I2C_Type *base, const uint8_t *txBuff, uint8_t txSize) -{ - assert(txBuff != NULL); - assert(txSize != 0U); - - uint32_t status; -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - while (0U != txSize--) - { - FLEXIO_I2C_MasterWriteByte(base, *txBuff++); - - /* Wait until data transfer complete. */ -#if I2C_RETRY_TIMES - waitTimes = I2C_RETRY_TIMES; - while ((0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == ((status = FLEXIO_I2C_MasterGetStatusFlags(base)) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) - { - } -#endif - - if ((status & (uint32_t)kFLEXIO_I2C_ReceiveNakFlag) != 0U) - { - FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - return kStatus_FLEXIO_I2C_Nak; - } - } - return kStatus_Success; -} - -/*! - * brief Receives a buffer of bytes. - * - * note This function blocks via polling until all bytes have been received. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param rxBuff The buffer to store the received bytes. - * param rxSize The number of data bytes to be received. - * retval kStatus_Success Successfully read data. - * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags. - */ -status_t FLEXIO_I2C_MasterReadBlocking(FLEXIO_I2C_Type *base, uint8_t *rxBuff, uint8_t rxSize) -{ - assert(rxBuff != NULL); - assert(rxSize != 0U); - -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - while (0U != rxSize--) - { - /* Wait until data transfer complete. */ -#if I2C_RETRY_TIMES - waitTimes = I2C_RETRY_TIMES; - while ((0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == (FLEXIO_I2C_MasterGetStatusFlags(base) & (uint32_t)kFLEXIO_I2C_RxFullFlag)) - { - } -#endif - *rxBuff++ = FLEXIO_I2C_MasterReadByte(base); - } - return kStatus_Success; -} - -/*! - * brief Performs a master polling transfer on the I2C bus. - * - * note The API does not return until the transfer succeeds or fails due - * to receiving NAK. - * - * param base pointer to FLEXIO_I2C_Type structure. - * param xfer pointer to flexio_i2c_master_transfer_t structure. - * return status of status_t. - */ -status_t FLEXIO_I2C_MasterTransferBlocking(FLEXIO_I2C_Type *base, flexio_i2c_master_transfer_t *xfer) -{ - assert(xfer != NULL); - -#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS - /* Return an error if the bus is already in use not by us.*/ - status_t status = FLEXIO_I2C_CheckForBusyBus(base); - if (status != kStatus_Success) - { - return status; - } -#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/ - - flexio_i2c_master_handle_t tmpHandle; - uint32_t statusFlags; - status_t result = kStatus_Success; -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - /* Zero the handle. */ - (void)memset(&tmpHandle, 0, sizeof(tmpHandle)); - - /* Set up transfer machine. */ - result = FLEXIO_I2C_MasterTransferInitStateMachine(base, &tmpHandle, xfer); - if (result != kStatus_Success) - { - return result; - } - - do - { - /* Wait either tx empty or rx full flag is asserted. */ -#if I2C_RETRY_TIMES - waitTimes = I2C_RETRY_TIMES; - while ((0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) & - ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag))) && - (0U != --waitTimes)) - { - } - if (0U == waitTimes) - { - return kStatus_FLEXIO_I2C_Timeout; - } -#else - while (0U == ((statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base)) & - ((uint32_t)kFLEXIO_I2C_TxEmptyFlag | (uint32_t)kFLEXIO_I2C_RxFullFlag))) - { - } -#endif - FLEXIO_ClearTimerStatusFlags(base->flexioBase, ((1UL << base->timerIndex[0]) | (1UL << base->timerIndex[1]))); - result = FLEXIO_I2C_MasterTransferRunStateMachine(base, &tmpHandle, statusFlags); - - } while ((tmpHandle.state != (uint8_t)kFLEXIO_I2C_Idle) && (result == kStatus_Success)); - - /* Timer disable on timer compare, wait until bit clock TSF set, which means timer disable and stop has been sent. - */ - while (0U == (FLEXIO_GetTimerStatusFlags(base->flexioBase) & (1UL << base->timerIndex[1]))) - { - } - - return result; -} - -/*! - * brief Initializes the I2C handle which is used in transactional functions. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param handle Pointer to flexio_i2c_master_handle_t structure to store the transfer state. - * param callback Pointer to user callback function. - * param userData User param passed to the callback function. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/isr table out of range. - */ -status_t FLEXIO_I2C_MasterTransferCreateHandle(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - flexio_i2c_master_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Register callback and userData. */ - handle->completionCallback = callback; - handle->userData = userData; - - /* Clear pending NVIC IRQ before enable NVIC IRQ. */ - NVIC_ClearPendingIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]); - (void)EnableIRQ(flexio_irqs[FLEXIO_I2C_GetInstance(base)]); - - /* Save the context in global variables to support the double weak mechanism. */ - return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2C_MasterTransferHandleIRQ); -} - -/*! - * brief Performs a master interrupt non-blocking transfer on the I2C bus. - * - * note The API returns immediately after the transfer initiates. - * Call FLEXIO_I2C_MasterTransferGetCount to poll the transfer status to check whether - * the transfer is finished. If the return status is not kStatus_FLEXIO_I2C_Busy, the transfer - * is finished. - * - * param base Pointer to FLEXIO_I2C_Type structure - * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state - * param xfer pointer to flexio_i2c_master_transfer_t structure - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_FLEXIO_I2C_Busy FlexIO I2C is not idle, is running another transfer. - */ -status_t FLEXIO_I2C_MasterTransferNonBlocking(FLEXIO_I2C_Type *base, - flexio_i2c_master_handle_t *handle, - flexio_i2c_master_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - status_t result = kStatus_Success; - -#if defined(FSL_FEATURE_FLEXIO_HAS_PIN_STATUS) && FSL_FEATURE_FLEXIO_HAS_PIN_STATUS - /* Return an error if the bus is already in use not by us.*/ - result = FLEXIO_I2C_CheckForBusyBus(base); - if (result != kStatus_Success) - { - return result; - } -#endif /*FSL_FEATURE_FLEXIO_HAS_PIN_STATUS*/ - - if (handle->state != (uint8_t)kFLEXIO_I2C_Idle) - { - return kStatus_FLEXIO_I2C_Busy; - } - else - { - /* Set up transfer machine. */ - result = FLEXIO_I2C_MasterTransferInitStateMachine(base, handle, xfer); - if (result != kStatus_Success) - { - return result; - } - - /* Enable both tx empty and rxfull interrupt. */ - FLEXIO_I2C_MasterEnableInterrupts( - base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable); - - return kStatus_Success; - } -} - -/*! - * brief Aborts an interrupt non-blocking transfer early. - * - * note This API can be called at any time when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base Pointer to FLEXIO_I2C_Type structure - * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state - */ -void FLEXIO_I2C_MasterTransferAbort(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable interrupts. */ - FLEXIO_I2C_MasterDisableInterrupts( - base, (uint32_t)kFLEXIO_I2C_TxEmptyInterruptEnable | (uint32_t)kFLEXIO_I2C_RxFullInterruptEnable); - - /* Reset to idle state. */ - handle->state = (uint8_t)kFLEXIO_I2C_Idle; -} - -/*! - * brief Gets the master transfer status during a interrupt non-blocking transfer. - * - * param base Pointer to FLEXIO_I2C_Type structure. - * param handle Pointer to flexio_i2c_master_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the non-blocking transaction. - * retval kStatus_InvalidArgument count is Invalid. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_I2C_MasterTransferGetCount(FLEXIO_I2C_Type *base, flexio_i2c_master_handle_t *handle, size_t *count) -{ - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state == (uint8_t)kFLEXIO_I2C_Idle) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - *count = handle->transferSize - handle->transfer.dataSize; - - return kStatus_Success; -} - -/*! - * brief Master interrupt handler. - * - * param i2cType Pointer to FLEXIO_I2C_Type structure - * param i2cHandle Pointer to flexio_i2c_master_transfer_t structure - */ -void FLEXIO_I2C_MasterTransferHandleIRQ(void *i2cType, void *i2cHandle) -{ - FLEXIO_I2C_Type *base = (FLEXIO_I2C_Type *)i2cType; - flexio_i2c_master_handle_t *handle = (flexio_i2c_master_handle_t *)i2cHandle; - uint32_t statusFlags; - status_t result; - - statusFlags = FLEXIO_I2C_MasterGetStatusFlags(base); - - result = FLEXIO_I2C_MasterTransferRunStateMachine(base, handle, statusFlags); - - if (handle->state == (uint8_t)kFLEXIO_I2C_Idle) - { - FLEXIO_I2C_MasterTransferComplete(base, handle, result); - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s.c deleted file mode 100644 index 087e0d691d..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s.c +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_i2s.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_i2s" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ -/*!@brief _sai_transfer_state*/ -enum -{ - kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO_I2S is busy */ - kFLEXIO_I2S_Idle, /*!< Transfer is done. */ -}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Receive a piece of data in non-blocking way. - * - * @param base FLEXIO I2S base pointer - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * @param buffer Pointer to the data to be read. - * @param size Bytes to be read. - */ -static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size); - -/*! - * @brief sends a piece of data in non-blocking way. - * - * @param base FLEXIO I2S base pointer - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * @param buffer Pointer to the data to be written. - * @param size Bytes to be written. - */ -static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size); -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t FLEXIO_I2S_GetInstance(FLEXIO_I2S_Type *base) -{ - return FLEXIO_GetInstance(base->flexioBase); -} - -static void FLEXIO_I2S_WriteNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) -{ - uint32_t i = 0; - uint8_t j = 0; - uint8_t bytesPerWord = bitWidth / 8U; - uint32_t data = 0; - uint32_t temp = 0; - - for (i = 0; i < size / bytesPerWord; i++) - { - for (j = 0; j < bytesPerWord; j++) - { - temp = (uint32_t)(*txData); - data |= (temp << (8U * j)); - txData++; - } - base->flexioBase->SHIFTBUFBIS[base->txShifterIndex] = data << (32U - bitWidth); - data = 0; - } -} - -static void FLEXIO_I2S_ReadNonBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) -{ - uint32_t i = 0; - uint8_t j = 0; - uint8_t bytesPerWord = bitWidth / 8U; - uint32_t data = 0; - - for (i = 0; i < size / bytesPerWord; i++) - { - data = (base->flexioBase->SHIFTBUFBIS[base->rxShifterIndex]); - for (j = 0; j < bytesPerWord; j++) - { - *rxData = (uint8_t)((data >> (8U * j)) & 0xFFU); - rxData++; - } - } -} - -/*! - * brief Initializes the FlexIO I2S. - * - * This API configures FlexIO pins and shifter to I2S and configures the FlexIO I2S with a configuration structure. - * The configuration structure can be filled by the user, or be set with default values by - * FLEXIO_I2S_GetDefaultConfig(). - * - * note This API should be called at the beginning of the application to use - * the FlexIO I2S driver. Otherwise, any access to the FlexIO I2S module can cause hard fault - * because the clock is not enabled. - * - * param base FlexIO I2S base pointer - * param config FlexIO I2S configure structure. - */ -void FLEXIO_I2S_Init(FLEXIO_I2S_Type *base, const flexio_i2s_config_t *config) -{ - assert((base != NULL) && (config != NULL)); - - flexio_shifter_config_t shifterConfig = {0}; - flexio_timer_config_t timerConfig = {0}; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_I2S_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* reset Flexio */ - FLEXIO_Reset(base->flexioBase); - - /* Set shifter for I2S Tx data */ - shifterConfig.timerSelect = base->bclkTimerIndex; - shifterConfig.pinSelect = base->txPinIndex; - shifterConfig.timerPolarity = config->txTimerPolarity; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; - shifterConfig.pinPolarity = config->txPinPolarity; - shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - if (config->masterSlave == kFLEXIO_I2S_Master) - { - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; - } - else - { - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - } - - FLEXIO_SetShifterConfig(base->flexioBase, base->txShifterIndex, &shifterConfig); - - /* Set shifter for I2S Rx Data */ - shifterConfig.timerSelect = base->bclkTimerIndex; - shifterConfig.pinSelect = base->rxPinIndex; - shifterConfig.timerPolarity = config->rxTimerPolarity; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinPolarity = config->rxPinPolarity; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - - FLEXIO_SetShifterConfig(base->flexioBase, base->rxShifterIndex, &shifterConfig); - - /* Set Timer to I2S frame sync */ - if (config->masterSlave == kFLEXIO_I2S_Master) - { - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->txPinIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutput; - timerConfig.pinSelect = base->fsPinIndex; - timerConfig.pinPolarity = config->fsPinPolarity; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableNever; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - } - else - { - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->bclkPinIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->fsPinIndex; - timerConfig.pinPolarity = config->fsPinPolarity; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnTriggerInputShiftTriggerInput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - } - FLEXIO_SetTimerConfig(base->flexioBase, base->fsTimerIndex, &timerConfig); - - /* Set Timer to I2S bit clock */ - if (config->masterSlave == kFLEXIO_I2S_Master) - { - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinSelect = base->bclkPinIndex; - timerConfig.pinConfig = kFLEXIO_PinConfigOutput; - timerConfig.pinPolarity = config->bclkPinPolarity; - timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableNever; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - } - else - { - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->fsTimerIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinSelect = base->bclkPinIndex; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinPolarity = config->bclkPinPolarity; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompareTriggerLow; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdgeTriggerHigh; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - } - FLEXIO_SetTimerConfig(base->flexioBase, base->bclkTimerIndex, &timerConfig); - - /* If enable flexio I2S */ - if (config->enableI2S) - { - base->flexioBase->CTRL |= FLEXIO_CTRL_FLEXEN_MASK; - } - else - { - base->flexioBase->CTRL &= ~FLEXIO_CTRL_FLEXEN_MASK; - } -} - -/*! - * brief Sets the FlexIO I2S configuration structure to default values. - * - * The purpose of this API is to get the configuration structure initialized for use in FLEXIO_I2S_Init(). - * Users may use the initialized structure unchanged in FLEXIO_I2S_Init() or modify - * some fields of the structure before calling FLEXIO_I2S_Init(). - * - * param config pointer to master configuration structure - */ -void FLEXIO_I2S_GetDefaultConfig(flexio_i2s_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->masterSlave = kFLEXIO_I2S_Master; - config->enableI2S = true; - config->txPinPolarity = kFLEXIO_PinActiveHigh; - config->rxPinPolarity = kFLEXIO_PinActiveHigh; - config->bclkPinPolarity = kFLEXIO_PinActiveHigh; - config->fsPinPolarity = kFLEXIO_PinActiveLow; - config->txTimerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - config->rxTimerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; -} - -/*! - * brief De-initializes the FlexIO I2S. - * - * Calling this API resets the FlexIO I2S shifter and timer config. After calling this API, - * call the FLEXO_I2S_Init to use the FlexIO I2S module. - * - * param base FlexIO I2S base pointer - */ -void FLEXIO_I2S_Deinit(FLEXIO_I2S_Type *base) -{ - base->flexioBase->SHIFTCFG[base->txShifterIndex] = 0; - base->flexioBase->SHIFTCTL[base->txShifterIndex] = 0; - base->flexioBase->SHIFTCFG[base->rxShifterIndex] = 0; - base->flexioBase->SHIFTCTL[base->rxShifterIndex] = 0; - base->flexioBase->TIMCFG[base->fsTimerIndex] = 0; - base->flexioBase->TIMCMP[base->fsTimerIndex] = 0; - base->flexioBase->TIMCTL[base->fsTimerIndex] = 0; - base->flexioBase->TIMCFG[base->bclkTimerIndex] = 0; - base->flexioBase->TIMCMP[base->bclkTimerIndex] = 0; - base->flexioBase->TIMCTL[base->bclkTimerIndex] = 0; -} - -/*! - * brief Enables the FlexIO I2S interrupt. - * - * This function enables the FlexIO UART interrupt. - * - * param base Pointer to FLEXIO_I2S_Type structure - * param mask interrupt source - */ -void FLEXIO_I2S_EnableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) != 0UL) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->txShifterIndex); - } - if ((mask & (uint32_t)kFLEXIO_I2S_RxDataRegFullInterruptEnable) != 0UL) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->rxShifterIndex); - } -} - -/*! - * brief Gets the FlexIO I2S status flags. - * - * param base Pointer to FLEXIO_I2S_Type structure - * return Status flag, which are ORed by the enumerators in the _flexio_i2s_status_flags. - */ -uint32_t FLEXIO_I2S_GetStatusFlags(FLEXIO_I2S_Type *base) -{ - uint32_t status = 0; - status = ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->txShifterIndex)) >> base->txShifterIndex); - status |= - (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->rxShifterIndex)) >> (base->rxShifterIndex)) - << 1U); - return status; -} - -/*! - * brief Disables the FlexIO I2S interrupt. - * - * This function enables the FlexIO UART interrupt. - * - * param base pointer to FLEXIO_I2S_Type structure - * param mask interrupt source - */ -void FLEXIO_I2S_DisableInterrupts(FLEXIO_I2S_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyInterruptEnable) != 0UL) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->txShifterIndex); - } - if ((mask & (uint32_t)kFLEXIO_I2S_RxDataRegFullInterruptEnable) != 0UL) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->rxShifterIndex); - } -} - -/*! - * brief Configures the FlexIO I2S audio format in master mode. - * - * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data - * format to be transferred. - * - * param base Pointer to FLEXIO_I2S_Type structure - * param format Pointer to FlexIO I2S audio data format structure. - * param srcClock_Hz I2S master clock source frequency in Hz. - */ -void FLEXIO_I2S_MasterSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format, uint32_t srcClock_Hz) -{ - uint32_t timDiv = srcClock_Hz / (format->sampleRate_Hz * format->bitWidth * 2U); - uint32_t bclkDiv = 0; - - /* Shall keep bclk and fs div an integer */ - if ((timDiv % 2UL) != 0UL) - { - timDiv += 1U; - } - /* Set Frame sync timer cmp */ - base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * timDiv - 1U); - - /* Set bit clock timer cmp */ - bclkDiv = ((timDiv / 2U - 1U) | ((format->bitWidth * 2UL - 1UL) << 8U)); - base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(bclkDiv); -} - -/*! - * brief Configures the FlexIO I2S audio format in slave mode. - * - * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data - * format to be transferred. - * - * param base Pointer to FLEXIO_I2S_Type structure - * param format Pointer to FlexIO I2S audio data format structure. - */ -void FLEXIO_I2S_SlaveSetFormat(FLEXIO_I2S_Type *base, flexio_i2s_format_t *format) -{ - /* Set Frame sync timer cmp */ - base->flexioBase->TIMCMP[base->fsTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 4UL - 3UL); - - /* Set bit clock timer cmp */ - base->flexioBase->TIMCMP[base->bclkTimerIndex] = FLEXIO_TIMCMP_CMP(format->bitWidth * 2UL - 1UL); -} - -/*! - * brief Sends data using a blocking method. - * - * note This function blocks via polling until data is ready to be sent. - * - * param base FlexIO I2S base pointer. - * param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * param txData Pointer to the data to be written. - * param size Bytes to be written. - * retval kStatus_Success Successfully write data. - * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags. - */ -status_t FLEXIO_I2S_WriteBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *txData, size_t size) -{ - uint32_t i = 0; - uint8_t bytesPerWord = bitWidth / 8U; -#if I2S_RETRY_TIMES - uint32_t waitTimes = I2S_RETRY_TIMES; -#endif - - for (i = 0; i < size / bytesPerWord; i++) - { - /* Wait until it can write data */ -#if I2S_RETRY_TIMES - waitTimes = I2S_RETRY_TIMES; - while (((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyFlag) == 0UL) && - (--waitTimes != 0U)) - { - } - if (waitTimes == 0U) - { - return kStatus_FLEXIO_I2S_Timeout; - } -#else - while ((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyFlag) == 0UL) - { - } -#endif - - FLEXIO_I2S_WriteNonBlocking(base, bitWidth, txData, bytesPerWord); - txData = (uint8_t *)((uint32_t)txData + bytesPerWord); - } - - /* Wait until the last data is sent */ -#if I2S_RETRY_TIMES - waitTimes = I2S_RETRY_TIMES; - while (((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyFlag) == 0UL) && (--waitTimes != 0U)) - { - } - if (waitTimes == 0U) - { - return kStatus_FLEXIO_I2S_Timeout; - } -#else - while ((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyFlag) == 0UL) - { - } -#endif - - return kStatus_Success; -} - -/*! - * brief Receives a piece of data using a blocking method. - * - * note This function blocks via polling until data is ready to be sent. - * - * param base FlexIO I2S base pointer - * param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * param rxData Pointer to the data to be read. - * param size Bytes to be read. - * retval kStatus_Success Successfully read data. - * retval kStatus_FLEXIO_I2C_Timeout Timeout polling status flags. - */ -status_t FLEXIO_I2S_ReadBlocking(FLEXIO_I2S_Type *base, uint8_t bitWidth, uint8_t *rxData, size_t size) -{ - uint32_t i = 0; - uint8_t bytesPerWord = bitWidth / 8U; -#if I2S_RETRY_TIMES - uint32_t waitTimes = I2S_RETRY_TIMES; -#endif - - for (i = 0; i < size / bytesPerWord; i++) - { - /* Wait until data is received */ -#if I2S_RETRY_TIMES - waitTimes = I2S_RETRY_TIMES; - while ((!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->rxShifterIndex)) != 0UL)) && - (--waitTimes != 0U)) - { - } - if (waitTimes == 0U) - { - return kStatus_FLEXIO_I2S_Timeout; - } -#else - while (!((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->rxShifterIndex)) != 0UL)) - { - } -#endif - - FLEXIO_I2S_ReadNonBlocking(base, bitWidth, rxData, bytesPerWord); - rxData = (uint8_t *)((uint32_t)rxData + bytesPerWord); - } - return kStatus_Success; -} - -/*! - * brief Initializes the FlexIO I2S handle. - * - * This function initializes the FlexIO I2S handle which can be used for other - * FlexIO I2S transactional APIs. Call this API once to get the - * initialized handle. - * - * param base Pointer to FLEXIO_I2S_Type structure - * param handle Pointer to flexio_i2s_handle_t structure to store the transfer state. - * param callback FlexIO I2S callback function, which is called while finished a block. - * param userData User parameter for the FlexIO I2S callback. - */ -void FLEXIO_I2S_TransferTxCreateHandle(FLEXIO_I2S_Type *base, - flexio_i2s_handle_t *handle, - flexio_i2s_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Store callback and user data. */ - handle->callback = callback; - handle->userData = userData; - - /* Save the context in global variables to support the double weak mechanism. */ - (void)FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferTxHandleIRQ); - - /* Set the TX/RX state. */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_I2S_GetInstance(base)]); -} - -/*! - * brief Initializes the FlexIO I2S receive handle. - * - * This function initializes the FlexIO I2S handle which can be used for other - * FlexIO I2S transactional APIs. Call this API once to get the - * initialized handle. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure to store the transfer state. - * param callback FlexIO I2S callback function, which is called while finished a block. - * param userData User parameter for the FlexIO I2S callback. - */ -void FLEXIO_I2S_TransferRxCreateHandle(FLEXIO_I2S_Type *base, - flexio_i2s_handle_t *handle, - flexio_i2s_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Store callback and user data. */ - handle->callback = callback; - handle->userData = userData; - - /* Save the context in global variables to support the double weak mechanism. */ - (void)FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_I2S_TransferRxHandleIRQ); - - /* Set the TX/RX state. */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_I2S_GetInstance(base)]); -} - -/*! - * brief Configures the FlexIO I2S audio format. - * - * Audio format can be changed at run-time of FlexIO I2S. This function configures the sample rate and audio data - * format to be transferred. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle FlexIO I2S handle pointer. - * param format Pointer to audio data format structure. - * param srcClock_Hz FlexIO I2S bit clock source frequency in Hz. This parameter should be 0 while in slave mode. - */ -void FLEXIO_I2S_TransferSetFormat(FLEXIO_I2S_Type *base, - flexio_i2s_handle_t *handle, - flexio_i2s_format_t *format, - uint32_t srcClock_Hz) -{ - assert((handle != NULL) && (format != NULL)); - - /* Set the bitWidth to handle */ - handle->bitWidth = format->bitWidth; - - /* Set sample rate */ - if (srcClock_Hz != 0UL) - { - /* It is master */ - FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); - } - else - { - FLEXIO_I2S_SlaveSetFormat(base, format); - } -} - -/*! - * brief Performs an interrupt non-blocking send transfer on FlexIO I2S. - * - * note The API returns immediately after transfer initiates. - * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status and check whether - * the transfer is finished. If the return status is 0, the transfer is finished. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - * param xfer Pointer to flexio_i2s_transfer_t structure - * retval kStatus_Success Successfully start the data transmission. - * retval kStatus_FLEXIO_I2S_TxBusy Previous transmission still not finished, data not all written to TX register yet. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t FLEXIO_I2S_TransferSendNonBlocking(FLEXIO_I2S_Type *base, - flexio_i2s_handle_t *handle, - flexio_i2s_transfer_t *xfer) -{ - assert(handle != NULL); - - /* Check if the queue is full */ - if (handle->queue[handle->queueUser].data != NULL) - { - return kStatus_FLEXIO_I2S_QueueFull; - } - if ((xfer->dataSize == 0U) || (xfer->data == NULL)) - { - return kStatus_InvalidArgument; - } - - /* Add into queue */ - handle->queue[handle->queueUser].data = xfer->data; - handle->queue[handle->queueUser].dataSize = xfer->dataSize; - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - - /* Set the state to busy */ - handle->state = (uint32_t)kFLEXIO_I2S_Busy; - - FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); - - /* Enable Tx transfer */ - FLEXIO_I2S_Enable(base, true); - - return kStatus_Success; -} - -/*! - * brief Performs an interrupt non-blocking receive transfer on FlexIO I2S. - * - * note The API returns immediately after transfer initiates. - * Call FLEXIO_I2S_GetRemainingBytes to poll the transfer status to check whether - * the transfer is finished. If the return status is 0, the transfer is finished. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - * param xfer Pointer to flexio_i2s_transfer_t structure - * retval kStatus_Success Successfully start the data receive. - * retval kStatus_FLEXIO_I2S_RxBusy Previous receive still not finished. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t FLEXIO_I2S_TransferReceiveNonBlocking(FLEXIO_I2S_Type *base, - flexio_i2s_handle_t *handle, - flexio_i2s_transfer_t *xfer) -{ - assert(handle != NULL); - - /* Check if the queue is full */ - if (handle->queue[handle->queueUser].data != NULL) - { - return kStatus_FLEXIO_I2S_QueueFull; - } - - if ((xfer->dataSize == 0U) || (xfer->data == NULL)) - { - return kStatus_InvalidArgument; - } - - /* Add into queue */ - handle->queue[handle->queueUser].data = xfer->data; - handle->queue[handle->queueUser].dataSize = xfer->dataSize; - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - - /* Set state to busy */ - handle->state = (uint32_t)kFLEXIO_I2S_Busy; - - /* Enable interrupt */ - FLEXIO_I2S_EnableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); - - /* Enable Rx transfer */ - FLEXIO_I2S_Enable(base, true); - - return kStatus_Success; -} - -/*! - * brief Aborts the current send. - * - * note This API can be called at any time when interrupt non-blocking transfer initiates - * to abort the transfer in a early time. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - */ -void FLEXIO_I2S_TransferAbortSend(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) -{ - assert(handle != NULL); - - /* Stop Tx transfer and disable interrupt */ - FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_TxDataRegEmptyInterruptEnable); - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - /* Clear the queue */ - (void)memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Aborts the current receive. - * - * note This API can be called at any time when interrupt non-blocking transfer initiates - * to abort the transfer in a early time. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - */ -void FLEXIO_I2S_TransferAbortReceive(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle) -{ - assert(handle != NULL); - - /* Stop rx transfer and disable interrupt */ - FLEXIO_I2S_DisableInterrupts(base, kFLEXIO_I2S_RxDataRegFullInterruptEnable); - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - /* Clear the queue */ - (void)memset(handle->queue, 0, sizeof(flexio_i2s_transfer_t) * FLEXIO_I2S_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Gets the remaining bytes to be sent. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - * param count Bytes sent. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t FLEXIO_I2S_TransferGetSendCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint8_t queueDriver = handle->queueDriver; - - if (handle->state != (uint32_t)kFLEXIO_I2S_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriver] - handle->queue[queueDriver].dataSize); - } - - return status; -} - -/*! - * brief Gets the remaining bytes to be received. - * - * param base Pointer to FLEXIO_I2S_Type structure. - * param handle Pointer to flexio_i2s_handle_t structure which stores the transfer state - * return count Bytes received. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t FLEXIO_I2S_TransferGetReceiveCount(FLEXIO_I2S_Type *base, flexio_i2s_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint8_t queueDriver = handle->queueDriver; - - if (handle->state != (uint32_t)kFLEXIO_I2S_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriver] - handle->queue[queueDriver].dataSize); - } - - return status; -} - -/*! - * brief Tx interrupt handler. - * - * param i2sBase Pointer to FLEXIO_I2S_Type structure. - * param i2sHandle Pointer to flexio_i2s_handle_t structure - */ -void FLEXIO_I2S_TransferTxHandleIRQ(void *i2sBase, void *i2sHandle) -{ - assert(i2sHandle != NULL); - - flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; - FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; - uint8_t *buffer = handle->queue[handle->queueDriver].data; - uint8_t dataSize = handle->bitWidth / 8U; - - /* Handle error */ - if ((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->txShifterIndex)) != 0UL) - { - FLEXIO_ClearShifterErrorFlags(base->flexioBase, (1UL << base->txShifterIndex)); - } - /* Handle transfer */ - if (((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_TxDataRegEmptyFlag) != 0UL) && - (handle->queue[handle->queueDriver].data != NULL)) - { - FLEXIO_I2S_WriteNonBlocking(base, handle->bitWidth, buffer, dataSize); - - /* Update internal counter */ - handle->queue[handle->queueDriver].dataSize -= dataSize; - handle->queue[handle->queueDriver].data = - (uint8_t *)((uint32_t)handle->queue[handle->queueDriver].data + dataSize); - } - - /* If finished a block, call the callback function */ - if ((handle->queue[handle->queueDriver].dataSize == 0U) && (handle->queue[handle->queueDriver].data != NULL)) - { - (void)memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_Success, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->queue[handle->queueDriver].data == NULL) - { - FLEXIO_I2S_TransferAbortSend(base, handle); - } -} - -/*! - * brief Rx interrupt handler. - * - * param i2sBase Pointer to FLEXIO_I2S_Type structure. - * param i2sHandle Pointer to flexio_i2s_handle_t structure. - */ -void FLEXIO_I2S_TransferRxHandleIRQ(void *i2sBase, void *i2sHandle) -{ - assert(i2sHandle != NULL); - - flexio_i2s_handle_t *handle = (flexio_i2s_handle_t *)i2sHandle; - FLEXIO_I2S_Type *base = (FLEXIO_I2S_Type *)i2sBase; - uint8_t *buffer = handle->queue[handle->queueDriver].data; - uint8_t dataSize = handle->bitWidth / 8U; - - /* Handle transfer */ - if (((FLEXIO_I2S_GetStatusFlags(base) & (uint32_t)kFLEXIO_I2S_RxDataRegFullFlag) != 0UL) && - (handle->queue[handle->queueDriver].data != NULL)) - { - FLEXIO_I2S_ReadNonBlocking(base, handle->bitWidth, buffer, dataSize); - - /* Update internal state */ - handle->queue[handle->queueDriver].dataSize -= dataSize; - handle->queue[handle->queueDriver].data = - (uint8_t *)((uint32_t)handle->queue[handle->queueDriver].data + dataSize); - } - - /* If finished a block, call the callback function */ - if ((handle->queue[handle->queueDriver].dataSize == 0U) && (handle->queue[handle->queueDriver].data != NULL)) - { - (void)memset(&handle->queue[handle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_Success, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->queue[handle->queueDriver].data == NULL) - { - FLEXIO_I2S_TransferAbortReceive(base, handle); - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s_edma.c deleted file mode 100644 index 21e3a6ff51..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_i2s_edma.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_i2s_edma.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_i2s_edma" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ -/* Used for 32byte aligned */ -#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)(address) + 32U) & ~0x1FU) - -/*<! Structure definition for flexio_i2s_edma_private_handle_t. The structure is private. */ -typedef struct _flexio_i2s_edma_private_handle -{ - FLEXIO_I2S_Type *base; - flexio_i2s_edma_handle_t *handle; -} flexio_i2s_edma_private_handle_t; - -/*!@brief _flexio_i2s_edma_transfer_state */ -enum -{ - kFLEXIO_I2S_Busy = 0x0U, /*!< FLEXIO I2S is busy */ - kFLEXIO_I2S_Idle, /*!< Transfer is done. */ -}; - -/*<! Private handle only used for internally. */ -static flexio_i2s_edma_private_handle_t s_edmaPrivateHandle[2]; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief FLEXIO I2S EDMA callback for send. - * - * @param handle pointer to flexio_i2s_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void FLEXIO_I2S_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/*! - * @brief FLEXIO I2S EDMA callback for receive. - * - * @param handle pointer to flexio_i2s_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void FLEXIO_I2S_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ -static void FLEXIO_I2S_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - flexio_i2s_edma_private_handle_t *privHandle = (flexio_i2s_edma_private_handle_t *)userData; - flexio_i2s_edma_handle_t *flexio_i2sHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); - flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - if (flexio_i2sHandle->callback != NULL) - { - (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) - { - FLEXIO_I2S_TransferAbortSendEDMA(privHandle->base, flexio_i2sHandle); - } -} - -static void FLEXIO_I2S_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - flexio_i2s_edma_private_handle_t *privHandle = (flexio_i2s_edma_private_handle_t *)userData; - flexio_i2s_edma_handle_t *flexio_i2sHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver], 0, sizeof(flexio_i2s_transfer_t)); - flexio_i2sHandle->queueDriver = (flexio_i2sHandle->queueDriver + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - if (flexio_i2sHandle->callback != NULL) - { - (flexio_i2sHandle->callback)(privHandle->base, flexio_i2sHandle, kStatus_Success, flexio_i2sHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (flexio_i2sHandle->queue[flexio_i2sHandle->queueDriver].data == NULL) - { - FLEXIO_I2S_TransferAbortReceiveEDMA(privHandle->base, flexio_i2sHandle); - } -} - -/*! - * brief Initializes the FlexIO I2S eDMA handle. - * - * This function initializes the FlexIO I2S master DMA handle which can be used for other FlexIO I2S master - * transactional APIs. - * Usually, for a specified FlexIO I2S instance, call this API once to get the initialized handle. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S eDMA handle pointer. - * param callback FlexIO I2S eDMA callback function called while finished a block. - * param userData User parameter for callback. - * param dmaHandle eDMA handle for FlexIO I2S. This handle is a static value allocated by users. - */ -void FLEXIO_I2S_TransferTxCreateHandleEDMA(FLEXIO_I2S_Type *base, - flexio_i2s_edma_handle_t *handle, - flexio_i2s_edma_callback_t callback, - void *userData, - edma_handle_t *dmaHandle) -{ - assert((handle != NULL) && (dmaHandle != NULL)); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set flexio_i2s base to handle */ - handle->dmaHandle = dmaHandle; - handle->callback = callback; - handle->userData = userData; - - /* Set FLEXIO I2S state to idle */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - s_edmaPrivateHandle[0].base = base; - s_edmaPrivateHandle[0].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), FLEXIO_I2S_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel */ - EDMA_SetCallback(dmaHandle, FLEXIO_I2S_TxEDMACallback, &s_edmaPrivateHandle[0]); -} - -/*! - * brief Initializes the FlexIO I2S Rx eDMA handle. - * - * This function initializes the FlexIO I2S slave DMA handle which can be used for other FlexIO I2S master transactional - * APIs. - * Usually, for a specified FlexIO I2S instance, call this API once to get the initialized handle. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S eDMA handle pointer. - * param callback FlexIO I2S eDMA callback function called while finished a block. - * param userData User parameter for callback. - * param dmaHandle eDMA handle for FlexIO I2S. This handle is a static value allocated by users. - */ -void FLEXIO_I2S_TransferRxCreateHandleEDMA(FLEXIO_I2S_Type *base, - flexio_i2s_edma_handle_t *handle, - flexio_i2s_edma_callback_t callback, - void *userData, - edma_handle_t *dmaHandle) -{ - assert((handle != NULL) && (dmaHandle != NULL)); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set flexio_i2s base to handle */ - handle->dmaHandle = dmaHandle; - handle->callback = callback; - handle->userData = userData; - - /* Set FLEXIO I2S state to idle */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; - - s_edmaPrivateHandle[1].base = base; - s_edmaPrivateHandle[1].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(dmaHandle, STCD_ADDR(handle->tcd), FLEXIO_I2S_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel */ - EDMA_SetCallback(dmaHandle, FLEXIO_I2S_RxEDMACallback, &s_edmaPrivateHandle[1]); -} - -/*! - * brief Configures the FlexIO I2S Tx audio format. - * - * Audio format can be changed in run-time of FlexIO I2S. This function configures the sample rate and audio data - * format to be transferred. This function also sets the eDMA parameter according to format. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S eDMA handle pointer - * param format Pointer to FlexIO I2S audio data format structure. - * param srcClock_Hz FlexIO I2S clock source frequency in Hz, it should be 0 while in slave mode. - * retval kStatus_Success Audio format set successfully. - * retval kStatus_InvalidArgument The input arguments is invalid. - */ -void FLEXIO_I2S_TransferSetFormatEDMA(FLEXIO_I2S_Type *base, - flexio_i2s_edma_handle_t *handle, - flexio_i2s_format_t *format, - uint32_t srcClock_Hz) -{ - assert((handle != NULL) && (format != NULL)); - - /* Configure the audio format to FLEXIO I2S registers */ - if (srcClock_Hz != 0UL) - { - /* It is master */ - FLEXIO_I2S_MasterSetFormat(base, format, srcClock_Hz); - } - else - { - FLEXIO_I2S_SlaveSetFormat(base, format); - } - - /* Get the transfer size from format, this should be used in EDMA configuration */ - handle->bytesPerFrame = format->bitWidth / 8U; -} - -/*! - * brief Performs a non-blocking FlexIO I2S transfer using DMA. - * - * note This interface returned immediately after transfer initiates. Users should call - * FLEXIO_I2S_GetTransferStatus to poll the transfer status and check whether the FlexIO I2S transfer is finished. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - * param xfer Pointer to DMA transfer structure. - * retval kStatus_Success Start a FlexIO I2S eDMA send successfully. - * retval kStatus_InvalidArgument The input arguments is invalid. - * retval kStatus_TxBusy FlexIO I2S is busy sending data. - */ -status_t FLEXIO_I2S_TransferSendEDMA(FLEXIO_I2S_Type *base, - flexio_i2s_edma_handle_t *handle, - flexio_i2s_transfer_t *xfer) -{ - assert((handle != NULL) && (xfer != NULL)); - - edma_transfer_config_t config = {0}; - uint32_t destAddr = FLEXIO_I2S_TxGetDataRegisterAddress(base) + (4UL - handle->bytesPerFrame); - - /* Check if input parameter invalid */ - if ((xfer->data == NULL) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - if (handle->queue[handle->queueUser].data != NULL) - { - return kStatus_FLEXIO_I2S_QueueFull; - } - - /* Change the state of handle */ - handle->state = (uint32_t)kFLEXIO_I2S_Busy; - - /* Update the queue state */ - handle->queue[handle->queueUser].data = xfer->data; - handle->queue[handle->queueUser].dataSize = xfer->dataSize; - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (uint32_t *)destAddr, handle->bytesPerFrame, - handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO I2S handle */ - handle->nbytes = handle->bytesPerFrame; - - (void)EDMA_SubmitTransfer(handle->dmaHandle, &config); - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaHandle); - - /* Enable DMA enable bit */ - FLEXIO_I2S_TxEnableDMA(base, true); - - /* Enable FLEXIO I2S Tx clock */ - FLEXIO_I2S_Enable(base, true); - - return kStatus_Success; -} - -/*! - * brief Performs a non-blocking FlexIO I2S receive using eDMA. - * - * note This interface returned immediately after transfer initiates. Users should call - * FLEXIO_I2S_GetReceiveRemainingBytes to poll the transfer status and check whether the FlexIO I2S transfer is - * finished. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - * param xfer Pointer to DMA transfer structure. - * retval kStatus_Success Start a FlexIO I2S eDMA receive successfully. - * retval kStatus_InvalidArgument The input arguments is invalid. - * retval kStatus_RxBusy FlexIO I2S is busy receiving data. - */ -status_t FLEXIO_I2S_TransferReceiveEDMA(FLEXIO_I2S_Type *base, - flexio_i2s_edma_handle_t *handle, - flexio_i2s_transfer_t *xfer) -{ - assert((handle != NULL) && (xfer != NULL)); - - edma_transfer_config_t config = {0}; - uint32_t srcAddr = FLEXIO_I2S_RxGetDataRegisterAddress(base); - - /* Check if input parameter invalid */ - if ((xfer->data == NULL) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - if (handle->queue[handle->queueUser].data != NULL) - { - return kStatus_FLEXIO_I2S_QueueFull; - } - - /* Change the state of handle */ - handle->state = (uint32_t)kFLEXIO_I2S_Busy; - - /* Update queue state */ - handle->queue[handle->queueUser].data = xfer->data; - handle->queue[handle->queueUser].dataSize = xfer->dataSize; - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % FLEXIO_I2S_XFER_QUEUE_SIZE; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, (uint32_t *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, - handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO I2S handle */ - handle->nbytes = handle->bytesPerFrame; - - (void)EDMA_SubmitTransfer(handle->dmaHandle, &config); - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaHandle); - - /* Enable DMA enable bit */ - FLEXIO_I2S_RxEnableDMA(base, true); - - /* Enable FLEXIO I2S Rx clock */ - FLEXIO_I2S_Enable(base, true); - - return kStatus_Success; -} - -/*! - * brief Aborts a FlexIO I2S transfer using eDMA. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - */ -void FLEXIO_I2S_TransferAbortSendEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaHandle); - - /* Disable DMA enable bit */ - FLEXIO_I2S_TxEnableDMA(base, false); - - /* Set the handle state */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; -} - -/*! - * brief Aborts a FlexIO I2S receive using eDMA. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - */ -void FLEXIO_I2S_TransferAbortReceiveEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaHandle); - - /* Disable DMA enable bit */ - FLEXIO_I2S_RxEnableDMA(base, false); - - /* Set the handle state */ - handle->state = (uint32_t)kFLEXIO_I2S_Idle; -} - -/*! - * brief Gets the remaining bytes to be sent. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - * param count Bytes sent. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t FLEXIO_I2S_TransferGetSendCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kFLEXIO_I2S_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel); - } - - return status; -} - -/*! - * brief Get the remaining bytes to be received. - * - * param base FlexIO I2S peripheral base address. - * param handle FlexIO I2S DMA handle pointer. - * param count Bytes received. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t FLEXIO_I2S_TransferGetReceiveCountEDMA(FLEXIO_I2S_Type *base, flexio_i2s_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kFLEXIO_I2S_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel); - } - - return status; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd.c deleted file mode 100644 index f9f890a627..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd.c +++ /dev/null @@ -1,1293 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_mculcd.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_mculcd" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ - -enum _mculcd_transfer_state -{ - kFLEXIO_MCULCD_StateIdle, /*!< No transfer in progress. */ - kFLEXIO_MCULCD_StateReadArray, /*!< Reading array in progress. */ - kFLEXIO_MCULCD_StateWriteArray, /*!< Writing array in progress. */ - kFLEXIO_MCULCD_StateWriteSameValue, /*!< Writing the same value in progress. */ -}; - -/* The TIMCFG[0:7] is used for baud rate divider in dual 8-bit counters baud/bit mode. */ -#define FLEXIO_BAUDRATE_DIV_MASK 0xFFU - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, configures the - * FlexIO MCULCD hardware, and configures the FlexIO MCULCD with FlexIO MCULCD - * configuration. - * The configuration structure can be filled by the user, or be set with default - * values - * by the ref FLEXIO_MCULCD_GetDefaultConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param config Pointer to the flexio_mculcd_config_t structure. - * param srcClock_Hz FlexIO source clock in Hz. - * retval kStatus_Success Initialization success. - * retval kStatus_InvalidArgument Initialization failed because of invalid - * argument. - */ -status_t FLEXIO_MCULCD_Init(FLEXIO_MCULCD_Type *base, flexio_mculcd_config_t *config, uint32_t srcClock_Hz) -{ - assert(NULL != config); - - flexio_config_t flexioConfig = {config->enable, config->enableInDoze, config->enableInDebug, - config->enableFastAccess}; - - FLEXIO_Init(base->flexioBase, &flexioConfig); - - if (kStatus_Success != FLEXIO_MCULCD_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz)) - { - return kStatus_Success; - } - - base->setCSPin(true); - base->setRSPin(true); - - return kStatus_Success; -} - -/*! - * brief Resets the FLEXIO_MCULCD timer and shifter configuration. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - */ -void FLEXIO_MCULCD_Deinit(FLEXIO_MCULCD_Type *base) -{ - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); - FLEXIO_MCULCD_ClearSingleBeatReadConfig(base); -} - -/*! - * brief Gets the default configuration to configure the FlexIO MCULCD. - * - * The default configuration value is: - * code - * config->enable = true; - * config->enableInDoze = false; - * config->enableInDebug = true; - * config->enableFastAccess = true; - * config->baudRate_Bps = 96000000U; - * endcode - * param Config Pointer to the flexio_mculcd_config_t structure. - */ -void FLEXIO_MCULCD_GetDefaultConfig(flexio_mculcd_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enable = true; - config->enableInDoze = false; - config->enableInDebug = true; - config->enableFastAccess = true; - config->baudRate_Bps = 96000000U; -} - -/*! - * brief Set desired baud rate. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param baudRate_Bps Desired baud rate. - * param srcClock_Hz FLEXIO clock frequency in Hz. - * retval kStatus_Success Set successfully. - * retval kStatus_InvalidArgument Could not set the baud rate. - */ -status_t FLEXIO_MCULCD_SetBaudRate(FLEXIO_MCULCD_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) -{ - uint32_t baudRateDiv; - uint32_t baudRatePerDataLine; - uint32_t timerCompare; - status_t status; - - baudRatePerDataLine = baudRate_Bps / FLEXIO_MCULCD_DATA_BUS_WIDTH; - - baudRateDiv = (srcClock_Hz + baudRatePerDataLine) / (baudRatePerDataLine * 2U); - - if ((0U == baudRateDiv) || (baudRateDiv > (FLEXIO_BAUDRATE_DIV_MASK + 1U))) - { - status = kStatus_InvalidArgument; - } - else - { - baudRateDiv--; - - timerCompare = base->flexioBase->TIMCMP[base->timerIndex]; - - timerCompare = (timerCompare & ~FLEXIO_BAUDRATE_DIV_MASK) | baudRateDiv; - - base->flexioBase->TIMCMP[base->timerIndex] = timerCompare; - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Gets FlexIO MCULCD status flags. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * return status flag; OR'ed value or the ref _flexio_mculcd_status_flags. - * - * note Don't use this function with DMA APIs. - */ -uint32_t FLEXIO_MCULCD_GetStatusFlags(FLEXIO_MCULCD_Type *base) -{ - uint32_t ret = 0U; - uint32_t flags; - - /* Get shifter status. */ - flags = FLEXIO_GetShifterStatusFlags(base->flexioBase); - - if (0U != (flags & (1UL << base->rxShifterEndIndex))) - { - ret |= (uint32_t)kFLEXIO_MCULCD_RxFullFlag; - } - - if (0U != (flags & (1UL << base->txShifterStartIndex))) - { - ret |= (uint32_t)kFLEXIO_MCULCD_TxEmptyFlag; - } - - return ret; -} - -/*! - * brief Clears FlexIO MCULCD status flags. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param mask Status to clear, it is the OR'ed value of ref - * _flexio_mculcd_status_flags. - * - * note Don't use this function with DMA APIs. - */ -void FLEXIO_MCULCD_ClearStatusFlags(FLEXIO_MCULCD_Type *base, uint32_t mask) -{ - uint32_t flags = 0U; - - /* Clear the shifter flags. */ - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_RxFullFlag)) - { - flags |= (1UL << base->rxShifterEndIndex); - } - - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_TxEmptyFlag)) - { - flags |= (1UL << base->txShifterStartIndex); - } - - FLEXIO_ClearShifterStatusFlags(base->flexioBase, flags); -} - -/*! - * brief Enables the FlexIO MCULCD interrupt. - * - * This function enables the FlexIO MCULCD interrupt. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param mask Interrupts to enable, it is the OR'ed value of ref - * _flexio_mculcd_interrupt_enable. - */ -void FLEXIO_MCULCD_EnableInterrupts(FLEXIO_MCULCD_Type *base, uint32_t mask) -{ - uint32_t interrupts = 0U; - - /* Enable shifter interrupts. */ - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_RxFullFlag)) - { - interrupts |= (1UL << base->rxShifterEndIndex); - } - - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_TxEmptyFlag)) - { - interrupts |= (1UL << base->txShifterStartIndex); - } - - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, interrupts); -} - -/*! - * brief Disables the FlexIO MCULCD interrupt. - * - * This function disables the FlexIO MCULCD interrupt. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param mask Interrupts to disable, it is the OR'ed value of ref - * _flexio_mculcd_interrupt_enable. - */ -void FLEXIO_MCULCD_DisableInterrupts(FLEXIO_MCULCD_Type *base, uint32_t mask) -{ - uint32_t interrupts = 0U; - - /* Disable shifter interrupts. */ - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_RxFullFlag)) - { - interrupts |= (1UL << base->rxShifterEndIndex); - } - - if (0U != (mask & (uint32_t)kFLEXIO_MCULCD_TxEmptyFlag)) - { - interrupts |= (1UL << base->txShifterStartIndex); - } - - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, interrupts); -} - -/*! - * brief Read data from the FLEXIO MCULCD RX shifter buffer. - * - * Read data from the RX shift buffer directly, it does no check whether the - * buffer is empty or not. - * - * If the data bus width is 8-bit: - * code - * uint8_t value; - * value = (uint8_t)FLEXIO_MCULCD_ReadData(base); - * endcode - * - * If the data bus width is 16-bit: - * code - * uint16_t value; - * value = (uint16_t)FLEXIO_MCULCD_ReadData(base); - * endcode - * - * note This function returns the RX shifter buffer value (32-bit) directly. - * The return value should be converted according to data bus width. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * return The data read out. - * - * note Don't use this function with DMA APIs. - */ -uint32_t FLEXIO_MCULCD_ReadData(FLEXIO_MCULCD_Type *base) -{ -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - return base->flexioBase->SHIFTBUFBYS[base->rxShifterEndIndex]; -#else - return base->flexioBase->SHIFTBUFHWS[base->rxShifterEndIndex]; -#endif -} - -/*! - * brief Configures the FLEXIO MCULCD to multiple beats write mode. - * - * At the begining multiple beats write operation, the FLEXIO MCULCD is configured to - * multiple beats write mode using this function. After write operation, the configuration - * is cleared by ref FLEXIO_MCULCD_ClearSingleBeatWriteConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_SetSingleBeatWriteConfig(FLEXIO_MCULCD_Type *base) -{ - /* - * This function will be called at the beginning of every data writing. For - * performance consideration, it access the FlexIO registers directly, but not - * call FlexIO driver APIs. - */ - - uint32_t timerCompare; - - /* Enable the TX Shifter output. */ - base->flexioBase->SHIFTCFG[base->txShifterStartIndex] = - FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U) | - FLEXIO_SHIFTCFG_INSRC(kFLEXIO_ShifterInputFromNextShifterOutput); - - base->flexioBase->SHIFTCTL[base->txShifterStartIndex] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnPositive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutput) | FLEXIO_SHIFTCTL_PINSEL(base->dataPinStartIndex) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit); - - timerCompare = base->flexioBase->TIMCMP[base->timerIndex] & 0xFFU; - - /* - * TIMCMP[15:8] = (number of beats x 2) - 1. Because the number of beat is 1, - * so the TIMCMP[15:8] is 1. - */ - base->flexioBase->TIMCMP[base->timerIndex] = (1UL << 8U) | timerCompare; - - /* Use TX shifter flag as the inverted timer trigger. Timer output to WR/EN pin. */ - base->flexioBase->TIMCFG[base->timerIndex] = - FLEXIO_TIMCFG_TIMOUT(kFLEXIO_TimerOutputOneNotAffectedByReset) | - FLEXIO_TIMCFG_TIMDEC(kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput) | - FLEXIO_TIMCFG_TIMRST(kFLEXIO_TimerResetNever) | FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare) | - FLEXIO_TIMCFG_TIMENA(kFLEXIO_TimerEnableOnTriggerHigh) | FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled) | - FLEXIO_TIMCFG_TSTART(kFLEXIO_TimerStartBitDisabled); - - base->flexioBase->TIMCTL[base->timerIndex] = - FLEXIO_TIMCTL_TRGSEL(FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterStartIndex)) | - FLEXIO_TIMCTL_TRGPOL(kFLEXIO_TimerTriggerPolarityActiveLow) | - FLEXIO_TIMCTL_TRGSRC(kFLEXIO_TimerTriggerSourceInternal) | FLEXIO_TIMCTL_PINCFG(kFLEXIO_PinConfigOutput) | - FLEXIO_TIMCTL_PINSEL(base->ENWRPinIndex) | FLEXIO_TIMCTL_PINPOL(kFLEXIO_PinActiveLow) | - FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitBaudBit); -} - -/*! - * brief Clear the FLEXIO MCULCD multiple beats write mode configuration. - * - * Clear the write configuration set by ref FLEXIO_MCULCD_SetSingleBeatWriteConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_ClearSingleBeatWriteConfig(FLEXIO_MCULCD_Type *base) -{ - /* Disable the timer. */ - base->flexioBase->TIMCTL[base->timerIndex] = 0U; - base->flexioBase->TIMCFG[base->timerIndex] = 0U; - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex); - /* Stop the TX shifter. */ - base->flexioBase->SHIFTCTL[base->txShifterStartIndex] = 0U; - base->flexioBase->SHIFTCFG[base->txShifterStartIndex] = 0U; - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = (1UL << base->txShifterStartIndex); -} - -/*! - * brief Configures the FLEXIO MCULCD to multiple beats read mode. - * - * At the begining or multiple beats read operation, the FLEXIO MCULCD is configured - * to multiple beats read mode using this function. After read operation, the configuration - * is cleared by ref FLEXIO_MCULCD_ClearSingleBeatReadConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_SetSingleBeatReadConfig(FLEXIO_MCULCD_Type *base) -{ - /* - * This function will be called at the beginning of every data reading. For - * performance consideration, it access the FlexIO registers directly, but not - * call FlexIO driver APIs. - */ - - uint8_t timerPin; - uint32_t timerCompare; - flexio_pin_polarity_t timerPinPolarity; - - /* Timer output to RD pin (8080 mode), to WR/EN pin in 6800 mode. */ - if (kFLEXIO_MCULCD_8080 == base->busType) - { - timerPin = base->RDPinIndex; - timerPinPolarity = kFLEXIO_PinActiveLow; - } - else - { - timerPin = base->ENWRPinIndex; - timerPinPolarity = kFLEXIO_PinActiveHigh; - } - - /* Enable the RX Shifter input. */ - base->flexioBase->SHIFTCFG[base->rxShifterEndIndex] = FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U); - - base->flexioBase->SHIFTCTL[base->rxShifterEndIndex] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutputDisabled) | FLEXIO_SHIFTCTL_PINSEL(base->dataPinStartIndex) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeReceive); - - /* Use RX shifter flag as the inverted timer trigger. */ - base->flexioBase->TIMCFG[base->timerIndex] = - FLEXIO_TIMCFG_TIMOUT(kFLEXIO_TimerOutputOneNotAffectedByReset) | - FLEXIO_TIMCFG_TIMDEC(kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput) | - FLEXIO_TIMCFG_TIMRST(kFLEXIO_TimerResetNever) | FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare) | - FLEXIO_TIMCFG_TIMENA(kFLEXIO_TimerEnableOnTriggerHigh) | - FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable) | - FLEXIO_TIMCFG_TSTART(kFLEXIO_TimerStartBitDisabled); - - timerCompare = base->flexioBase->TIMCMP[base->timerIndex] & 0xFFU; - - /* - * TIMCMP[15:8] = (number of beats x 2) - 1. Because the number of beat is 1, - * so the TIMCMP[15:8] is 1. - */ - base->flexioBase->TIMCMP[base->timerIndex] = (1UL << 8U) | timerCompare; - - base->flexioBase->TIMCTL[base->timerIndex] |= - FLEXIO_TIMCTL_TRGSEL(FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->rxShifterEndIndex)) | - FLEXIO_TIMCTL_TRGPOL(kFLEXIO_TimerTriggerPolarityActiveLow) | - FLEXIO_TIMCTL_TRGSRC(kFLEXIO_TimerTriggerSourceInternal) | FLEXIO_TIMCTL_PINCFG(kFLEXIO_PinConfigOutput) | - FLEXIO_TIMCTL_PINSEL(timerPin) | FLEXIO_TIMCTL_PINPOL(timerPinPolarity) | - FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitBaudBit); -} - -/*! - * brief Clear the FLEXIO MCULCD multiple beats read mode configuration. - * - * Clear the read configuration set by ref FLEXIO_MCULCD_SetSingleBeatReadConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_ClearSingleBeatReadConfig(FLEXIO_MCULCD_Type *base) -{ - /* Disable the timer. */ - base->flexioBase->TIMCTL[base->timerIndex] = 0U; - base->flexioBase->TIMCFG[base->timerIndex] = 0U; - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex); - /* Stop the RX shifter. */ - base->flexioBase->SHIFTCTL[base->rxShifterEndIndex] = 0U; - base->flexioBase->SHIFTCFG[base->rxShifterEndIndex] = 0U; - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = (1UL << base->rxShifterEndIndex); -} - -/*! - * brief Configures the FLEXIO MCULCD to multiple beats write mode. - * - * At the begining multiple beats write operation, the FLEXIO MCULCD is configured to - * multiple beats write mode using this function. After write operation, the configuration - * is cleared by ref FLEXIO_MCULCD_ClearMultBeatsWriteConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_SetMultiBeatsWriteConfig(FLEXIO_MCULCD_Type *base) -{ - /* - * This function will be called at the beginning of every data writing. For - * performance consideration, it access the FlexIO registers directly, but not - * call FlexIO driver APIs. - */ - - uint32_t timerCompare; - uint8_t beats; - uint8_t i; - - /* Enable the TX Shifter output. */ - base->flexioBase->SHIFTCFG[base->txShifterStartIndex] = - FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U) | - FLEXIO_SHIFTCFG_INSRC(kFLEXIO_ShifterInputFromNextShifterOutput); - - base->flexioBase->SHIFTCTL[base->txShifterStartIndex] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnPositive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutput) | FLEXIO_SHIFTCTL_PINSEL(base->dataPinStartIndex) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit); - - for (i = base->txShifterStartIndex + 1U; i <= base->txShifterEndIndex; i++) - { - base->flexioBase->SHIFTCFG[i] = FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U) | - FLEXIO_SHIFTCFG_INSRC(kFLEXIO_ShifterInputFromNextShifterOutput); - - base->flexioBase->SHIFTCTL[i] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnPositive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutputDisabled) | FLEXIO_SHIFTCTL_PINSEL(0) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeTransmit); - } - - timerCompare = base->flexioBase->TIMCMP[base->timerIndex] & 0xFFU; - -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - beats = 4U * (base->txShifterEndIndex - base->txShifterStartIndex + 1U); -#else - beats = 2U * (base->txShifterEndIndex - base->txShifterStartIndex + 1U); -#endif - - /* - * TIMCMP[15:8] = (number of beats x 2) - 1. - */ - base->flexioBase->TIMCMP[base->timerIndex] = ((beats * 2UL - 1UL) << 8U) | timerCompare; - - /* Use TX shifter flag as the inverted timer trigger. Timer output to WR/EN pin. */ - base->flexioBase->TIMCFG[base->timerIndex] = - FLEXIO_TIMCFG_TIMOUT(kFLEXIO_TimerOutputOneNotAffectedByReset) | - FLEXIO_TIMCFG_TIMDEC(kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput) | - FLEXIO_TIMCFG_TIMRST(kFLEXIO_TimerResetNever) | FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare) | - FLEXIO_TIMCFG_TIMENA(kFLEXIO_TimerEnableOnTriggerHigh) | FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitDisabled) | - FLEXIO_TIMCFG_TSTART(kFLEXIO_TimerStartBitDisabled); - - base->flexioBase->TIMCTL[base->timerIndex] = - FLEXIO_TIMCTL_TRGSEL(FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->txShifterEndIndex)) | - FLEXIO_TIMCTL_TRGPOL(kFLEXIO_TimerTriggerPolarityActiveLow) | - FLEXIO_TIMCTL_TRGSRC(kFLEXIO_TimerTriggerSourceInternal) | FLEXIO_TIMCTL_PINCFG(kFLEXIO_PinConfigOutput) | - FLEXIO_TIMCTL_PINSEL(base->ENWRPinIndex) | FLEXIO_TIMCTL_PINPOL(kFLEXIO_PinActiveLow) | - FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitBaudBit); -} - -/*! - * brief Clear the FLEXIO MCULCD multiple beats write mode configuration. - * - * Clear the write configuration set by ref FLEXIO_MCULCD_SetMultBeatsWriteConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_ClearMultiBeatsWriteConfig(FLEXIO_MCULCD_Type *base) -{ - uint8_t i; - uint32_t statusFlags = 0U; - - /* Disable the timer. */ - base->flexioBase->TIMCTL[base->timerIndex] = 0U; - base->flexioBase->TIMCFG[base->timerIndex] = 0U; - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex); - - /* Stop the TX shifter. */ - for (i = base->txShifterStartIndex; i <= base->txShifterEndIndex; i++) - { - base->flexioBase->SHIFTCFG[i] = 0U; - base->flexioBase->SHIFTCTL[i] = 0U; - statusFlags |= (1UL << i); - } - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = statusFlags; -} - -/*! - * brief Configures the FLEXIO MCULCD to multiple beats read mode. - * - * At the begining or multiple beats read operation, the FLEXIO MCULCD is configured - * to multiple beats read mode using this function. After read operation, the configuration - * is cleared by ref FLEXIO_MCULCD_ClearMultBeatsReadConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_SetMultiBeatsReadConfig(FLEXIO_MCULCD_Type *base) -{ - /* - * This function will be called at the beginning of every data reading. For - * performance consideration, it access the FlexIO registers directly, but not - * call FlexIO driver APIs. - */ - - uint8_t timerPin; - uint8_t beats; - uint8_t i; - uint32_t timerCompare; - flexio_pin_polarity_t timerPinPolarity; - - /* Timer output to RD pin (8080 mode), to WR/EN pin in 6800 mode. */ - if (kFLEXIO_MCULCD_8080 == base->busType) - { - timerPin = base->RDPinIndex; - timerPinPolarity = kFLEXIO_PinActiveLow; - } - else - { - timerPin = base->ENWRPinIndex; - timerPinPolarity = kFLEXIO_PinActiveHigh; - } - - /* Enable the RX Shifter input. */ - for (i = base->rxShifterStartIndex; i < base->rxShifterEndIndex; i++) - { - base->flexioBase->SHIFTCFG[i] = FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U) | - FLEXIO_SHIFTCFG_INSRC(kFLEXIO_ShifterInputFromNextShifterOutput); - - base->flexioBase->SHIFTCTL[i] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutputDisabled) | FLEXIO_SHIFTCTL_PINSEL(base->dataPinStartIndex) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeReceive); - } - - base->flexioBase->SHIFTCFG[base->rxShifterEndIndex] = FLEXIO_SHIFTCFG_PWIDTH(FLEXIO_MCULCD_DATA_BUS_WIDTH - 1U); - base->flexioBase->SHIFTCTL[base->rxShifterEndIndex] = - FLEXIO_SHIFTCTL_TIMSEL(base->timerIndex) | FLEXIO_SHIFTCTL_TIMPOL(kFLEXIO_ShifterTimerPolarityOnNegitive) | - FLEXIO_SHIFTCTL_PINCFG(kFLEXIO_PinConfigOutputDisabled) | FLEXIO_SHIFTCTL_PINSEL(base->dataPinStartIndex) | - FLEXIO_SHIFTCTL_PINPOL(kFLEXIO_PinActiveHigh) | FLEXIO_SHIFTCTL_SMOD(kFLEXIO_ShifterModeReceive); - - timerCompare = base->flexioBase->TIMCMP[base->timerIndex] & 0xFFU; - -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - beats = 4U * (base->rxShifterEndIndex - base->rxShifterStartIndex + 1U); -#else - beats = 2U * (base->rxShifterEndIndex - base->rxShifterStartIndex + 1U); -#endif - - /* - * TIMCMP[15:8] = (number of beats x 2) - 1. - */ - base->flexioBase->TIMCMP[base->timerIndex] = ((beats * 2UL - 1UL) << 8U) | timerCompare; - - /* Use RX shifter flag as the inverted timer trigger. */ - base->flexioBase->TIMCFG[base->timerIndex] = - FLEXIO_TIMCFG_TIMOUT(kFLEXIO_TimerOutputOneNotAffectedByReset) | - FLEXIO_TIMCFG_TIMDEC(kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput) | - FLEXIO_TIMCFG_TIMRST(kFLEXIO_TimerResetNever) | FLEXIO_TIMCFG_TIMDIS(kFLEXIO_TimerDisableOnTimerCompare) | - FLEXIO_TIMCFG_TIMENA(kFLEXIO_TimerEnableOnTriggerHigh) | - FLEXIO_TIMCFG_TSTOP(kFLEXIO_TimerStopBitEnableOnTimerDisable) | - FLEXIO_TIMCFG_TSTART(kFLEXIO_TimerStartBitDisabled); - - base->flexioBase->TIMCTL[base->timerIndex] |= - FLEXIO_TIMCTL_TRGSEL(FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->rxShifterEndIndex)) | - FLEXIO_TIMCTL_TRGPOL(kFLEXIO_TimerTriggerPolarityActiveLow) | - FLEXIO_TIMCTL_TRGSRC(kFLEXIO_TimerTriggerSourceInternal) | FLEXIO_TIMCTL_PINCFG(kFLEXIO_PinConfigOutput) | - FLEXIO_TIMCTL_PINSEL(timerPin) | FLEXIO_TIMCTL_PINPOL(timerPinPolarity) | - FLEXIO_TIMCTL_TIMOD(kFLEXIO_TimerModeDual8BitBaudBit); -} - -/*! - * brief Clear the FLEXIO MCULCD multiple beats read mode configuration. - * - * Clear the read configuration set by ref FLEXIO_MCULCD_SetMultBeatsReadConfig. - * - * param base Pointer to the FLEXIO_MCULCD_Type. - * - * note This is an internal used function, upper layer should not use. - */ -void FLEXIO_MCULCD_ClearMultiBeatsReadConfig(FLEXIO_MCULCD_Type *base) -{ - uint8_t i; - uint32_t statusFlags = 0U; - - /* Disable the timer. */ - base->flexioBase->TIMCTL[base->timerIndex] = 0U; - base->flexioBase->TIMCFG[base->timerIndex] = 0U; - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex); - /* Stop the RX shifter. */ - for (i = base->rxShifterStartIndex; i <= base->rxShifterEndIndex; i++) - { - base->flexioBase->SHIFTCTL[i] = 0U; - base->flexioBase->SHIFTCFG[i] = 0U; - statusFlags |= (1UL << i); - } - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = statusFlags; -} - -/*! - * brief Wait for transmit data send out finished. - * - * Currently there is no effective method to wait for the data send out - * from the shiter, so here use a while loop to wait. - * - * note This is an internal used function. - */ -void FLEXIO_MCULCD_WaitTransmitComplete(void) -{ - uint32_t i = FLEXIO_MCULCD_WAIT_COMPLETE_TIME; - - while (0U != (i--)) - { - __NOP(); - } -} - -/*! - * brief Send command in blocking way. - * - * This function sends the command and returns when the command has been sent - * out. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param command The command to send. - */ -void FLEXIO_MCULCD_WriteCommandBlocking(FLEXIO_MCULCD_Type *base, uint32_t command) -{ - FLEXIO_Type *flexioBase = base->flexioBase; - - /* De-assert the RS pin. */ - base->setRSPin(false); - - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - - /* Configure the timer and TX shifter. */ - FLEXIO_MCULCD_SetSingleBeatWriteConfig(base); - - /* Write command to shifter buffer. */ - flexioBase->SHIFTBUF[base->txShifterStartIndex] = command; - - /* Wait for command send out. */ - while (0U == ((1UL << base->timerIndex) & FLEXIO_GetTimerStatusFlags(flexioBase))) - { - } - - /* Stop the timer and TX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); - - /* Assert the RS pin. */ - base->setRSPin(true); - /* For 6800, assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(true); - } -} - -/*! - * brief Send data array in blocking way. - * - * This function sends the data array and returns when the data sent out. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param data The data array to send. - * param size How many bytes to write. - */ -void FLEXIO_MCULCD_WriteDataArrayBlocking(FLEXIO_MCULCD_Type *base, void *data, size_t size) -{ - assert(size > 0U); - - uint32_t i; -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - uint8_t *data8Bit; -#else - uint16_t *data16Bit; -#endif - FLEXIO_Type *flexioBase = base->flexioBase; - - /* Assert the RS pin. */ - base->setRSPin(true); - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - - /* Configure the timer and TX shifter. */ - FLEXIO_MCULCD_SetSingleBeatWriteConfig(base); - -/* If data bus width is 8. */ -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - data8Bit = (uint8_t *)data; - - for (i = 0; i < size; i++) - { - flexioBase->SHIFTBUF[base->txShifterStartIndex] = data8Bit[i]; - - /* Wait for the data send out. */ - while (0U == ((1UL << base->timerIndex) & flexioBase->TIMSTAT)) - { - } - - /* Clear the timer stat. */ - flexioBase->TIMSTAT = 1UL << base->timerIndex; - } -#else - data16Bit = (uint16_t *)data; - size /= 2U; - - for (i = 0; i < size; i++) - { - flexioBase->SHIFTBUF[base->txShifterStartIndex] = data16Bit[i]; - - /* Wait for the data send out. */ - while (0U == ((1UL << base->timerIndex) & flexioBase->TIMSTAT)) - { - } - - /* Clear the timer stat. */ - flexioBase->TIMSTAT = 1UL << base->timerIndex; - } -#endif - - /* Stop the timer and TX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); -} - -/*! - * brief Read data into array in blocking way. - * - * This function reads the data into array and returns when the data read - * finished. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param data The array to save the data. - * param size How many bytes to read. - */ -void FLEXIO_MCULCD_ReadDataArrayBlocking(FLEXIO_MCULCD_Type *base, void *data, size_t size) -{ - assert(size > 0U); - - uint32_t i; - -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - uint8_t *data8Bit = (uint8_t *)data; -#else - uint16_t *data16Bit = (uint16_t *)data; -#endif - FLEXIO_Type *flexioBase = base->flexioBase; - - /* Assert the RS pin. */ - base->setRSPin(true); - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - - /* Enable the timer and RX shifter. */ - FLEXIO_MCULCD_SetSingleBeatReadConfig(base); - -/* If data bus width is 8. */ -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - for (i = 0; i < (size - 1U); i++) - { - /* Wait for shifter buffer full. */ - while (0U == ((1UL << base->rxShifterEndIndex) & FLEXIO_GetShifterStatusFlags(flexioBase))) - { - } - - data8Bit[i] = (uint8_t)flexioBase->SHIFTBUFBYS[base->rxShifterEndIndex]; - } -#else - /* Data bus width is 16. */ - size /= 2U; - - for (i = 0; i < (size - 1U); i++) - { - /* Wait for shifter buffer full. */ - while (0U == ((1UL << base->rxShifterEndIndex) & FLEXIO_GetShifterStatusFlags(flexioBase))) - { - } - - data16Bit[i] = (uint16_t)flexioBase->SHIFTBUFHWS[base->rxShifterEndIndex]; - } -#endif - - /* Wait for shifter buffer full. */ - while (0U == ((1UL << base->rxShifterEndIndex) & FLEXIO_GetShifterStatusFlags(flexioBase))) - { - } - - /* Stop the timer and disable the RX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatReadConfig(base); - -/* Read out the last data. */ -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - data8Bit[i] = (uint8_t)flexioBase->SHIFTBUFBYS[base->rxShifterEndIndex]; -#else - data16Bit[i] = (uint16_t)flexioBase->SHIFTBUFHWS[base->rxShifterEndIndex]; -#endif -} - -/*! - * brief Send the same value many times in blocking way. - * - * This function sends the same value many times. It could be used to clear the - * LCD screen. If the data bus width is 8, this function will send LSB 8 bits of - * p sameValue for p size times. If the data bus is 16, this function will send - * LSB 16 bits of p sameValue for p size / 2 times. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param sameValue The same value to send. - * param size How many bytes to send. - */ -void FLEXIO_MCULCD_WriteSameValueBlocking(FLEXIO_MCULCD_Type *base, uint32_t sameValue, size_t size) -{ - assert(size > 0U); - - uint32_t i; - FLEXIO_Type *flexioBase = base->flexioBase; - -#if (16 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - size /= 2U; -#endif - - /* Assert the RS pin. */ - base->setRSPin(true); - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - - /* Configure the timer and TX shifter. */ - FLEXIO_MCULCD_SetSingleBeatWriteConfig(base); - - for (i = 0; i < size; i++) - { - flexioBase->SHIFTBUF[base->txShifterStartIndex] = sameValue; - - /* Wait for the data send out. */ - while (0U == ((1UL << base->timerIndex) & flexioBase->TIMSTAT)) - { - } - - /* Clear the timer stat. */ - flexioBase->TIMSTAT = 1UL << base->timerIndex; - } - - /* Stop the timer and TX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); -} - -/*! - * brief Performs a polling transfer. - * - * note The API does not return until the transfer finished. - * - * param base pointer to FLEXIO_MCULCD_Type structure. - * param xfer pointer to flexio_mculcd_transfer_t structure. - */ -void FLEXIO_MCULCD_TransferBlocking(FLEXIO_MCULCD_Type *base, flexio_mculcd_transfer_t *xfer) -{ - FLEXIO_MCULCD_StartTransfer(base); - - FLEXIO_MCULCD_WriteCommandBlocking(base, xfer->command); - - if (xfer->dataSize > 0U) - { - if (kFLEXIO_MCULCD_ReadArray == xfer->mode) - { - FLEXIO_MCULCD_ReadDataArrayBlocking(base, (uint8_t *)(xfer->dataAddrOrSameValue), xfer->dataSize); - } - else if (kFLEXIO_MCULCD_WriteArray == xfer->mode) - { - FLEXIO_MCULCD_WriteDataArrayBlocking(base, (uint8_t *)(xfer->dataAddrOrSameValue), xfer->dataSize); - } - else - { - FLEXIO_MCULCD_WriteSameValueBlocking(base, xfer->dataAddrOrSameValue, xfer->dataSize); - } - } - - FLEXIO_MCULCD_StopTransfer(base); -} - -/*! - * brief Initializes the FlexIO MCULCD handle, which is used in transactional - * functions. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param handle Pointer to the flexio_mculcd_handle_t structure to store the - * transfer state. - * param callback The callback function. - * param userData The parameter of the callback function. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_MCULCD_TransferCreateHandle(FLEXIO_MCULCD_Type *base, - flexio_mculcd_handle_t *handle, - flexio_mculcd_transfer_callback_t callback, - void *userData) -{ - assert(NULL != handle); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - /* Register callback and userData. */ - handle->completionCallback = callback; - handle->userData = userData; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_GetInstance(base->flexioBase)]); - - /* Save the context in global variables to support the double weak mechanism. - */ - return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_MCULCD_TransferHandleIRQ); -} - -/*! - * brief Transfer data using IRQ. - * - * This function sends data using IRQ. This is a non-blocking function, which - * returns right away. When all data is sent out/received, the callback - * function is called. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param handle Pointer to the flexio_mculcd_handle_t structure to store the - * transfer state. - * param xfer FlexIO MCULCD transfer structure. See #flexio_mculcd_transfer_t. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_MCULCD_Busy MCULCD is busy with another transfer. - */ -status_t FLEXIO_MCULCD_TransferNonBlocking(FLEXIO_MCULCD_Type *base, - flexio_mculcd_handle_t *handle, - flexio_mculcd_transfer_t *xfer) -{ - /* If previous transfer is in progress. */ - if ((uint32_t)kFLEXIO_MCULCD_StateIdle != handle->state) - { - return kStatus_FLEXIO_MCULCD_Busy; - } - - /* Set the state in handle. */ - if (kFLEXIO_MCULCD_ReadArray == xfer->mode) - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateReadArray; - } - else if (kFLEXIO_MCULCD_WriteArray == xfer->mode) - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteArray; - } - else - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteSameValue; - } - - /* Assert the nCS. */ - FLEXIO_MCULCD_StartTransfer(base); - - /* Send the command. */ - FLEXIO_MCULCD_WriteCommandBlocking(base, xfer->command); - - /* If transfer count is 0 (only to send command), return directly. */ - if (0U == xfer->dataSize) - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - /* De-assert the nCS. */ - FLEXIO_MCULCD_StopTransfer(base); - - if (NULL != handle->completionCallback) - { - handle->completionCallback(base, handle, kStatus_FLEXIO_MCULCD_Idle, handle->userData); - } - } - else - { -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - handle->dataCount = xfer->dataSize; -#else - handle->dataCount = xfer->dataSize / 2U; -#endif - - handle->remainingCount = handle->dataCount; - - handle->dataAddrOrSameValue = xfer->dataAddrOrSameValue; - - /* Enable interrupt. */ - if (kFLEXIO_MCULCD_ReadArray == xfer->mode) - { - /* For 6800, assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(true); - } - FLEXIO_MCULCD_SetSingleBeatReadConfig(base); - FLEXIO_MCULCD_EnableInterrupts(base, (uint32_t)kFLEXIO_MCULCD_RxFullInterruptEnable); - } - else - { - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - FLEXIO_MCULCD_SetSingleBeatWriteConfig(base); - FLEXIO_MCULCD_EnableInterrupts(base, (uint32_t)kFLEXIO_MCULCD_TxEmptyInterruptEnable); - } - } - - return kStatus_Success; -} - -/*! - * brief Aborts the data transfer, which used IRQ. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param handle Pointer to the flexio_mculcd_handle_t structure to store the - * transfer state. - */ -void FLEXIO_MCULCD_TransferAbort(FLEXIO_MCULCD_Type *base, flexio_mculcd_handle_t *handle) -{ - /* If no transfer in process, return directly. */ - if ((uint32_t)kFLEXIO_MCULCD_StateIdle == handle->state) - { - return; - } - - /* Disable the interrupt. */ - FLEXIO_MCULCD_DisableInterrupts( - base, (uint32_t)kFLEXIO_MCULCD_RxFullInterruptEnable | (uint32_t)kFLEXIO_MCULCD_TxEmptyInterruptEnable); - - if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == handle->state) - { - /* Stop the timer and disable the RX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatReadConfig(base); - } - else - { - /* Stop the timer and disable the TX shifter. */ - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(base); - } - - /* Clean the flags. */ - FLEXIO_MCULCD_ClearStatusFlags(base, (uint32_t)kFLEXIO_MCULCD_TxEmptyFlag | (uint32_t)kFLEXIO_MCULCD_RxFullFlag); - - /* De-assert the nCS. */ - FLEXIO_MCULCD_StopTransfer(base); - - handle->dataCount = 0; - handle->remainingCount = 0; - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; -} - -/*! - * brief Gets the data transfer status which used IRQ. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param handle Pointer to the flexio_mculcd_handle_t structure to store the - * transfer state. - * param count How many bytes transferred so far by the non-blocking transaction. - * retval kStatus_Success Get the transferred count Successfully. - * retval kStatus_NoTransferInProgress No transfer in process. - */ -status_t FLEXIO_MCULCD_TransferGetCount(FLEXIO_MCULCD_Type *base, flexio_mculcd_handle_t *handle, size_t *count) -{ - assert(NULL != count); - - if ((uint32_t)kFLEXIO_MCULCD_StateIdle == handle->state) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->dataCount - handle->remainingCount; - -#if (16 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - *count *= 2U; -#endif - - return kStatus_Success; -} - -/*! - * brief FlexIO MCULCD IRQ handler function. - * - * param base Pointer to the FLEXIO_MCULCD_Type structure. - * param handle Pointer to the flexio_mculcd_handle_t structure to store the - * transfer state. - */ -void FLEXIO_MCULCD_TransferHandleIRQ(void *base, void *handle) -{ - FLEXIO_MCULCD_Type *flexioLcdMcuBase = (FLEXIO_MCULCD_Type *)base; - flexio_mculcd_handle_t *flexioLcdMcuHandle = (flexio_mculcd_handle_t *)handle; - uint32_t statusFlags = FLEXIO_MCULCD_GetStatusFlags(flexioLcdMcuBase); - uint32_t data; - - if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == flexioLcdMcuHandle->state) - { - /* Handle the reading process. */ - while ((0U != ((uint32_t)kFLEXIO_MCULCD_RxFullFlag & statusFlags)) && (flexioLcdMcuHandle->remainingCount > 0U)) - { - if (1U == flexioLcdMcuHandle->remainingCount) - { - /* If this is the last data, stop the RX shifter and timer. */ - FLEXIO_MCULCD_DisableInterrupts(flexioLcdMcuBase, (uint32_t)kFLEXIO_MCULCD_RxFullInterruptEnable); - FLEXIO_MCULCD_ClearSingleBeatReadConfig(flexioLcdMcuBase); - FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase); - } - - /* Read out the data. */ - data = FLEXIO_MCULCD_ReadData(flexioLcdMcuBase); - -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - *(uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue) = (uint8_t)data; - flexioLcdMcuHandle->dataAddrOrSameValue++; -#else - *(uint16_t *)(flexioLcdMcuHandle->dataAddrOrSameValue) = (uint16_t)data; - flexioLcdMcuHandle->dataAddrOrSameValue += 2U; -#endif - - flexioLcdMcuHandle->remainingCount--; - - /* Transfer finished, call the callback. */ - if (0U == flexioLcdMcuHandle->remainingCount) - { - flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - if (NULL != flexioLcdMcuHandle->completionCallback) - { - flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, - kStatus_FLEXIO_MCULCD_Idle, flexioLcdMcuHandle->userData); - } - } - - /* Is the shifter buffer ready to send the next data? */ - statusFlags = FLEXIO_MCULCD_GetStatusFlags(flexioLcdMcuBase); - } - } - else - { - /* Handle the writing process. */ - while ((0U != ((uint32_t)kFLEXIO_MCULCD_TxEmptyFlag & statusFlags)) && - (flexioLcdMcuHandle->remainingCount > 0U)) - { - /* Send the data. */ - if ((uint32_t)kFLEXIO_MCULCD_StateWriteSameValue == flexioLcdMcuHandle->state) - { - data = flexioLcdMcuHandle->dataAddrOrSameValue; - } - else - { -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - data = *(uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue); - flexioLcdMcuHandle->dataAddrOrSameValue++; -#else - data = *(uint16_t *)(flexioLcdMcuHandle->dataAddrOrSameValue); - flexioLcdMcuHandle->dataAddrOrSameValue += 2U; -#endif - } - - /* If this is the last data to send, delay to wait for the data shift out. */ - if (1U == flexioLcdMcuHandle->remainingCount) - { - FLEXIO_MCULCD_DisableInterrupts(flexioLcdMcuBase, (uint32_t)kFLEXIO_MCULCD_TxEmptyInterruptEnable); - - /* Write the last data. */ - FLEXIO_MCULCD_WriteData(flexioLcdMcuBase, data); - - /* Wait for the last data send finished. */ - FLEXIO_MCULCD_WaitTransmitComplete(); - flexioLcdMcuHandle->remainingCount = 0; - - FLEXIO_MCULCD_ClearSingleBeatWriteConfig(flexioLcdMcuBase); - FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase); - flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - if (NULL != flexioLcdMcuHandle->completionCallback) - { - flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, - kStatus_FLEXIO_MCULCD_Idle, flexioLcdMcuHandle->userData); - } - } - else - { - FLEXIO_MCULCD_WriteData(flexioLcdMcuBase, data); - flexioLcdMcuHandle->remainingCount--; - } - /* Is the shifter buffer ready to send the next data? */ - statusFlags = FLEXIO_MCULCD_GetStatusFlags(flexioLcdMcuBase); - } - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd_edma.c deleted file mode 100644 index 458ad8e72b..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_mculcd_edma.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_mculcd_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_mculcd_edma" -#endif - -#define EDMA_MAX_MAJOR_COUNT (DMA_CITER_ELINKNO_CITER_MASK >> DMA_CITER_ELINKNO_CITER_SHIFT) - -enum -{ - kFLEXIO_MCULCD_StateIdle, /*!< No transfer in progress. */ - kFLEXIO_MCULCD_StateReadArray, /*!< Reading array in progress. */ - kFLEXIO_MCULCD_StateWriteArray, /*!< Writing array in progress. */ - kFLEXIO_MCULCD_StateWriteSameValue, /*!< Writing the same value in progress. - */ -}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief EDMA callback function for FLEXIO MCULCD TX. - * - * For details, see @ref edma_callback. - */ -static void FLEXIO_MCULCD_TxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief EDMA callback function for FLEXIO MCULCD RX. - * - * For details, see @ref edma_callback. - */ -static void FLEXIO_MCULCD_RxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief Set EDMA config for FLEXIO MCULCD transfer. - * - * @param base pointer to FLEXIO_MCULCD_Type structure. - * @param handle pointer to flexio_mculcd_edma_handle_t structure to store the - * transfer state. - */ -static void FLEXIO_MCULCD_EDMAConfig(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle); - -/*! - * @brief Convert the FlexIO shifter number to eDMA modulo. - * - * @param shifterNum The FlexIO shifter number. - * @param modulo The modulo number. - * @retval Get the modulo successfully. - * @retval Could not get the modulo for the shifter number. - */ -static bool FLEXIO_MCULCD_GetEDMAModulo(uint8_t shifterNum, edma_modulo_t *modulo); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void FLEXIO_MCULCD_TxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds) -{ - tcds = tcds; - flexio_mculcd_edma_handle_t *flexioLcdMcuHandle = (flexio_mculcd_edma_handle_t *)param; - FLEXIO_MCULCD_Type *flexioLcdMcuBase = flexioLcdMcuHandle->base; - - if (transferDone) - { - if (flexioLcdMcuHandle->remainingCount >= flexioLcdMcuHandle->minorLoopBytes) - { - FLEXIO_MCULCD_EDMAConfig(flexioLcdMcuBase, flexioLcdMcuHandle); - EDMA_StartTransfer(flexioLcdMcuHandle->txDmaHandle); - } - else - { - FLEXIO_MCULCD_EnableTxDMA(flexioLcdMcuBase, false); - - /* Now the data are in shifter, wait for the data send out from the shifter. */ - FLEXIO_MCULCD_WaitTransmitComplete(); - - /* Disable the TX shifter and the timer. */ - FLEXIO_MCULCD_ClearMultiBeatsWriteConfig(flexioLcdMcuBase); - - /* Send the remaining data. */ - if (0U != flexioLcdMcuHandle->remainingCount) - { - if ((uint32_t)kFLEXIO_MCULCD_StateWriteSameValue == flexioLcdMcuHandle->state) - { - FLEXIO_MCULCD_WriteSameValueBlocking(flexioLcdMcuBase, flexioLcdMcuHandle->dataAddrOrSameValue, - flexioLcdMcuHandle->remainingCount); - } - else - { - FLEXIO_MCULCD_WriteDataArrayBlocking(flexioLcdMcuBase, - (uint8_t *)flexioLcdMcuHandle->dataAddrOrSameValue, - flexioLcdMcuHandle->remainingCount); - } - } - - /* De-assert nCS. */ - FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase); - - /* Change the state. */ - flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - flexioLcdMcuHandle->dataCount = 0; - flexioLcdMcuHandle->remainingCount = 0; - - /* Callback to inform upper layer. */ - if (NULL != flexioLcdMcuHandle->completionCallback) - { - flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, kStatus_FLEXIO_MCULCD_Idle, - flexioLcdMcuHandle->userData); - } - } - } -} - -static void FLEXIO_MCULCD_RxEDMACallback(edma_handle_t *DmaHandle, void *param, bool transferDone, uint32_t tcds) -{ - tcds = tcds; - uint32_t i; - uint32_t rxBufAddr; - flexio_mculcd_edma_handle_t *flexioLcdMcuHandle = (flexio_mculcd_edma_handle_t *)param; - FLEXIO_MCULCD_Type *flexioLcdMcuBase = flexioLcdMcuHandle->base; - FLEXIO_Type *flexioBase = flexioLcdMcuBase->flexioBase; - - if (transferDone) - { - if (flexioLcdMcuHandle->remainingCount >= (2U * flexioLcdMcuHandle->minorLoopBytes)) - { - FLEXIO_MCULCD_EDMAConfig(flexioLcdMcuBase, flexioLcdMcuHandle); - EDMA_StartTransfer(flexioLcdMcuHandle->rxDmaHandle); - } - else - { - FLEXIO_MCULCD_EnableRxDMA(flexioLcdMcuBase, false); - - /* Wait the data saved to the shifter buffer. */ - while (0U == ((1UL << flexioLcdMcuBase->rxShifterEndIndex) & FLEXIO_GetShifterStatusFlags(flexioBase))) - { - } - - /* Disable the RX shifter and the timer. */ - FLEXIO_MCULCD_ClearMultiBeatsReadConfig(flexioLcdMcuBase); - - rxBufAddr = FLEXIO_MCULCD_GetRxDataRegisterAddress(flexioLcdMcuBase); - -/* Read out the data. */ -#if (defined(__CORTEX_M) && (__CORTEX_M == 0)) - /* Cortex M0 and M0+ only support aligned access. */ - for (i = 0; i < flexioLcdMcuHandle->rxShifterNum * 4; i++) - { - ((uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue))[i] = ((volatile uint8_t *)rxBufAddr)[i]; - } -#else - for (i = 0; i < flexioLcdMcuHandle->rxShifterNum; i++) - { - ((uint32_t *)(flexioLcdMcuHandle->dataAddrOrSameValue))[i] = ((volatile uint32_t *)rxBufAddr)[i]; - } -#endif - flexioLcdMcuHandle->remainingCount -= flexioLcdMcuHandle->minorLoopBytes; - - if (0U != flexioLcdMcuHandle->remainingCount) - { - FLEXIO_MCULCD_ReadDataArrayBlocking( - flexioLcdMcuBase, - (uint8_t *)(flexioLcdMcuHandle->dataAddrOrSameValue + flexioLcdMcuHandle->minorLoopBytes), - flexioLcdMcuHandle->remainingCount); - } - - /* De-assert nCS. */ - FLEXIO_MCULCD_StopTransfer(flexioLcdMcuBase); - - /* Change the state. */ - flexioLcdMcuHandle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - flexioLcdMcuHandle->dataCount = 0; - flexioLcdMcuHandle->remainingCount = 0; - - /* Callback to inform upper layer. */ - if (NULL != flexioLcdMcuHandle->completionCallback) - { - flexioLcdMcuHandle->completionCallback(flexioLcdMcuBase, flexioLcdMcuHandle, kStatus_FLEXIO_MCULCD_Idle, - flexioLcdMcuHandle->userData); - } - } - } -} - -static void FLEXIO_MCULCD_EDMAConfig(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle) -{ - edma_transfer_config_t xferConfig = {0}; - edma_transfer_size_t transferSize = kEDMA_TransferSize1Bytes; - int16_t offset; - uint32_t majorLoopCounts; - uint32_t transferCount; - -#if (8 == FLEXIO_MCULCD_DATA_BUS_WIDTH) - transferSize = kEDMA_TransferSize1Bytes; - offset = 1; -#else - transferSize = kEDMA_TransferSize2Bytes; - offset = 2; -#endif - - majorLoopCounts = handle->remainingCount / handle->minorLoopBytes; - - /* For reading, the last minor loop data is not tranfered by DMA. */ - if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == handle->state) - { - majorLoopCounts--; - } - - if (majorLoopCounts > EDMA_MAX_MAJOR_COUNT) - { - majorLoopCounts = EDMA_MAX_MAJOR_COUNT; - } - - transferCount = majorLoopCounts * handle->minorLoopBytes; - - if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == handle->state) - { - xferConfig.srcAddr = FLEXIO_MCULCD_GetRxDataRegisterAddress(base); - xferConfig.destAddr = handle->dataAddrOrSameValue; - xferConfig.srcTransferSize = kEDMA_TransferSize4Bytes; - xferConfig.destTransferSize = transferSize; - xferConfig.srcOffset = 4; - xferConfig.destOffset = offset; - xferConfig.minorLoopBytes = handle->minorLoopBytes; - xferConfig.majorLoopCounts = majorLoopCounts; - handle->remainingCount -= transferCount; - handle->dataAddrOrSameValue += transferCount; - (void)EDMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig); - EDMA_SetModulo(handle->rxDmaHandle->base, handle->rxDmaHandle->channel, handle->rxEdmaModulo, - kEDMA_ModuloDisable); - } - else - { - if ((uint32_t)kFLEXIO_MCULCD_StateWriteArray == handle->state) - { - xferConfig.srcAddr = handle->dataAddrOrSameValue; - xferConfig.srcOffset = offset; - handle->dataAddrOrSameValue += transferCount; - } - else - { - xferConfig.srcAddr = (uint32_t)(&(handle->dataAddrOrSameValue)); - xferConfig.srcOffset = 0; - } - xferConfig.destAddr = FLEXIO_MCULCD_GetTxDataRegisterAddress(base); - xferConfig.srcTransferSize = transferSize; - xferConfig.destTransferSize = kEDMA_TransferSize4Bytes; - xferConfig.destOffset = 4; - xferConfig.minorLoopBytes = handle->minorLoopBytes; - xferConfig.majorLoopCounts = majorLoopCounts; - handle->remainingCount -= transferCount; - (void)EDMA_SubmitTransfer(handle->txDmaHandle, &xferConfig); - EDMA_SetModulo(handle->txDmaHandle->base, handle->txDmaHandle->channel, kEDMA_ModuloDisable, - handle->txEdmaModulo); - } -} - -static bool FLEXIO_MCULCD_GetEDMAModulo(uint8_t shifterNum, edma_modulo_t *modulo) -{ - bool ret = true; - - switch (shifterNum) - { - case 1U: - *modulo = kEDMA_Modulo4bytes; - break; - case 2U: - *modulo = kEDMA_Modulo8bytes; - break; - case 4U: - *modulo = kEDMA_Modulo16bytes; - break; - case 8U: - *modulo = kEDMA_Modulo32bytes; - break; - default: - ret = false; - break; - } - - return ret; -} - -/*! - * brief Initializes the FLEXO MCULCD master eDMA handle. - * - * This function initializes the FLEXO MCULCD master eDMA handle which can be - * used for other FLEXO MCULCD transactional APIs. For a specified FLEXO MCULCD - * instance, call this API once to get the initialized handle. - * - * param base Pointer to FLEXIO_MCULCD_Type structure. - * param handle Pointer to flexio_mculcd_edma_handle_t structure to store the - * transfer state. - * param callback MCULCD transfer complete callback, NULL means no callback. - * param userData callback function parameter. - * param txDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA TX, - * the DMA request source of this handle should be the first of TX shifters. - * param rxDmaHandle User requested eDMA handle for FlexIO MCULCD eDMA RX, - * the DMA request source of this handle should be the last of RX shifters. - * retval kStatus_Success Successfully create the handle. - */ -status_t FLEXIO_MCULCD_TransferCreateHandleEDMA(FLEXIO_MCULCD_Type *base, - flexio_mculcd_edma_handle_t *handle, - flexio_mculcd_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txDmaHandle, - edma_handle_t *rxDmaHandle) -{ - assert(NULL != handle); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Initialize the state. */ - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - /* Register callback and userData. */ - handle->completionCallback = callback; - handle->userData = userData; - - handle->base = base; - handle->txShifterNum = base->txShifterEndIndex - base->txShifterStartIndex + 1U; - handle->rxShifterNum = base->rxShifterEndIndex - base->rxShifterStartIndex + 1U; - - if (NULL != rxDmaHandle) - { - if (!FLEXIO_MCULCD_GetEDMAModulo(handle->rxShifterNum, &handle->rxEdmaModulo)) - { - return kStatus_InvalidArgument; - } - - handle->rxDmaHandle = rxDmaHandle; - EDMA_SetCallback(rxDmaHandle, FLEXIO_MCULCD_RxEDMACallback, handle); - } - - if (NULL != txDmaHandle) - { - if (!FLEXIO_MCULCD_GetEDMAModulo(handle->txShifterNum, &handle->txEdmaModulo)) - { - return kStatus_InvalidArgument; - } - - handle->txDmaHandle = txDmaHandle; - EDMA_SetCallback(txDmaHandle, FLEXIO_MCULCD_TxEDMACallback, handle); - } - - return kStatus_Success; -} - -/*! - * brief Performs a non-blocking FlexIO MCULCD transfer using eDMA. - * - * This function returns immediately after transfer initiates. To check whether - * the transfer is completed, user could: - * 1. Use the transfer completed callback; - * 2. Polling function ref FLEXIO_MCULCD_GetTransferCountEDMA - * - * param base pointer to FLEXIO_MCULCD_Type structure. - * param handle pointer to flexio_mculcd_edma_handle_t structure to store the - * transfer state. - * param xfer Pointer to FlexIO MCULCD transfer structure. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_MCULCD_Busy FlexIO MCULCD is not idle, it is running another - * transfer. - */ -status_t FLEXIO_MCULCD_TransferEDMA(FLEXIO_MCULCD_Type *base, - flexio_mculcd_edma_handle_t *handle, - flexio_mculcd_transfer_t *xfer) -{ - assert(NULL != handle); - assert(NULL != xfer); - - /* - * The data transfer mechanism: - * - * Read: - * Assume the data length is Lr = (n1 * minorLoopBytes + n2), where - * n2 < minorLoopBytes. - * If (n1 <= 1), then all data are sent using blocking method. - * If (n1 > 1), then the beginning ((n1-1) * minorLoopBytes) are read - * using DMA, the left (minorLoopBytes + n2) are read using blocking method. - * - * Write: - * Assume the data length is Lw = (n1 * minorLoopBytes + n2), where - * n2 < minorLoopBytes. - * If (n1 = 0), then all data are sent using blocking method. - * If (n1 >= 1), then the beginning (n1 * minorLoopBytes) are sent - * using DMA, the left n2 are sent using blocking method. - */ - - /* Check if the device is busy. */ - if ((uint32_t)kFLEXIO_MCULCD_StateIdle != handle->state) - { - return kStatus_FLEXIO_MCULCD_Busy; - } - - /* Set the state in handle. */ - if (kFLEXIO_MCULCD_ReadArray == xfer->mode) - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateReadArray; - handle->minorLoopBytes = handle->rxShifterNum * 4UL; - } - else - { - handle->minorLoopBytes = handle->txShifterNum * 4UL; - - if (kFLEXIO_MCULCD_WriteArray == xfer->mode) - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteArray; - } - else - { - handle->state = (uint32_t)kFLEXIO_MCULCD_StateWriteSameValue; - } - } - - /* - * For TX, if data is less than one minor loop, then use polling method. - * For RX, if data is less than two minor loop, then use polling method. - */ - if ((xfer->dataSize < handle->minorLoopBytes) || - ((kFLEXIO_MCULCD_ReadArray == xfer->mode) && (xfer->dataSize < 2U * (handle->minorLoopBytes)))) - { - FLEXIO_MCULCD_TransferBlocking(base, xfer); - - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - - /* Callback to inform upper layer. */ - if (NULL != handle->completionCallback) - { - handle->completionCallback(base, handle, kStatus_FLEXIO_MCULCD_Idle, handle->userData); - } - } - else - { - handle->dataCount = xfer->dataSize; - handle->remainingCount = xfer->dataSize; - handle->dataAddrOrSameValue = xfer->dataAddrOrSameValue; - - /* Setup DMA to transfer data. */ - /* Assert the nCS. */ - FLEXIO_MCULCD_StartTransfer(base); - /* Send the command. */ - FLEXIO_MCULCD_WriteCommandBlocking(base, xfer->command); - - /* Setup the DMA configuration. */ - FLEXIO_MCULCD_EDMAConfig(base, handle); - - /* Start the transfer. */ - if (kFLEXIO_MCULCD_ReadArray == xfer->mode) - { - /* For 6800, assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(true); - } - FLEXIO_MCULCD_SetMultiBeatsReadConfig(base); - FLEXIO_MCULCD_EnableRxDMA(base, true); - EDMA_StartTransfer(handle->rxDmaHandle); - } - else - { - /* For 6800, de-assert the RDWR pin. */ - if (kFLEXIO_MCULCD_6800 == base->busType) - { - base->setRDWRPin(false); - } - FLEXIO_MCULCD_SetMultiBeatsWriteConfig(base); - FLEXIO_MCULCD_EnableTxDMA(base, true); - EDMA_StartTransfer(handle->txDmaHandle); - } - } - - return kStatus_Success; -} - -/*! - * brief Aborts a FlexIO MCULCD transfer using eDMA. - * - * param base pointer to FLEXIO_MCULCD_Type structure. - * param handle FlexIO MCULCD eDMA handle pointer. - */ -void FLEXIO_MCULCD_TransferAbortEDMA(FLEXIO_MCULCD_Type *base, flexio_mculcd_edma_handle_t *handle) -{ - assert(NULL != handle); - - /* Disable dma. */ - if (NULL != handle->txDmaHandle) - { - EDMA_AbortTransfer(handle->txDmaHandle); - } - if (NULL != handle->rxDmaHandle) - { - EDMA_AbortTransfer(handle->rxDmaHandle); - } - - /* Disable DMA enable bit. */ - FLEXIO_MCULCD_EnableTxDMA(handle->base, false); - FLEXIO_MCULCD_EnableRxDMA(handle->base, false); - - /* Set the handle state. */ - handle->state = (uint32_t)kFLEXIO_MCULCD_StateIdle; - handle->dataCount = 0; -} - -/*! - * brief Gets the remaining bytes for FlexIO MCULCD eDMA transfer. - * - * param base pointer to FLEXIO_MCULCD_Type structure. - * param handle FlexIO MCULCD eDMA handle pointer. - * param count Number of count transferred so far by the eDMA transaction. - * retval kStatus_Success Get the transferred count Successfully. - * retval kStatus_NoTransferInProgress No transfer in process. - */ -status_t FLEXIO_MCULCD_TransferGetCountEDMA(FLEXIO_MCULCD_Type *base, - flexio_mculcd_edma_handle_t *handle, - size_t *count) -{ - assert(NULL != handle); - assert(NULL != count); - uint32_t state = handle->state; - - if ((uint32_t)kFLEXIO_MCULCD_StateIdle == state) - { - return kStatus_NoTransferInProgress; - } - else - { - *count = handle->dataCount - handle->remainingCount; - - if ((uint32_t)kFLEXIO_MCULCD_StateReadArray == state) - { - *count -= handle->minorLoopBytes * - EDMA_GetRemainingMajorLoopCount(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); - } - else - { - *count -= handle->minorLoopBytes * - EDMA_GetRemainingMajorLoopCount(handle->txDmaHandle->base, handle->txDmaHandle->channel); - } - } - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi.c deleted file mode 100644 index 3c7db5d552..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi.c +++ /dev/null @@ -1,1326 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_spi.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_spi" -#endif - -/*! @brief FLEXIO SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */ -enum _flexio_spi_transfer_states -{ - kFLEXIO_SPI_Idle = 0x0U, /*!< Nothing in the transmitter/receiver's queue. */ - kFLEXIO_SPI_Busy, /*!< Transmiter/Receive's queue is not finished. */ -}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Send a piece of data for SPI. - * - * This function computes the number of data to be written into D register or Tx FIFO, - * and write the data into it. At the same time, this function updates the values in - * master handle structure. - * - * @param base pointer to FLEXIO_SPI_Type structure - * @param handle Pointer to SPI master handle structure. - */ -static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); - -/*! - * @brief Receive a piece of data for SPI master. - * - * This function computes the number of data to receive from D register or Rx FIFO, - * and write the data to destination address. At the same time, this function updates - * the values in master handle structure. - * - * @param base pointer to FLEXIO_SPI_Type structure - * @param handle Pointer to SPI master handle structure. - */ -static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Codes - ******************************************************************************/ - -static uint32_t FLEXIO_SPI_GetInstance(FLEXIO_SPI_Type *base) -{ - return FLEXIO_GetInstance(base->flexioBase); -} - -static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) -{ - uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; - - if (handle->txData != NULL) - { - /* Transmit data and update tx size/buff. */ - if (handle->bytePerFrame == 1U) - { - tmpData = *(handle->txData); - handle->txData++; - } - else - { - if (handle->direction == kFLEXIO_SPI_MsbFirst) - { - tmpData = (uint16_t)(handle->txData[0]) << 8U; - tmpData += handle->txData[1]; - } - else - { - tmpData = (uint16_t)(handle->txData[1]) << 8U; - tmpData += handle->txData[0]; - } - handle->txData += 2U; - } - } - else - { - tmpData = FLEXIO_SPI_DUMMYDATA; - } - - handle->txRemainingBytes -= handle->bytePerFrame; - - FLEXIO_SPI_WriteData(base, handle->direction, tmpData); - - if (0U == handle->txRemainingBytes) - { - FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable); - } -} - -static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) -{ - uint16_t tmpData; - - tmpData = FLEXIO_SPI_ReadData(base, handle->direction); - - if (handle->rxData != NULL) - { - if (handle->bytePerFrame == 1U) - { - *handle->rxData = (uint8_t)tmpData; - handle->rxData++; - } - else - { - if (handle->direction == kFLEXIO_SPI_MsbFirst) - { - *handle->rxData = (uint8_t)(tmpData >> 8); - handle->rxData++; - *handle->rxData = (uint8_t)tmpData; - } - else - { - *handle->rxData = (uint8_t)tmpData; - handle->rxData++; - *handle->rxData = (uint8_t)(tmpData >> 8); - } - handle->rxData++; - } - } - handle->rxRemainingBytes -= handle->bytePerFrame; -} - -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI master hardware, - * and configures the FlexIO SPI with FlexIO SPI master configuration. The - * configuration structure can be filled by the user, or be set with default values - * by the FLEXIO_SPI_MasterGetDefaultConfig(). - * - * note 1.FlexIO SPI master only support CPOL = 0, which means clock inactive low. - * 2.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time - * is 2.5 clock cycles. So if FlexIO SPI master communicates with other spi IPs, the maximum baud - * rate is FlexIO clock frequency divided by 2*2=4. If FlexIO SPI master communicates with FlexIO - * SPI slave, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8. - * - * Example - code - FLEXIO_SPI_Type spiDev = { - .flexioBase = FLEXIO, - .SDOPinIndex = 0, - .SDIPinIndex = 1, - .SCKPinIndex = 2, - .CSnPinIndex = 3, - .shifterIndex = {0,1}, - .timerIndex = {0,1} - }; - flexio_spi_master_config_t config = { - .enableMaster = true, - .enableInDoze = false, - .enableInDebug = true, - .enableFastAccess = false, - .baudRate_Bps = 500000, - .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, - .direction = kFLEXIO_SPI_MsbFirst, - .dataMode = kFLEXIO_SPI_8BitMode - }; - FLEXIO_SPI_MasterInit(&spiDev, &config, srcClock_Hz); - endcode - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param masterConfig Pointer to the flexio_spi_master_config_t structure. - * param srcClock_Hz FlexIO source clock in Hz. -*/ -void FLEXIO_SPI_MasterInit(FLEXIO_SPI_Type *base, flexio_spi_master_config_t *masterConfig, uint32_t srcClock_Hz) -{ - assert(base != NULL); - assert(masterConfig != NULL); - - flexio_shifter_config_t shifterConfig; - flexio_timer_config_t timerConfig; - uint32_t ctrlReg = 0; - uint16_t timerDiv = 0; - uint16_t timerCmp = 0; - - /* Clear the shifterConfig & timerConfig struct. */ - (void)memset(&shifterConfig, 0, sizeof(shifterConfig)); - (void)memset(&timerConfig, 0, sizeof(timerConfig)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Configure FLEXIO SPI Master */ - ctrlReg = base->flexioBase->CTRL; - ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - ctrlReg |= (FLEXIO_CTRL_DBGE(masterConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(masterConfig->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(masterConfig->enableMaster)); - if (!masterConfig->enableInDoze) - { - ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; - } - - base->flexioBase->CTRL = ctrlReg; - - /* Do hardware configuration. */ - /* 1. Configure the shifter 0 for tx. */ - shifterConfig.timerSelect = base->timerIndex[0]; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; - shifterConfig.pinSelect = base->SDOPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - } - else - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitLow; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; - } - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); - - /* 2. Configure the shifter 1 for rx. */ - shifterConfig.timerSelect = base->timerIndex[0]; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinSelect = base->SDIPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - if (masterConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - } - else - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - } - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); - - /*3. Configure the timer 0 for SCK. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutput; - timerConfig.pinSelect = base->SCKPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; - timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; - timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - - timerDiv = (uint16_t)(srcClock_Hz / masterConfig->baudRate_Bps); - timerDiv = timerDiv / 2U - 1U; - - timerCmp = ((uint16_t)masterConfig->dataMode * 2U - 1U) << 8U; - timerCmp |= timerDiv; - - timerConfig.timerCompare = timerCmp; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); - - /* 4. Configure the timer 1 for CSn. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_TIMn(base->timerIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutput; - timerConfig.pinSelect = base->CSnPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveLow; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnPreTimerDisable; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPrevTimerEnable; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - - timerConfig.timerCompare = 0xFFFFU; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); -} - -/*! - * brief Resets the FlexIO SPI timer and shifter config. - * - * param base Pointer to the FLEXIO_SPI_Type. - */ -void FLEXIO_SPI_MasterDeinit(FLEXIO_SPI_Type *base) -{ - base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[0]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[0]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[0]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[1]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[1]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[1]] = 0; -} - -/*! - * brief Gets the default configuration to configure the FlexIO SPI master. The configuration - * can be used directly by calling the FLEXIO_SPI_MasterConfigure(). - * Example: - code - flexio_spi_master_config_t masterConfig; - FLEXIO_SPI_MasterGetDefaultConfig(&masterConfig); - endcode - * param masterConfig Pointer to the flexio_spi_master_config_t structure. -*/ -void FLEXIO_SPI_MasterGetDefaultConfig(flexio_spi_master_config_t *masterConfig) -{ - assert(masterConfig != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(masterConfig, 0, sizeof(*masterConfig)); - - masterConfig->enableMaster = true; - masterConfig->enableInDoze = false; - masterConfig->enableInDebug = true; - masterConfig->enableFastAccess = false; - /* Default baud rate 500kbps. */ - masterConfig->baudRate_Bps = 500000U; - /* Default CPHA = 0. */ - masterConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; - /* Default bit count at 8. */ - masterConfig->dataMode = kFLEXIO_SPI_8BitMode; -} - -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, configures the FlexIO SPI slave hardware - * configuration, and configures the FlexIO SPI with FlexIO SPI slave configuration. The - * configuration structure can be filled by the user, or be set with default values - * by the FLEXIO_SPI_SlaveGetDefaultConfig(). - * - * note 1.Only one timer is needed in the FlexIO SPI slave. As a result, the second timer index is ignored. - * 2.FlexIO SPI slave only support CPOL = 0, which means clock inactive low. - * 3.For FlexIO SPI master, the input valid time is 1.5 clock cycles, for slave the output valid time - * is 2.5 clock cycles. So if FlexIO SPI slave communicates with other spi IPs, the maximum baud - * rate is FlexIO clock frequency divided by 3*2=6. If FlexIO SPI slave communicates with FlexIO - * SPI master, the maximum baud rate is FlexIO clock frequency divided by (1.5+2.5)*2=8. - * Example - code - FLEXIO_SPI_Type spiDev = { - .flexioBase = FLEXIO, - .SDOPinIndex = 0, - .SDIPinIndex = 1, - .SCKPinIndex = 2, - .CSnPinIndex = 3, - .shifterIndex = {0,1}, - .timerIndex = {0} - }; - flexio_spi_slave_config_t config = { - .enableSlave = true, - .enableInDoze = false, - .enableInDebug = true, - .enableFastAccess = false, - .phase = kFLEXIO_SPI_ClockPhaseFirstEdge, - .direction = kFLEXIO_SPI_MsbFirst, - .dataMode = kFLEXIO_SPI_8BitMode - }; - FLEXIO_SPI_SlaveInit(&spiDev, &config); - endcode - * param base Pointer to the FLEXIO_SPI_Type structure. - * param slaveConfig Pointer to the flexio_spi_slave_config_t structure. -*/ -void FLEXIO_SPI_SlaveInit(FLEXIO_SPI_Type *base, flexio_spi_slave_config_t *slaveConfig) -{ - assert((base != NULL) && (slaveConfig != NULL)); - - flexio_shifter_config_t shifterConfig; - flexio_timer_config_t timerConfig; - uint32_t ctrlReg = 0; - - /* Clear the shifterConfig & timerConfig struct. */ - (void)memset(&shifterConfig, 0, sizeof(shifterConfig)); - (void)memset(&timerConfig, 0, sizeof(timerConfig)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_SPI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Configure FLEXIO SPI Slave */ - ctrlReg = base->flexioBase->CTRL; - ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - ctrlReg |= (FLEXIO_CTRL_DBGE(slaveConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(slaveConfig->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(slaveConfig->enableSlave)); - if (!slaveConfig->enableInDoze) - { - ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; - } - - base->flexioBase->CTRL = ctrlReg; - - /* Do hardware configuration. */ - /* 1. Configure the shifter 0 for tx. */ - shifterConfig.timerSelect = base->timerIndex[0]; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; - shifterConfig.pinSelect = base->SDOPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - } - else - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnShift; - } - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); - - /* 2. Configure the shifter 1 for rx. */ - shifterConfig.timerSelect = base->timerIndex[0]; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinSelect = base->SDIPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitDisable; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitDisabledLoadDataOnEnable; - if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - } - else - { - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - } - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); - - /*3. Configure the timer 0 for shift clock. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->CSnPinIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->SCKPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit; - timerConfig.timerOutput = kFLEXIO_TimerOutputZeroNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnPinInputShiftPinInput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerRisingEdge; - timerConfig.timerStop = kFLEXIO_TimerStopBitDisabled; - if (slaveConfig->phase == kFLEXIO_SPI_ClockPhaseFirstEdge) - { - /* The configuration kFLEXIO_TimerDisableOnTimerCompare only support continuous - PCS access, change to kFLEXIO_TimerDisableNever to enable discontinuous PCS access. */ - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerStart = kFLEXIO_TimerStartBitDisabled; - } - else - { - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTriggerFallingEdge; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - } - - timerConfig.timerCompare = (uint32_t)slaveConfig->dataMode * 2U - 1U; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); -} - -/*! - * brief Gates the FlexIO clock. - * - * param base Pointer to the FLEXIO_SPI_Type. - */ -void FLEXIO_SPI_SlaveDeinit(FLEXIO_SPI_Type *base) -{ - FLEXIO_SPI_MasterDeinit(base); -} - -/*! - * brief Gets the default configuration to configure the FlexIO SPI slave. The configuration - * can be used directly for calling the FLEXIO_SPI_SlaveConfigure(). - * Example: - code - flexio_spi_slave_config_t slaveConfig; - FLEXIO_SPI_SlaveGetDefaultConfig(&slaveConfig); - endcode - * param slaveConfig Pointer to the flexio_spi_slave_config_t structure. -*/ -void FLEXIO_SPI_SlaveGetDefaultConfig(flexio_spi_slave_config_t *slaveConfig) -{ - assert(slaveConfig != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(slaveConfig, 0, sizeof(*slaveConfig)); - - slaveConfig->enableSlave = true; - slaveConfig->enableInDoze = false; - slaveConfig->enableInDebug = true; - slaveConfig->enableFastAccess = false; - /* Default CPHA = 0. */ - slaveConfig->phase = kFLEXIO_SPI_ClockPhaseFirstEdge; - /* Default bit count at 8. */ - slaveConfig->dataMode = kFLEXIO_SPI_8BitMode; -} - -/*! - * brief Enables the FlexIO SPI interrupt. - * - * This function enables the FlexIO SPI interrupt. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param mask interrupt source. The parameter can be any combination of the following values: - * arg kFLEXIO_SPI_RxFullInterruptEnable - * arg kFLEXIO_SPI_TxEmptyInterruptEnable - */ -void FLEXIO_SPI_EnableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Disables the FlexIO SPI interrupt. - * - * This function disables the FlexIO SPI interrupt. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param mask interrupt source The parameter can be any combination of the following values: - * arg kFLEXIO_SPI_RxFullInterruptEnable - * arg kFLEXIO_SPI_TxEmptyInterruptEnable - */ -void FLEXIO_SPI_DisableInterrupts(FLEXIO_SPI_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Enables/disables the FlexIO SPI transmit DMA. This function enables/disables the FlexIO SPI Tx DMA, - * which means that asserting the kFLEXIO_SPI_TxEmptyFlag does/doesn't trigger the DMA request. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param mask SPI DMA source. - * param enable True means enable DMA, false means disable DMA. - */ -void FLEXIO_SPI_EnableDMA(FLEXIO_SPI_Type *base, uint32_t mask, bool enable) -{ - if ((mask & (uint32_t)kFLEXIO_SPI_TxDmaEnable) != 0U) - { - FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[0], enable); - } - - if ((mask & (uint32_t)kFLEXIO_SPI_RxDmaEnable) != 0U) - { - FLEXIO_EnableShifterStatusDMA(base->flexioBase, 1UL << base->shifterIndex[1], enable); - } -} - -/*! - * brief Gets FlexIO SPI status flags. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * return status flag; Use the status flag to AND the following flag mask and get the status. - * arg kFLEXIO_SPI_TxEmptyFlag - * arg kFLEXIO_SPI_RxEmptyFlag - */ - -uint32_t FLEXIO_SPI_GetStatusFlags(FLEXIO_SPI_Type *base) -{ - uint32_t shifterStatus = FLEXIO_GetShifterStatusFlags(base->flexioBase); - uint32_t status = 0; - - status = ((shifterStatus & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]); - status |= (((shifterStatus & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) << 1U); - - return status; -} - -/*! - * brief Clears FlexIO SPI status flags. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param mask status flag - * The parameter can be any combination of the following values: - * arg kFLEXIO_SPI_TxEmptyFlag - * arg kFLEXIO_SPI_RxEmptyFlag - */ - -void FLEXIO_SPI_ClearStatusFlags(FLEXIO_SPI_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Sets baud rate for the FlexIO SPI transfer, which is only used for the master. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param baudRate_Bps Baud Rate needed in Hz. - * param srcClockHz SPI source clock frequency in Hz. - */ -void FLEXIO_SPI_MasterSetBaudRate(FLEXIO_SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClockHz) -{ - uint16_t timerDiv = 0; - uint16_t timerCmp = 0; - FLEXIO_Type *flexioBase = base->flexioBase; - - /* Set TIMCMP[7:0] = (baud rate divider / 2) - 1.*/ - timerDiv = (uint16_t)(srcClockHz / baudRate_Bps); - timerDiv = timerDiv / 2U - 1U; - - timerCmp = (uint16_t)(flexioBase->TIMCMP[base->timerIndex[0]]); - timerCmp &= 0xFF00U; - timerCmp |= timerDiv; - - flexioBase->TIMCMP[base->timerIndex[0]] = timerCmp; -} - -/*! - * brief Sends a buffer of data bytes. - * - * note This function blocks using the polling method until all bytes have been sent. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param direction Shift direction of MSB first or LSB first. - * param buffer The data bytes to send. - * param size The number of data bytes to send. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted. - */ -status_t FLEXIO_SPI_WriteBlocking(FLEXIO_SPI_Type *base, - flexio_spi_shift_direction_t direction, - const uint8_t *buffer, - size_t size) -{ - assert(buffer != NULL); - assert(size != 0U); - -#if SPI_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != size--) - { - /* Wait until data transfer complete. */ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_FLEXIO_SPI_Timeout; - } -#endif - FLEXIO_SPI_WriteData(base, direction, *buffer++); - } - - return kStatus_Success; -} - -/*! - * brief Receives a buffer of bytes. - * - * note This function blocks using the polling method until all bytes have been received. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param direction Shift direction of MSB first or LSB first. - * param buffer The buffer to store the received bytes. - * param size The number of data bytes to be received. - * param direction Shift direction of MSB first or LSB first. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted. - */ -status_t FLEXIO_SPI_ReadBlocking(FLEXIO_SPI_Type *base, - flexio_spi_shift_direction_t direction, - uint8_t *buffer, - size_t size) -{ - assert(buffer != NULL); - assert(size != 0U); - -#if SPI_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != size--) - { - /* Wait until data transfer complete. */ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_FLEXIO_SPI_Timeout; - } -#endif - *buffer++ = (uint8_t)FLEXIO_SPI_ReadData(base, direction); - } - - return kStatus_Success; -} - -/*! - * brief Receives a buffer of bytes. - * - * note This function blocks via polling until all bytes have been received. - * - * param base pointer to FLEXIO_SPI_Type structure - * param xfer FlexIO SPI transfer structure, see #flexio_spi_transfer_t. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_FLEXIO_SPI_Timeout The transfer timed out and was aborted. - */ -status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_transfer_t *xfer) -{ - flexio_spi_shift_direction_t direction; - uint8_t bytesPerFrame; - uint32_t dataMode = 0; - uint16_t timerCmp = (uint16_t)(base->flexioBase->TIMCMP[base->timerIndex[0]]); - uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; -#if SPI_RETRY_TIMES - uint32_t waitTimes; -#endif - - timerCmp &= 0x00FFU; - /* Configure the values in handle. */ - switch (xfer->flags) - { - case (uint8_t)kFLEXIO_SPI_8bitMsb: - dataMode = (8UL * 2UL - 1UL) << 8U; - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_MsbFirst; - break; - - case (uint8_t)kFLEXIO_SPI_8bitLsb: - dataMode = (8UL * 2UL - 1UL) << 8U; - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_LsbFirst; - break; - - case (uint8_t)kFLEXIO_SPI_16bitMsb: - dataMode = (16UL * 2UL - 1UL) << 8U; - bytesPerFrame = 2U; - direction = kFLEXIO_SPI_MsbFirst; - break; - - case (uint8_t)kFLEXIO_SPI_16bitLsb: - dataMode = (16UL * 2UL - 1UL) << 8U; - bytesPerFrame = 2U; - direction = kFLEXIO_SPI_LsbFirst; - break; - - default: - dataMode = (8UL * 2UL - 1UL) << 8U; - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_MsbFirst; - assert(true); - break; - } - - dataMode |= timerCmp; - - /* Configure transfer size. */ - base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; - - while (xfer->dataSize != 0U) - { - /* Wait until data transfer complete. */ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag)) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_FLEXIO_SPI_Timeout; - } -#endif - if (xfer->txData != NULL) - { - /* Transmit data and update tx size/buff. */ - if (bytesPerFrame == 1U) - { - tmpData = *(xfer->txData); - xfer->txData++; - } - else - { - if (direction == kFLEXIO_SPI_MsbFirst) - { - tmpData = (uint16_t)(xfer->txData[0]) << 8U; - tmpData += xfer->txData[1]; - } - else - { - tmpData = (uint16_t)(xfer->txData[1]) << 8U; - tmpData += xfer->txData[0]; - } - xfer->txData += 2U; - } - } - else - { - tmpData = FLEXIO_SPI_DUMMYDATA; - } - - xfer->dataSize -= bytesPerFrame; - - FLEXIO_SPI_WriteData(base, direction, tmpData); - -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_SPI_GetStatusFlags(base) & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag)) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_FLEXIO_SPI_Timeout; - } -#endif - tmpData = FLEXIO_SPI_ReadData(base, direction); - - if (xfer->rxData != NULL) - { - if (bytesPerFrame == 1U) - { - *xfer->rxData = (uint8_t)tmpData; - xfer->rxData++; - } - else - { - if (direction == kFLEXIO_SPI_MsbFirst) - { - *xfer->rxData = (uint8_t)(tmpData >> 8); - xfer->rxData++; - *xfer->rxData = (uint8_t)tmpData; - } - else - { - *xfer->rxData = (uint8_t)tmpData; - xfer->rxData++; - *xfer->rxData = (uint8_t)(tmpData >> 8); - } - xfer->rxData++; - } - } - } - - return kStatus_Success; -} - -/*! - * brief Initializes the FlexIO SPI Master handle, which is used in transactional functions. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. - * param callback The callback function. - * param userData The parameter of the callback function. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_SPI_MasterTransferCreateHandle(FLEXIO_SPI_Type *base, - flexio_spi_master_handle_t *handle, - flexio_spi_master_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Register callback and userData. */ - handle->callback = callback; - handle->userData = userData; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]); - - /* Save the context in global variables to support the double weak mechanism. */ - return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_MasterTransferHandleIRQ); -} - -/*! - * brief Master transfer data using IRQ. - * - * This function sends data using IRQ. This is a non-blocking function, which returns - * right away. When all data is sent out/received, the callback function is called. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. - * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_SPI_Busy SPI is not idle, is running another transfer. - */ -status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base, - flexio_spi_master_handle_t *handle, - flexio_spi_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - uint32_t dataMode = 0; - uint16_t timerCmp = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]]; - uint16_t tmpData = FLEXIO_SPI_DUMMYDATA; - - timerCmp &= 0x00FFU; - - /* Check if SPI is busy. */ - if (handle->state == (uint32_t)kFLEXIO_SPI_Busy) - { - return kStatus_FLEXIO_SPI_Busy; - } - - /* Check if the argument is legal. */ - if ((xfer->txData == NULL) && (xfer->rxData == NULL)) - { - return kStatus_InvalidArgument; - } - - /* Configure the values in handle */ - switch (xfer->flags) - { - case (uint8_t)kFLEXIO_SPI_8bitMsb: - dataMode = (8UL * 2UL - 1UL) << 8U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_8bitLsb: - dataMode = (8UL * 2UL - 1UL) << 8U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_LsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitMsb: - dataMode = (16UL * 2UL - 1UL) << 8U; - handle->bytePerFrame = 2U; - handle->direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitLsb: - dataMode = (16UL * 2UL - 1UL) << 8U; - handle->bytePerFrame = 2U; - handle->direction = kFLEXIO_SPI_LsbFirst; - break; - default: - dataMode = (8UL * 2UL - 1UL) << 8U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_MsbFirst; - assert(true); - break; - } - - dataMode |= timerCmp; - - /* Configure transfer size. */ - base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; - - handle->state = (uint32_t)kFLEXIO_SPI_Busy; - handle->txData = xfer->txData; - handle->rxData = xfer->rxData; - handle->rxRemainingBytes = xfer->dataSize; - - /* Save total transfer size. */ - handle->transferSize = xfer->dataSize; - - /* Send first byte of data to trigger the rx interrupt. */ - if (handle->txData != NULL) - { - /* Transmit data and update tx size/buff. */ - if (handle->bytePerFrame == 1U) - { - tmpData = *(handle->txData); - handle->txData++; - } - else - { - if (handle->direction == kFLEXIO_SPI_MsbFirst) - { - tmpData = (uint16_t)(handle->txData[0]) << 8U; - tmpData += handle->txData[1]; - } - else - { - tmpData = (uint16_t)(handle->txData[1]) << 8U; - tmpData += handle->txData[0]; - } - handle->txData += 2U; - } - } - else - { - tmpData = FLEXIO_SPI_DUMMYDATA; - } - - handle->txRemainingBytes = xfer->dataSize - handle->bytePerFrame; - - FLEXIO_SPI_WriteData(base, handle->direction, tmpData); - - /* Enable transmit and receive interrupt to handle rx. */ - FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable); - - return kStatus_Success; -} - -/*! - * brief Gets the data transfer status which used IRQ. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. - * param count Number of bytes transferred so far by the non-blocking transaction. - * retval kStatus_InvalidArgument count is Invalid. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_SPI_MasterTransferGetCount(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Return remaing bytes in different cases. */ - if (handle->rxData != NULL) - { - *count = handle->transferSize - handle->rxRemainingBytes; - } - else - { - *count = handle->transferSize - handle->txRemainingBytes; - } - - return kStatus_Success; -} - -/*! - * brief Aborts the master data transfer, which used IRQ. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param handle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. - */ -void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_handle_t *handle) -{ - assert(handle != NULL); - - FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable); - FLEXIO_SPI_DisableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable); - - /* Transfer finished, set the state to idle. */ - handle->state = (uint32_t)kFLEXIO_SPI_Idle; - - /* Clear the internal state. */ - handle->rxRemainingBytes = 0; - handle->txRemainingBytes = 0; -} - -/*! - * brief FlexIO SPI master IRQ handler function. - * - * param spiType Pointer to the FLEXIO_SPI_Type structure. - * param spiHandle Pointer to the flexio_spi_master_handle_t structure to store the transfer state. - */ -void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle) -{ - assert(spiHandle != NULL); - - flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; - FLEXIO_SPI_Type *base; - uint32_t status; - - if (handle->state == (uint32_t)kFLEXIO_SPI_Idle) - { - return; - } - - base = (FLEXIO_SPI_Type *)spiType; - status = FLEXIO_SPI_GetStatusFlags(base); - - /* Handle rx. */ - if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U)) - { - FLEXIO_SPI_TransferReceiveTransaction(base, handle); - } - - /* Handle tx. */ - if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U)) - { - FLEXIO_SPI_TransferSendTransaction(base, handle); - } - - /* All the transfer finished. */ - if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) - { - FLEXIO_SPI_MasterTransferAbort(base, handle); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); - } - } -} - -/*! - * brief Initializes the FlexIO SPI Slave handle, which is used in transactional functions. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. - * param callback The callback function. - * param userData The parameter of the callback function. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_SPI_SlaveTransferCreateHandle(FLEXIO_SPI_Type *base, - flexio_spi_slave_handle_t *handle, - flexio_spi_slave_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Register callback and userData. */ - handle->callback = callback; - handle->userData = userData; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_SPI_GetInstance(base)]); - - /* Save the context in global variables to support the double weak mechanism. */ - return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_SPI_SlaveTransferHandleIRQ); -} - -/*! - * brief Slave transfer data using IRQ. - * - * This function sends data using IRQ. This is a non-blocking function, which returns - * right away. When all data is sent out/received, the callback function is called. - * param handle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. - * - * param base Pointer to the FLEXIO_SPI_Type structure. - * param xfer FlexIO SPI transfer structure. See #flexio_spi_transfer_t. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_SPI_Busy SPI is not idle; it is running another transfer. - */ -status_t FLEXIO_SPI_SlaveTransferNonBlocking(FLEXIO_SPI_Type *base, - flexio_spi_slave_handle_t *handle, - flexio_spi_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - uint32_t dataMode = 0; - - /* Check if SPI is busy. */ - if (handle->state == (uint32_t)kFLEXIO_SPI_Busy) - { - return kStatus_FLEXIO_SPI_Busy; - } - - /* Check if the argument is legal. */ - if ((xfer->txData == NULL) && (xfer->rxData == NULL)) - { - return kStatus_InvalidArgument; - } - - /* Configure the values in handle */ - switch (xfer->flags) - { - case (uint8_t)kFLEXIO_SPI_8bitMsb: - dataMode = 8U * 2U - 1U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_8bitLsb: - dataMode = 8U * 2U - 1U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_LsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitMsb: - dataMode = 16U * 2U - 1U; - handle->bytePerFrame = 2U; - handle->direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitLsb: - dataMode = 16U * 2U - 1U; - handle->bytePerFrame = 2U; - handle->direction = kFLEXIO_SPI_LsbFirst; - break; - default: - dataMode = 8U * 2U - 1U; - handle->bytePerFrame = 1U; - handle->direction = kFLEXIO_SPI_MsbFirst; - assert(true); - break; - } - - /* Configure transfer size. */ - base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; - - handle->state = (uint32_t)kFLEXIO_SPI_Busy; - handle->txData = xfer->txData; - handle->rxData = xfer->rxData; - handle->txRemainingBytes = xfer->dataSize; - handle->rxRemainingBytes = xfer->dataSize; - - /* Save total transfer size. */ - handle->transferSize = xfer->dataSize; - - /* Enable transmit and receive interrupt to handle tx and rx. */ - FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_TxEmptyInterruptEnable); - FLEXIO_SPI_EnableInterrupts(base, (uint32_t)kFLEXIO_SPI_RxFullInterruptEnable); - - return kStatus_Success; -} - -/*! - * brief FlexIO SPI slave IRQ handler function. - * - * param spiType Pointer to the FLEXIO_SPI_Type structure. - * param spiHandle Pointer to the flexio_spi_slave_handle_t structure to store the transfer state. - */ -void FLEXIO_SPI_SlaveTransferHandleIRQ(void *spiType, void *spiHandle) -{ - assert(spiHandle != NULL); - - flexio_spi_master_handle_t *handle = (flexio_spi_master_handle_t *)spiHandle; - FLEXIO_SPI_Type *base; - uint32_t status; - - if (handle->state == (uint32_t)kFLEXIO_SPI_Idle) - { - return; - } - - base = (FLEXIO_SPI_Type *)spiType; - status = FLEXIO_SPI_GetStatusFlags(base); - - /* Handle tx. */ - if (((status & (uint32_t)kFLEXIO_SPI_TxBufferEmptyFlag) != 0U) && (handle->txRemainingBytes != 0U)) - { - FLEXIO_SPI_TransferSendTransaction(base, handle); - } - - /* Handle rx. */ - if (((status & (uint32_t)kFLEXIO_SPI_RxBufferFullFlag) != 0U) && (handle->rxRemainingBytes != 0U)) - { - FLEXIO_SPI_TransferReceiveTransaction(base, handle); - } - - /* All the transfer finished. */ - if ((handle->txRemainingBytes == 0U) && (handle->rxRemainingBytes == 0U)) - { - FLEXIO_SPI_SlaveTransferAbort(base, handle); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_FLEXIO_SPI_Idle, handle->userData); - } - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi_edma.c deleted file mode 100644 index 3adf92d4df..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_spi_edma.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_spi_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_spi_edma" -#endif - -/*<! Structure definition for spi_edma_private_handle_t. The structure is private. */ -typedef struct _flexio_spi_master_edma_private_handle -{ - FLEXIO_SPI_Type *base; - flexio_spi_master_edma_handle_t *handle; -} flexio_spi_master_edma_private_handle_t; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief EDMA callback function for FLEXIO SPI send transfer. - * - * @param handle EDMA handle pointer. - * @param param Callback function parameter. - */ -static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief EDMA callback function for FLEXIO SPI receive transfer. - * - * @param handle EDMA handle pointer. - * @param param Callback function parameter. - */ -static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief EDMA config for FLEXIO SPI transfer. - * - * @param base pointer to FLEXIO_SPI_Type structure. - * @param handle pointer to flexio_spi_master_edma_handle_t structure to store the transfer state. - * @param xfer Pointer to flexio spi transfer structure. - */ -static void FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base, - flexio_spi_master_edma_handle_t *handle, - flexio_spi_transfer_t *xfer); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Dummy data used to send */ -static const uint16_t s_dummyData = FLEXIO_SPI_DUMMYDATA; - -/*< @brief user configurable flexio spi handle count. */ -#define FLEXIO_SPI_HANDLE_COUNT 2 - -/*<! Private handle only used for internally. */ -static flexio_spi_master_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT]; - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void FLEXIO_SPI_TxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) -{ - tcds = tcds; - flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param; - - /* Disable Tx DMA */ - if (transferDone) - { - FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, false); - - /* change the state */ - spiPrivateHandle->handle->txInProgress = false; - - /* All finished, call the callback */ - if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) - { - if (spiPrivateHandle->handle->callback != NULL) - { - (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, - spiPrivateHandle->handle->userData); - } - } - } -} - -static void FLEXIO_SPI_RxEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) -{ - tcds = tcds; - flexio_spi_master_edma_private_handle_t *spiPrivateHandle = (flexio_spi_master_edma_private_handle_t *)param; - - if (transferDone) - { - /* Disable Rx dma */ - FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, false); - - /* change the state */ - spiPrivateHandle->handle->rxInProgress = false; - - /* All finished, call the callback */ - if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) - { - if (spiPrivateHandle->handle->callback != NULL) - { - (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, - spiPrivateHandle->handle->userData); - } - } - } -} - -static void FLEXIO_SPI_EDMAConfig(FLEXIO_SPI_Type *base, - flexio_spi_master_edma_handle_t *handle, - flexio_spi_transfer_t *xfer) -{ - edma_transfer_config_t xferConfig = {0}; - flexio_spi_shift_direction_t direction = kFLEXIO_SPI_MsbFirst; - uint8_t bytesPerFrame; - - /* Configure the values in handle. */ - switch (xfer->flags) - { - case (uint8_t)kFLEXIO_SPI_8bitMsb: - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_8bitLsb: - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_LsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitMsb: - bytesPerFrame = 2U; - direction = kFLEXIO_SPI_MsbFirst; - break; - case (uint8_t)kFLEXIO_SPI_16bitLsb: - bytesPerFrame = 2U; - direction = kFLEXIO_SPI_LsbFirst; - break; - default: - bytesPerFrame = 1U; - direction = kFLEXIO_SPI_MsbFirst; - assert(true); - break; - } - - /* Save total transfer size. */ - handle->transferSize = xfer->dataSize; - - /* Configure tx transfer EDMA. */ - xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction); - xferConfig.destOffset = 0; - if (bytesPerFrame == 1U) - { - xferConfig.srcTransferSize = kEDMA_TransferSize1Bytes; - xferConfig.destTransferSize = kEDMA_TransferSize1Bytes; - xferConfig.minorLoopBytes = 1U; - } - else - { - if (direction == kFLEXIO_SPI_MsbFirst) - { - xferConfig.destAddr -= 1U; - } - xferConfig.srcTransferSize = kEDMA_TransferSize2Bytes; - xferConfig.destTransferSize = kEDMA_TransferSize2Bytes; - xferConfig.minorLoopBytes = 2U; - } - - /* Configure DMA channel. */ - if (xfer->txData != NULL) - { - xferConfig.srcOffset = (int16_t)bytesPerFrame; - xferConfig.srcAddr = (uint32_t)(xfer->txData); - } - else - { - /* Disable the source increasement and source set to dummyData. */ - xferConfig.srcOffset = 0; - xferConfig.srcAddr = (uint32_t)(&s_dummyData); - } - - xferConfig.majorLoopCounts = (xfer->dataSize / xferConfig.minorLoopBytes); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO SPI handle */ - handle->nbytes = (uint8_t)xferConfig.minorLoopBytes; - - if (handle->txHandle != NULL) - { - (void)EDMA_SubmitTransfer(handle->txHandle, &xferConfig); - } - - /* Configure rx transfer EDMA. */ - if (xfer->rxData != NULL) - { - xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction); - if (bytesPerFrame == 2U) - { - if (direction == kFLEXIO_SPI_LsbFirst) - { - xferConfig.srcAddr -= 1U; - } - } - xferConfig.srcOffset = 0; - xferConfig.destAddr = (uint32_t)(xfer->rxData); - xferConfig.destOffset = (int16_t)bytesPerFrame; - (void)EDMA_SubmitTransfer(handle->rxHandle, &xferConfig); - handle->rxInProgress = true; - FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_RxDmaEnable, true); - EDMA_StartTransfer(handle->rxHandle); - } - - /* Always start tx transfer. */ - if (handle->txHandle != NULL) - { - handle->txInProgress = true; - FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_TxDmaEnable, true); - EDMA_StartTransfer(handle->txHandle); - } -} - -/*! - * brief Initializes the FlexIO SPI master eDMA handle. - * - * This function initializes the FlexIO SPI master eDMA handle which can be used for other FlexIO SPI master - * transactional - * APIs. - * For a specified FlexIO SPI instance, call this API once to get the initialized handle. - * - * param base Pointer to FLEXIO_SPI_Type structure. - * param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state. - * param callback SPI callback, NULL means no callback. - * param userData callback function parameter. - * param txHandle User requested eDMA handle for FlexIO SPI RX eDMA transfer. - * param rxHandle User requested eDMA handle for FlexIO SPI TX eDMA transfer. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range. - */ -status_t FLEXIO_SPI_MasterTransferCreateHandleEDMA(FLEXIO_SPI_Type *base, - flexio_spi_master_edma_handle_t *handle, - flexio_spi_master_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txHandle, - edma_handle_t *rxHandle) -{ - assert(handle != NULL); - - uint8_t index = 0; - - /* Find the an empty handle pointer to store the handle. */ - for (index = 0U; index < (uint8_t)FLEXIO_SPI_HANDLE_COUNT; index++) - { - if (s_edmaPrivateHandle[index].base == NULL) - { - s_edmaPrivateHandle[index].base = base; - s_edmaPrivateHandle[index].handle = handle; - break; - } - } - - if (index == (uint16_t)FLEXIO_SPI_HANDLE_COUNT) - { - return kStatus_OutOfRange; - } - - /* Set spi base to handle. */ - handle->txHandle = txHandle; - handle->rxHandle = rxHandle; - - /* Register callback and userData. */ - handle->callback = callback; - handle->userData = userData; - - /* Set SPI state to idle. */ - handle->txInProgress = false; - handle->rxInProgress = false; - - /* Install callback for Tx/Rx dma channel. */ - if (handle->txHandle != NULL) - { - EDMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxEDMACallback, &s_edmaPrivateHandle[index]); - } - if (handle->rxHandle != NULL) - { - EDMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxEDMACallback, &s_edmaPrivateHandle[index]); - } - - return kStatus_Success; -} - -/*! - * brief Performs a non-blocking FlexIO SPI transfer using eDMA. - * - * note This interface returns immediately after transfer initiates. Call - * FLEXIO_SPI_MasterGetTransferCountEDMA to poll the transfer status and check - * whether the FlexIO SPI transfer is finished. - * - * param base Pointer to FLEXIO_SPI_Type structure. - * param handle Pointer to flexio_spi_master_edma_handle_t structure to store the transfer state. - * param xfer Pointer to FlexIO SPI transfer structure. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. - */ -status_t FLEXIO_SPI_MasterTransferEDMA(FLEXIO_SPI_Type *base, - flexio_spi_master_edma_handle_t *handle, - flexio_spi_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - uint32_t dataMode = 0; - uint16_t timerCmp = (uint16_t)base->flexioBase->TIMCMP[base->timerIndex[0]]; - - timerCmp &= 0x00FFU; - - /* Check if the device is busy. */ - if ((handle->txInProgress) || (handle->rxInProgress)) - { - return kStatus_FLEXIO_SPI_Busy; - } - - /* Check if input parameter invalid. */ - if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - /* configure data mode. */ - if ((xfer->flags == (uint8_t)kFLEXIO_SPI_8bitMsb) || (xfer->flags == (uint8_t)kFLEXIO_SPI_8bitLsb)) - { - dataMode = (8UL * 2UL - 1UL) << 8U; - } - else if ((xfer->flags == (uint8_t)kFLEXIO_SPI_16bitMsb) || (xfer->flags == (uint8_t)kFLEXIO_SPI_16bitLsb)) - { - dataMode = (16UL * 2UL - 1UL) << 8U; - } - else - { - dataMode = 8UL * 2UL - 1UL; - } - - dataMode |= timerCmp; - - base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; - - FLEXIO_SPI_EDMAConfig(base, handle, xfer); - - return kStatus_Success; -} - -/*! - * brief Gets the remaining bytes for FlexIO SPI eDMA transfer. - * - * param base Pointer to FLEXIO_SPI_Type structure. - * param handle FlexIO SPI eDMA handle pointer. - * param count Number of bytes transferred so far by the non-blocking transaction. - */ -status_t FLEXIO_SPI_MasterTransferGetCountEDMA(FLEXIO_SPI_Type *base, - flexio_spi_master_edma_handle_t *handle, - size_t *count) -{ - assert(handle != NULL); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - if (handle->rxInProgress) - { - *count = - (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount( - handle->rxHandle->base, handle->rxHandle->channel)); - } - else - { - *count = - (handle->transferSize - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount( - handle->txHandle->base, handle->txHandle->channel)); - } - - return kStatus_Success; -} - -/*! - * brief Aborts a FlexIO SPI transfer using eDMA. - * - * param base Pointer to FLEXIO_SPI_Type structure. - * param handle FlexIO SPI eDMA handle pointer. - */ -void FLEXIO_SPI_MasterTransferAbortEDMA(FLEXIO_SPI_Type *base, flexio_spi_master_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma. */ - EDMA_StopTransfer(handle->txHandle); - EDMA_StopTransfer(handle->rxHandle); - - /* Disable DMA enable bit. */ - FLEXIO_SPI_EnableDMA(base, (uint32_t)kFLEXIO_SPI_DmaAllEnable, false); - - /* Set the handle state. */ - handle->txInProgress = false; - handle->rxInProgress = false; -} - -/*! - * brief Performs a non-blocking FlexIO SPI transfer using eDMA. - * - * note This interface returns immediately after transfer initiates. Call - * FLEXIO_SPI_SlaveGetTransferCountEDMA to poll the transfer status and - * check whether the FlexIO SPI transfer is finished. - * - * param base Pointer to FLEXIO_SPI_Type structure. - * param handle Pointer to flexio_spi_slave_edma_handle_t structure to store the transfer state. - * param xfer Pointer to FlexIO SPI transfer structure. - * retval kStatus_Success Successfully start a transfer. - * retval kStatus_InvalidArgument Input argument is invalid. - * retval kStatus_FLEXIO_SPI_Busy FlexIO SPI is not idle, is running another transfer. - */ -status_t FLEXIO_SPI_SlaveTransferEDMA(FLEXIO_SPI_Type *base, - flexio_spi_slave_edma_handle_t *handle, - flexio_spi_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - uint32_t dataMode = 0U; - - /* Check if the device is busy. */ - if ((handle->txInProgress) || (handle->rxInProgress)) - { - return kStatus_FLEXIO_SPI_Busy; - } - - /* Check if input parameter invalid. */ - if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - /* configure data mode. */ - if ((xfer->flags == (uint8_t)kFLEXIO_SPI_8bitMsb) || (xfer->flags == (uint8_t)kFLEXIO_SPI_8bitLsb)) - { - dataMode = 8U * 2U - 1U; - } - else if ((xfer->flags == (uint8_t)kFLEXIO_SPI_16bitMsb) || (xfer->flags == (uint8_t)kFLEXIO_SPI_16bitLsb)) - { - dataMode = 16U * 2U - 1U; - } - else - { - dataMode = 8U * 2U - 1U; - } - - base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; - - FLEXIO_SPI_EDMAConfig(base, handle, xfer); - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart.c deleted file mode 100644 index 6e524470b8..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart.c +++ /dev/null @@ -1,991 +0,0 @@ -/* - * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_uart.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_uart" -#endif - -/*<! @brief uart transfer state. */ -enum _flexio_uart_transfer_states -{ - kFLEXIO_UART_TxIdle, /* TX idle. */ - kFLEXIO_UART_TxBusy, /* TX busy. */ - kFLEXIO_UART_RxIdle, /* RX idle. */ - kFLEXIO_UART_RxBusy /* RX busy. */ -}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get the length of received data in RX ring buffer. - * - * @param handle FLEXIO UART handle pointer. - * @return Length of received data in RX ring buffer. - */ -static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle); - -/*! - * @brief Check whether the RX ring buffer is full. - * - * @param handle FLEXIO UART handle pointer. - * @retval true RX ring buffer is full. - * @retval false RX ring buffer is not full. - */ -static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle); - -/******************************************************************************* - * Codes - ******************************************************************************/ - -static uint32_t FLEXIO_UART_GetInstance(FLEXIO_UART_Type *base) -{ - return FLEXIO_GetInstance(base->flexioBase); -} - -static size_t FLEXIO_UART_TransferGetRxRingBufferLength(flexio_uart_handle_t *handle) -{ - size_t size; - uint16_t rxRingBufferHead = handle->rxRingBufferHead; - uint16_t rxRingBufferTail = handle->rxRingBufferTail; - - if (rxRingBufferTail > rxRingBufferHead) - { - size = (size_t)rxRingBufferHead + handle->rxRingBufferSize - (size_t)rxRingBufferTail; - } - else - { - size = (size_t)rxRingBufferHead - (size_t)rxRingBufferTail; - } - - return size; -} - -static bool FLEXIO_UART_TransferIsRxRingBufferFull(flexio_uart_handle_t *handle) -{ - bool full; - - if (FLEXIO_UART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) - { - full = true; - } - else - { - full = false; - } - - return full; -} - -/*! - * brief Ungates the FlexIO clock, resets the FlexIO module, configures FlexIO UART - * hardware, and configures the FlexIO UART with FlexIO UART configuration. - * The configuration structure can be filled by the user or be set with - * default values by FLEXIO_UART_GetDefaultConfig(). - * - * Example - code - FLEXIO_UART_Type base = { - .flexioBase = FLEXIO, - .TxPinIndex = 0, - .RxPinIndex = 1, - .shifterIndex = {0,1}, - .timerIndex = {0,1} - }; - flexio_uart_config_t config = { - .enableInDoze = false, - .enableInDebug = true, - .enableFastAccess = false, - .baudRate_Bps = 115200U, - .bitCountPerChar = 8 - }; - FLEXIO_UART_Init(base, &config, srcClock_Hz); - endcode - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param userConfig Pointer to the flexio_uart_config_t structure. - * param srcClock_Hz FlexIO source clock in Hz. - * retval kStatus_Success Configuration success - * retval kStatus_InvalidArgument Buadrate configuration out of range -*/ -status_t FLEXIO_UART_Init(FLEXIO_UART_Type *base, const flexio_uart_config_t *userConfig, uint32_t srcClock_Hz) -{ - assert((base != NULL) && (userConfig != NULL)); - - flexio_shifter_config_t shifterConfig; - flexio_timer_config_t timerConfig; - uint32_t ctrlReg = 0; - uint16_t timerDiv = 0; - uint16_t timerCmp = 0; - status_t result = kStatus_Success; - - /* Clear the shifterConfig & timerConfig struct. */ - (void)memset(&shifterConfig, 0, sizeof(shifterConfig)); - (void)memset(&timerConfig, 0, sizeof(timerConfig)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate flexio clock. */ - CLOCK_EnableClock(s_flexioClocks[FLEXIO_UART_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Configure FLEXIO UART */ - ctrlReg = base->flexioBase->CTRL; - ctrlReg &= ~(FLEXIO_CTRL_DOZEN_MASK | FLEXIO_CTRL_DBGE_MASK | FLEXIO_CTRL_FASTACC_MASK | FLEXIO_CTRL_FLEXEN_MASK); - ctrlReg |= (FLEXIO_CTRL_DBGE(userConfig->enableInDebug) | FLEXIO_CTRL_FASTACC(userConfig->enableFastAccess) | - FLEXIO_CTRL_FLEXEN(userConfig->enableUart)); - if (!userConfig->enableInDoze) - { - ctrlReg |= FLEXIO_CTRL_DOZEN_MASK; - } - - base->flexioBase->CTRL = ctrlReg; - - /* Do hardware configuration. */ - /* 1. Configure the shifter 0 for tx. */ - shifterConfig.timerSelect = base->timerIndex[0]; - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnPositive; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutput; - shifterConfig.pinSelect = base->TxPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeTransmit; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[0], &shifterConfig); - - /*2. Configure the timer 0 for tx. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_SHIFTnSTAT(base->shifterIndex[0]); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveLow; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceInternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->TxPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveHigh; - timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetNever; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnTriggerHigh; - timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - - timerDiv = (uint16_t)(srcClock_Hz / userConfig->baudRate_Bps); - timerDiv = timerDiv / 2U - 1U; - - if (timerDiv > 0xFFU) - { - result = kStatus_InvalidArgument; - } - - timerCmp = ((uint16_t)userConfig->bitCountPerChar * 2U - 1U) << 8U; - timerCmp |= timerDiv; - - timerConfig.timerCompare = timerCmp; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[0], &timerConfig); - - /* 3. Configure the shifter 1 for rx. */ - shifterConfig.timerSelect = base->timerIndex[1]; - shifterConfig.timerPolarity = kFLEXIO_ShifterTimerPolarityOnNegitive; - shifterConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - shifterConfig.pinSelect = base->RxPinIndex; - shifterConfig.pinPolarity = kFLEXIO_PinActiveHigh; - shifterConfig.shifterMode = kFLEXIO_ShifterModeReceive; - shifterConfig.inputSource = kFLEXIO_ShifterInputFromPin; - shifterConfig.shifterStop = kFLEXIO_ShifterStopBitHigh; - shifterConfig.shifterStart = kFLEXIO_ShifterStartBitLow; - - FLEXIO_SetShifterConfig(base->flexioBase, base->shifterIndex[1], &shifterConfig); - - /* 4. Configure the timer 1 for rx. */ - timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(base->RxPinIndex); - timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; - timerConfig.triggerSource = kFLEXIO_TimerTriggerSourceExternal; - timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled; - timerConfig.pinSelect = base->RxPinIndex; - timerConfig.pinPolarity = kFLEXIO_PinActiveLow; - timerConfig.timerMode = kFLEXIO_TimerModeDual8BitBaudBit; - timerConfig.timerOutput = kFLEXIO_TimerOutputOneAffectedByReset; - timerConfig.timerDecrement = kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput; - timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge; - timerConfig.timerDisable = kFLEXIO_TimerDisableOnTimerCompare; - timerConfig.timerEnable = kFLEXIO_TimerEnableOnPinRisingEdge; - timerConfig.timerStop = kFLEXIO_TimerStopBitEnableOnTimerDisable; - timerConfig.timerStart = kFLEXIO_TimerStartBitEnabled; - - timerConfig.timerCompare = timerCmp; - - FLEXIO_SetTimerConfig(base->flexioBase, base->timerIndex[1], &timerConfig); - - return result; -} - -/*! - * brief Resets the FlexIO UART shifter and timer config. - * - * note After calling this API, call the FLEXO_UART_Init to use the FlexIO UART module. - * - * param base Pointer to FLEXIO_UART_Type structure - */ -void FLEXIO_UART_Deinit(FLEXIO_UART_Type *base) -{ - base->flexioBase->SHIFTCFG[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[0]] = 0; - base->flexioBase->SHIFTCFG[base->shifterIndex[1]] = 0; - base->flexioBase->SHIFTCTL[base->shifterIndex[1]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[0]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[0]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[0]] = 0; - base->flexioBase->TIMCFG[base->timerIndex[1]] = 0; - base->flexioBase->TIMCMP[base->timerIndex[1]] = 0; - base->flexioBase->TIMCTL[base->timerIndex[1]] = 0; - /* Clear the shifter flag. */ - base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[0]); - base->flexioBase->SHIFTSTAT = (1UL << base->shifterIndex[1]); - /* Clear the timer flag. */ - base->flexioBase->TIMSTAT = (1UL << base->timerIndex[0]); - base->flexioBase->TIMSTAT = (1UL << base->timerIndex[1]); -} - -/*! - * brief Gets the default configuration to configure the FlexIO UART. The configuration - * can be used directly for calling the FLEXIO_UART_Init(). - * Example: - code - flexio_uart_config_t config; - FLEXIO_UART_GetDefaultConfig(&userConfig); - endcode - * param userConfig Pointer to the flexio_uart_config_t structure. -*/ -void FLEXIO_UART_GetDefaultConfig(flexio_uart_config_t *userConfig) -{ - assert(userConfig != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(userConfig, 0, sizeof(*userConfig)); - - userConfig->enableUart = true; - userConfig->enableInDoze = false; - userConfig->enableInDebug = true; - userConfig->enableFastAccess = false; - /* Default baud rate 115200. */ - userConfig->baudRate_Bps = 115200U; - /* Default bit count at 8. */ - userConfig->bitCountPerChar = kFLEXIO_UART_8BitsPerChar; -} - -/*! - * brief Enables the FlexIO UART interrupt. - * - * This function enables the FlexIO UART interrupt. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param mask Interrupt source. - */ -void FLEXIO_UART_EnableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_UART_TxDataRegEmptyInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable) != 0U) - { - FLEXIO_EnableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Disables the FlexIO UART interrupt. - * - * This function disables the FlexIO UART interrupt. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param mask Interrupt source. - */ -void FLEXIO_UART_DisableInterrupts(FLEXIO_UART_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_UART_TxDataRegEmptyInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable) != 0U) - { - FLEXIO_DisableShifterStatusInterrupts(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Gets the FlexIO UART status flags. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * return FlexIO UART status flags. - */ - -uint32_t FLEXIO_UART_GetStatusFlags(FLEXIO_UART_Type *base) -{ - uint32_t status = 0U; - status = - ((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0])) >> base->shifterIndex[0]); - status |= - (((FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) - << 1U); - status |= - (((FLEXIO_GetShifterErrorFlags(base->flexioBase) & (1UL << base->shifterIndex[1])) >> (base->shifterIndex[1])) - << 2U); - return status; -} - -/*! - * brief Gets the FlexIO UART status flags. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param mask Status flag. - * The parameter can be any combination of the following values: - * arg kFLEXIO_UART_TxDataRegEmptyFlag - * arg kFLEXIO_UART_RxEmptyFlag - * arg kFLEXIO_UART_RxOverRunFlag - */ - -void FLEXIO_UART_ClearStatusFlags(FLEXIO_UART_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kFLEXIO_UART_TxDataRegEmptyFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[0]); - } - if ((mask & (uint32_t)kFLEXIO_UART_RxDataRegFullFlag) != 0U) - { - FLEXIO_ClearShifterStatusFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - } - if ((mask & (uint32_t)kFLEXIO_UART_RxOverRunFlag) != 0U) - { - FLEXIO_ClearShifterErrorFlags(base->flexioBase, 1UL << base->shifterIndex[1]); - } -} - -/*! - * brief Sends a buffer of data bytes. - * - * note This function blocks using the polling method until all bytes have been sent. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param txData The data bytes to send. - * param txSize The number of data bytes to send. - * retval kStatus_FLEXIO_UART_Timeout Transmission timed out and was aborted. - * retval kStatus_Success Successfully wrote all data. - */ -status_t FLEXIO_UART_WriteBlocking(FLEXIO_UART_Type *base, const uint8_t *txData, size_t txSize) -{ - assert(txData != NULL); - assert(txSize != 0U); -#if UART_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != txSize--) - { - /* Wait until data transfer complete. */ -#if UART_RETRY_TIMES - waitTimes = UART_RETRY_TIMES; - while ((0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_GetShifterStatusFlags(base->flexioBase) & (1UL << base->shifterIndex[0]))) -#endif - { - } -#if UART_RETRY_TIMES - if (0U == waitTimes) - { - return kStatus_FLEXIO_UART_Timeout; - } -#endif - - base->flexioBase->SHIFTBUF[base->shifterIndex[0]] = *txData++; - } - return kStatus_Success; -} - -/*! - * brief Receives a buffer of bytes. - * - * note This function blocks using the polling method until all bytes have been received. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param rxData The buffer to store the received bytes. - * param rxSize The number of data bytes to be received. - * retval kStatus_FLEXIO_UART_Timeout Transmission timed out and was aborted. - * retval kStatus_Success Successfully received all data. - */ -status_t FLEXIO_UART_ReadBlocking(FLEXIO_UART_Type *base, uint8_t *rxData, size_t rxSize) -{ - assert(rxData != NULL); - assert(rxSize != 0U); -#if UART_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != rxSize--) - { - /* Wait until data transfer complete. */ -#if UART_RETRY_TIMES - waitTimes = UART_RETRY_TIMES; - while ((0U == (FLEXIO_UART_GetStatusFlags(base) & (uint32_t)kFLEXIO_UART_RxDataRegFullFlag)) && - (0U != --waitTimes)) -#else - while (0U == (FLEXIO_UART_GetStatusFlags(base) & (uint32_t)kFLEXIO_UART_RxDataRegFullFlag)) -#endif - { - } -#if UART_RETRY_TIMES - if (0U == waitTimes) - { - return kStatus_FLEXIO_UART_Timeout; - } -#endif - - *rxData++ = (uint8_t)(base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]); - } - return kStatus_Success; -} - -/*! - * brief Initializes the UART handle. - * - * This function initializes the FlexIO UART handle, which can be used for other FlexIO - * UART transactional APIs. Call this API once to get the - * initialized handle. - * - * The UART driver supports the "background" receiving, which means that users can set up - * a RX ring buffer optionally. Data received is stored into the ring buffer even when - * the user doesn't call the FLEXIO_UART_TransferReceiveNonBlocking() API. If there is already data - * received in the ring buffer, users can get the received data from the ring buffer - * directly. The ring buffer is disabled if passing NULL as p ringBuffer. - * - * param base to FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param callback The callback function. - * param userData The parameter of the callback function. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO type/handle/ISR table out of range. - */ -status_t FLEXIO_UART_TransferCreateHandle(FLEXIO_UART_Type *base, - flexio_uart_handle_t *handle, - flexio_uart_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - IRQn_Type flexio_irqs[] = FLEXIO_IRQS; - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set the TX/RX state. */ - handle->rxState = (uint8_t)kFLEXIO_UART_RxIdle; - handle->txState = (uint8_t)kFLEXIO_UART_TxIdle; - - /* Set the callback and user data. */ - handle->callback = callback; - handle->userData = userData; - - /* Enable interrupt in NVIC. */ - (void)EnableIRQ(flexio_irqs[FLEXIO_UART_GetInstance(base)]); - - /* Save the context in global variables to support the double weak mechanism. */ - return FLEXIO_RegisterHandleIRQ(base, handle, FLEXIO_UART_TransferHandleIRQ); -} - -/*! - * brief Sets up the RX ring buffer. - * - * This function sets up the RX ring buffer to a specific UART handle. - * - * When the RX ring buffer is used, data received is stored into the ring buffer even when - * the user doesn't call the UART_ReceiveNonBlocking() API. If there is already data received - * in the ring buffer, users can get the received data from the ring buffer directly. - * - * note When using the RX ring buffer, one byte is reserved for internal use. In other - * words, if p ringBufferSize is 32, only 31 bytes are used for saving data. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. - * param ringBufferSize Size of the ring buffer. - */ -void FLEXIO_UART_TransferStartRingBuffer(FLEXIO_UART_Type *base, - flexio_uart_handle_t *handle, - uint8_t *ringBuffer, - size_t ringBufferSize) -{ - assert(handle != NULL); - - /* Setup the ringbuffer address */ - if (ringBuffer != NULL) - { - handle->rxRingBuffer = ringBuffer; - handle->rxRingBufferSize = ringBufferSize; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; - - /* Enable the interrupt to accept the data when user need the ring buffer. */ - FLEXIO_UART_EnableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - } -} - -/*! - * brief Aborts the background transfer and uninstalls the ring buffer. - * - * This function aborts the background transfer and uninstalls the ring buffer. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - */ -void FLEXIO_UART_TransferStopRingBuffer(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) -{ - assert(handle != NULL); - - if (handle->rxState == (uint8_t)kFLEXIO_UART_RxIdle) - { - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - } - - handle->rxRingBuffer = NULL; - handle->rxRingBufferSize = 0U; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; -} - -/*! - * brief Transmits a buffer of data using the interrupt method. - * - * This function sends data using an interrupt method. This is a non-blocking function, - * which returns directly without waiting for all data to be written to the TX register. When - * all data is written to the TX register in ISR, the FlexIO UART driver calls the callback - * function and passes the ref kStatus_FLEXIO_UART_TxIdle as status parameter. - * - * note The kStatus_FLEXIO_UART_TxIdle is passed to the upper layer when all data is written - * to the TX register. However, it does not ensure that all data is sent out. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param xfer FlexIO UART transfer structure. See #flexio_uart_transfer_t. - * retval kStatus_Success Successfully starts the data transmission. - * retval kStatus_UART_TxBusy Previous transmission still not finished, data not written to the TX register. - */ -status_t FLEXIO_UART_TransferSendNonBlocking(FLEXIO_UART_Type *base, - flexio_uart_handle_t *handle, - flexio_uart_transfer_t *xfer) -{ - status_t status; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - - /* Return error if current TX busy. */ - if ((uint8_t)kFLEXIO_UART_TxBusy == handle->txState) - { - status = kStatus_FLEXIO_UART_TxBusy; - } - else - { - handle->txData = xfer->data; - handle->txDataSize = xfer->dataSize; - handle->txDataSizeAll = xfer->dataSize; - handle->txState = (uint8_t)kFLEXIO_UART_TxBusy; - - /* Enable transmiter interrupt. */ - FLEXIO_UART_EnableInterrupts(base, (uint32_t)kFLEXIO_UART_TxDataRegEmptyInterruptEnable); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the interrupt-driven data transmit. - * - * This function aborts the interrupt-driven data sending. Get the remainBytes to find out - * how many bytes are still not sent out. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - */ -void FLEXIO_UART_TransferAbortSend(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) -{ - /* Disable the transmitter and disable the interrupt. */ - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_TxDataRegEmptyInterruptEnable); - - handle->txDataSize = 0U; - handle->txState = (uint8_t)kFLEXIO_UART_TxIdle; -} - -/*! - * brief Gets the number of bytes sent. - * - * This function gets the number of bytes sent driven by interrupt. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param count Number of bytes sent so far by the non-blocking transaction. - * retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_UART_TransferGetSendCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - assert(count != NULL); - - if ((uint8_t)kFLEXIO_UART_TxIdle == handle->txState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->txDataSizeAll - handle->txDataSize; - - return kStatus_Success; -} - -/*! - * brief Receives a buffer of data using the interrupt method. - * - * This function receives data using the interrupt method. This is a non-blocking function, - * which returns without waiting for all data to be received. - * If the RX ring buffer is used and not empty, the data in ring buffer is copied and - * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. - * After copying, if the data in ring buffer is not enough to read, the receive - * request is saved by the UART driver. When new data arrives, the receive request - * is serviced first. When all data is received, the UART driver notifies the upper layer - * through a callback function and passes the status parameter ref kStatus_UART_RxIdle. - * For example, if the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer, - * the 5 bytes are copied to xfer->data. This function returns with the - * parameter p receivedBytes set to 5. For the last 5 bytes, newly arrived data is - * saved from the xfer->data[5]. When 5 bytes are received, the UART driver notifies upper layer. - * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt - * to receive data to xfer->data. When all data is received, the upper layer is notified. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param xfer UART transfer structure. See #flexio_uart_transfer_t. - * param receivedBytes Bytes received from the ring buffer directly. - * retval kStatus_Success Successfully queue the transfer into the transmit queue. - * retval kStatus_FLEXIO_UART_RxBusy Previous receive request is not finished. - */ -status_t FLEXIO_UART_TransferReceiveNonBlocking(FLEXIO_UART_Type *base, - flexio_uart_handle_t *handle, - flexio_uart_transfer_t *xfer, - size_t *receivedBytes) -{ - uint32_t i; - status_t status; - /* How many bytes to copy from ring buffer to user memory. */ - size_t bytesToCopy = 0U; - /* How many bytes to receive. */ - size_t bytesToReceive; - /* How many bytes currently have received. */ - size_t bytesCurrentReceived; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - - /* How to get data: - 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize - to uart handle, enable interrupt to store received data to xfer->data. When - all data received, trigger callback. - 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. - If there are enough data in ring buffer, copy them to xfer->data and return. - If there are not enough data in ring buffer, copy all of them to xfer->data, - save the xfer->data remained empty space to uart handle, receive data - to this empty space and trigger callback when finished. */ - - if ((uint8_t)kFLEXIO_UART_RxBusy == handle->rxState) - { - status = kStatus_FLEXIO_UART_RxBusy; - } - else - { - bytesToReceive = xfer->dataSize; - bytesCurrentReceived = 0U; - - /* If RX ring buffer is used. */ - if (handle->rxRingBuffer != NULL) - { - /* Disable FLEXIO_UART RX IRQ, protect ring buffer. */ - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - - /* How many bytes in RX ring buffer currently. */ - bytesToCopy = FLEXIO_UART_TransferGetRxRingBufferLength(handle); - - if (bytesToCopy != 0U) - { - bytesToCopy = MIN(bytesToReceive, bytesToCopy); - - bytesToReceive -= bytesToCopy; - - /* Copy data from ring buffer to user memory. */ - for (i = 0U; i < bytesToCopy; i++) - { - xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; - - /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ - if ((uint32_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - } - - /* If ring buffer does not have enough data, still need to read more data. */ - if (bytesToReceive != 0U) - { - /* No data in ring buffer, save the request to UART handle. */ - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = (uint8_t)kFLEXIO_UART_RxBusy; - } - - /* Enable FLEXIO_UART RX IRQ if previously enabled. */ - FLEXIO_UART_EnableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - - /* Call user callback since all data are received. */ - if (0U == bytesToReceive) - { - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData); - } - } - } - /* Ring buffer not used. */ - else - { - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = (uint8_t)kFLEXIO_UART_RxBusy; - - /* Enable RX interrupt. */ - FLEXIO_UART_EnableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - } - - /* Return the how many bytes have read. */ - if (receivedBytes != NULL) - { - *receivedBytes = bytesCurrentReceived; - } - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the receive data which was using IRQ. - * - * This function aborts the receive data which was using IRQ. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - */ -void FLEXIO_UART_TransferAbortReceive(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle) -{ - /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ - if (NULL == handle->rxRingBuffer) - { - /* Disable RX interrupt. */ - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - } - - handle->rxDataSize = 0U; - handle->rxState = (uint8_t)kFLEXIO_UART_RxIdle; -} - -/*! - * brief Gets the number of bytes received. - * - * This function gets the number of bytes received driven by interrupt. - * - * param base Pointer to the FLEXIO_UART_Type structure. - * param handle Pointer to the flexio_uart_handle_t structure to store the transfer state. - * param count Number of bytes received so far by the non-blocking transaction. - * retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_UART_TransferGetReceiveCount(FLEXIO_UART_Type *base, flexio_uart_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - assert(count != NULL); - - if ((uint8_t)kFLEXIO_UART_RxIdle == handle->rxState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->rxDataSizeAll - handle->rxDataSize; - - return kStatus_Success; -} - -/*! - * brief FlexIO UART IRQ handler function. - * - * This function processes the FlexIO UART transmit and receives the IRQ request. - * - * param uartType Pointer to the FLEXIO_UART_Type structure. - * param uartHandle Pointer to the flexio_uart_handle_t structure to store the transfer state. - */ -void FLEXIO_UART_TransferHandleIRQ(void *uartType, void *uartHandle) -{ - uint8_t count = 1; - FLEXIO_UART_Type *base = (FLEXIO_UART_Type *)uartType; - flexio_uart_handle_t *handle = (flexio_uart_handle_t *)uartHandle; - uint16_t rxRingBufferHead; - - /* Read the status back. */ - uint32_t status = FLEXIO_UART_GetStatusFlags(base); - - /* If RX overrun. */ - if (((uint32_t)kFLEXIO_UART_RxOverRunFlag & status) != 0U) - { - /* Clear Overrun flag. */ - FLEXIO_UART_ClearStatusFlags(base, (uint32_t)kFLEXIO_UART_RxOverRunFlag); - - /* Trigger callback. */ - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_FLEXIO_UART_RxHardwareOverrun, handle->userData); - } - } - - /* Receive data register full */ - if ((((uint32_t)kFLEXIO_UART_RxDataRegFullFlag & status) != 0U) && - ((base->flexioBase->SHIFTSIEN & (1UL << base->shifterIndex[1])) != 0U)) - { - /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ - if (handle->rxDataSize != 0U) - { - /* Using non block API to read the data from the registers. */ - FLEXIO_UART_ReadByte(base, handle->rxData); - handle->rxDataSize--; - handle->rxData++; - count--; - - /* If all the data required for upper layer is ready, trigger callback. */ - if (0U == handle->rxDataSize) - { - handle->rxState = (uint8_t)kFLEXIO_UART_RxIdle; - - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_FLEXIO_UART_RxIdle, handle->userData); - } - } - } - - if (handle->rxRingBuffer != NULL) - { - if (count != 0U) - { - /* If RX ring buffer is full, trigger callback to notify over run. */ - if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) - { - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_FLEXIO_UART_RxRingBufferOverrun, handle->userData); - } - } - - /* If ring buffer is still full after callback function, the oldest data is overridden. */ - if (FLEXIO_UART_TransferIsRxRingBufferFull(handle)) - { - /* Increase handle->rxRingBufferTail to make room for new data. */ - if ((uint32_t)handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - - /* Read data. */ - rxRingBufferHead = handle->rxRingBufferHead; - handle->rxRingBuffer[rxRingBufferHead] = - (uint8_t)(base->flexioBase->SHIFTBUFBYS[base->shifterIndex[1]]); - - /* Increase handle->rxRingBufferHead. */ - if ((uint32_t)handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) - { - handle->rxRingBufferHead = 0U; - } - else - { - handle->rxRingBufferHead++; - } - } - } - /* If no receive requst pending, stop RX interrupt. */ - else if (0U == handle->rxDataSize) - { - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_RxDataRegFullInterruptEnable); - } - else - { - } - } - - /* Send data register empty and the interrupt is enabled. */ - if ((((uint32_t)kFLEXIO_UART_TxDataRegEmptyFlag & status) != 0U) && - ((base->flexioBase->SHIFTSIEN & (1UL << base->shifterIndex[0])) != 0U)) - { - if (handle->txDataSize != 0U) - { - /* Using non block API to write the data to the registers. */ - FLEXIO_UART_WriteByte(base, handle->txData); - handle->txData++; - handle->txDataSize--; - - /* If all the data are written to data register, TX finished. */ - if (0U == handle->txDataSize) - { - handle->txState = (uint8_t)kFLEXIO_UART_TxIdle; - - /* Disable TX register empty interrupt. */ - FLEXIO_UART_DisableInterrupts(base, (uint32_t)kFLEXIO_UART_TxDataRegEmptyInterruptEnable); - - /* Trigger callback. */ - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_FLEXIO_UART_TxIdle, handle->userData); - } - } - } - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart_edma.c deleted file mode 100644 index 522cbe83c9..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexio_uart_edma.c +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexio_uart_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexio_uart_edma" -#endif - -/*<! Structure definition for uart_edma_private_handle_t. The structure is private. */ -typedef struct _flexio_uart_edma_private_handle -{ - FLEXIO_UART_Type *base; - flexio_uart_edma_handle_t *handle; -} flexio_uart_edma_private_handle_t; - -/* UART EDMA transfer handle. */ -enum _flexio_uart_edma_tansfer_states -{ - kFLEXIO_UART_TxIdle, /* TX idle. */ - kFLEXIO_UART_TxBusy, /* TX busy. */ - kFLEXIO_UART_RxIdle, /* RX idle. */ - kFLEXIO_UART_RxBusy /* RX busy. */ -}; - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*< @brief user configurable flexio uart handle count. */ -#define FLEXIO_UART_HANDLE_COUNT 2 - -/*<! Private handle only used for internally. */ -static flexio_uart_edma_private_handle_t s_edmaPrivateHandle[FLEXIO_UART_HANDLE_COUNT]; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief FLEXIO UART EDMA send finished callback function. - * - * This function is called when FLEXIO UART EDMA send finished. It disables the UART - * TX EDMA request and sends @ref kStatus_FLEXIO_UART_TxIdle to FLEXIO UART callback. - * - * @param handle The EDMA handle. - * @param param Callback function parameter. - */ -static void FLEXIO_UART_TransferSendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief FLEXIO UART EDMA receive finished callback function. - * - * This function is called when FLEXIO UART EDMA receive finished. It disables the UART - * RX EDMA request and sends @ref kStatus_FLEXIO_UART_RxIdle to UART callback. - * - * @param handle The EDMA handle. - * @param param Callback function parameter. - */ -static void FLEXIO_UART_TransferReceiveEDMACallback(edma_handle_t *handle, - void *param, - bool transferDone, - uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void FLEXIO_UART_TransferSendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) -{ - flexio_uart_edma_private_handle_t *uartPrivateHandle = (flexio_uart_edma_private_handle_t *)param; - - assert(uartPrivateHandle->handle != NULL); - - /* Avoid the warning for unused variables. */ - handle = handle; - tcds = tcds; - - if (transferDone) - { - FLEXIO_UART_TransferAbortSendEDMA(uartPrivateHandle->base, uartPrivateHandle->handle); - - if (uartPrivateHandle->handle->callback != NULL) - { - uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, - kStatus_FLEXIO_UART_TxIdle, uartPrivateHandle->handle->userData); - } - } -} - -static void FLEXIO_UART_TransferReceiveEDMACallback(edma_handle_t *handle, - void *param, - bool transferDone, - uint32_t tcds) -{ - flexio_uart_edma_private_handle_t *uartPrivateHandle = (flexio_uart_edma_private_handle_t *)param; - - assert(uartPrivateHandle->handle != NULL); - - /* Avoid the warning for unused variables. */ - handle = handle; - tcds = tcds; - - if (transferDone) - { - /* Disable transfer. */ - FLEXIO_UART_TransferAbortReceiveEDMA(uartPrivateHandle->base, uartPrivateHandle->handle); - - if (uartPrivateHandle->handle->callback != NULL) - { - uartPrivateHandle->handle->callback(uartPrivateHandle->base, uartPrivateHandle->handle, - kStatus_FLEXIO_UART_RxIdle, uartPrivateHandle->handle->userData); - } - } -} - -/*! - * brief Initializes the UART handle which is used in transactional functions. - * - * param base Pointer to FLEXIO_UART_Type. - * param handle Pointer to flexio_uart_edma_handle_t structure. - * param callback The callback function. - * param userData The parameter of the callback function. - * param rxEdmaHandle User requested DMA handle for RX DMA transfer. - * param txEdmaHandle User requested DMA handle for TX DMA transfer. - * retval kStatus_Success Successfully create the handle. - * retval kStatus_OutOfRange The FlexIO SPI eDMA type/handle table out of range. - */ -status_t FLEXIO_UART_TransferCreateHandleEDMA(FLEXIO_UART_Type *base, - flexio_uart_edma_handle_t *handle, - flexio_uart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle) -{ - assert(handle != NULL); - - uint8_t index = 0U; - - /* Find the an empty handle pointer to store the handle. */ - for (index = 0U; index < (uint8_t)FLEXIO_UART_HANDLE_COUNT; index++) - { - if (s_edmaPrivateHandle[index].base == NULL) - { - s_edmaPrivateHandle[index].base = base; - s_edmaPrivateHandle[index].handle = handle; - break; - } - } - - if (index == (uint8_t)FLEXIO_UART_HANDLE_COUNT) - { - return kStatus_OutOfRange; - } - - (void)memset(handle, 0, sizeof(*handle)); - - handle->rxState = (uint8_t)kFLEXIO_UART_RxIdle; - handle->txState = (uint8_t)kFLEXIO_UART_TxIdle; - - handle->rxEdmaHandle = rxEdmaHandle; - handle->txEdmaHandle = txEdmaHandle; - - handle->callback = callback; - handle->userData = userData; - - /* Configure TX. */ - if (txEdmaHandle != NULL) - { - EDMA_SetCallback(handle->txEdmaHandle, FLEXIO_UART_TransferSendEDMACallback, &s_edmaPrivateHandle); - } - - /* Configure RX. */ - if (rxEdmaHandle != NULL) - { - EDMA_SetCallback(handle->rxEdmaHandle, FLEXIO_UART_TransferReceiveEDMACallback, &s_edmaPrivateHandle); - } - - return kStatus_Success; -} - -/*! - * brief Sends data using eDMA. - * - * This function sends data using eDMA. This is a non-blocking function, which returns - * right away. When all data is sent out, the send callback function is called. - * - * param base Pointer to FLEXIO_UART_Type - * param handle UART handle pointer. - * param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t. - * retval kStatus_Success if succeed, others failed. - * retval kStatus_FLEXIO_UART_TxBusy Previous transfer on going. - */ -status_t FLEXIO_UART_TransferSendEDMA(FLEXIO_UART_Type *base, - flexio_uart_edma_handle_t *handle, - flexio_uart_transfer_t *xfer) -{ - assert(handle->txEdmaHandle != NULL); - - edma_transfer_config_t xferConfig; - status_t status; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - - /* If previous TX not finished. */ - if ((uint8_t)kFLEXIO_UART_TxBusy == handle->txState) - { - status = kStatus_FLEXIO_UART_TxBusy; - } - else - { - handle->txState = (uint8_t)kFLEXIO_UART_TxBusy; - handle->txDataSizeAll = xfer->dataSize; - - /* Prepare transfer. */ - EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), - (uint32_t *)FLEXIO_UART_GetTxDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t), - xfer->dataSize, kEDMA_MemoryToPeripheral); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */ - handle->nbytes = sizeof(uint8_t); - - /* Submit transfer. */ - (void)EDMA_SubmitTransfer(handle->txEdmaHandle, &xferConfig); - EDMA_StartTransfer(handle->txEdmaHandle); - - /* Enable UART TX EDMA. */ - FLEXIO_UART_EnableTxDMA(base, true); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Receives data using eDMA. - * - * This function receives data using eDMA. This is a non-blocking function, which returns - * right away. When all data is received, the receive callback function is called. - * - * param base Pointer to FLEXIO_UART_Type - * param handle Pointer to flexio_uart_edma_handle_t structure - * param xfer UART eDMA transfer structure, see #flexio_uart_transfer_t. - * retval kStatus_Success if succeed, others failed. - * retval kStatus_UART_RxBusy Previous transfer on going. - */ -status_t FLEXIO_UART_TransferReceiveEDMA(FLEXIO_UART_Type *base, - flexio_uart_edma_handle_t *handle, - flexio_uart_transfer_t *xfer) -{ - assert(handle->rxEdmaHandle != NULL); - - edma_transfer_config_t xferConfig; - status_t status; - - /* Return error if xfer invalid. */ - if ((0U == xfer->dataSize) || (NULL == xfer->data)) - { - return kStatus_InvalidArgument; - } - - /* If previous RX not finished. */ - if ((uint8_t)kFLEXIO_UART_RxBusy == handle->rxState) - { - status = kStatus_FLEXIO_UART_RxBusy; - } - else - { - handle->rxState = (uint8_t)kFLEXIO_UART_RxBusy; - handle->rxDataSizeAll = xfer->dataSize; - - /* Prepare transfer. */ - EDMA_PrepareTransfer(&xferConfig, (uint32_t *)FLEXIO_UART_GetRxDataRegisterAddress(base), sizeof(uint8_t), - xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); - - /* Store the initially configured eDMA minor byte transfer count into the FLEXIO UART handle */ - handle->nbytes = sizeof(uint8_t); - - /* Submit transfer. */ - (void)EDMA_SubmitTransfer(handle->rxEdmaHandle, &xferConfig); - EDMA_StartTransfer(handle->rxEdmaHandle); - - /* Enable UART RX EDMA. */ - FLEXIO_UART_EnableRxDMA(base, true); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the sent data which using eDMA. - * - * This function aborts sent data which using eDMA. - * - * param base Pointer to FLEXIO_UART_Type - * param handle Pointer to flexio_uart_edma_handle_t structure - */ -void FLEXIO_UART_TransferAbortSendEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle) -{ - assert(handle->txEdmaHandle != NULL); - - /* Disable UART TX EDMA. */ - FLEXIO_UART_EnableTxDMA(base, false); - - /* Stop transfer. */ - EDMA_StopTransfer(handle->txEdmaHandle); - - handle->txState = (uint8_t)kFLEXIO_UART_TxIdle; -} - -/*! - * brief Aborts the receive data which using eDMA. - * - * This function aborts the receive data which using eDMA. - * - * param base Pointer to FLEXIO_UART_Type - * param handle Pointer to flexio_uart_edma_handle_t structure - */ -void FLEXIO_UART_TransferAbortReceiveEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle) -{ - assert(handle->rxEdmaHandle != NULL); - - /* Disable UART RX EDMA. */ - FLEXIO_UART_EnableRxDMA(base, false); - - /* Stop transfer. */ - EDMA_StopTransfer(handle->rxEdmaHandle); - - handle->rxState = (uint8_t)kFLEXIO_UART_RxIdle; -} - -/*! - * brief Gets the number of bytes received. - * - * This function gets the number of bytes received. - * - * param base Pointer to FLEXIO_UART_Type - * param handle Pointer to flexio_uart_edma_handle_t structure - * param count Number of bytes received so far by the non-blocking transaction. - * retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_UART_TransferGetReceiveCountEDMA(FLEXIO_UART_Type *base, - flexio_uart_edma_handle_t *handle, - size_t *count) -{ - assert(handle != NULL); - assert(handle->rxEdmaHandle != NULL); - assert(count != NULL); - - if ((uint8_t)kFLEXIO_UART_RxIdle == handle->rxState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->rxDataSizeAll - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel); - - return kStatus_Success; -} - -/*! - * brief Gets the number of bytes sent out. - * - * This function gets the number of bytes sent out. - * - * param base Pointer to FLEXIO_UART_Type - * param handle Pointer to flexio_uart_edma_handle_t structure - * param count Number of bytes sent so far by the non-blocking transaction. - * retval kStatus_NoTransferInProgress transfer has finished or no transfer in progress. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXIO_UART_TransferGetSendCountEDMA(FLEXIO_UART_Type *base, flexio_uart_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - assert(handle->txEdmaHandle != NULL); - assert(count != NULL); - - if ((uint8_t)kFLEXIO_UART_TxIdle == handle->txState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->txDataSizeAll - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel); - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram.c deleted file mode 100644 index 898c0d897c..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexram.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexram" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Gets the instance from the base address to be used to gate or ungate the module clock - * - * @param base FLEXRAM base address - * - * @return The FLEXRAM instance - */ -static uint32_t FLEXRAM_GetInstance(FLEXRAM_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to FLEXRAM bases for each instance. */ -static FLEXRAM_Type *const s_flexramBases[] = FLEXRAM_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to FLEXRAM clocks for each instance. */ -static const clock_ip_name_t s_flexramClocks[] = FLEXRAM_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t FLEXRAM_GetInstance(FLEXRAM_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_flexramBases); instance++) - { - if (s_flexramBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_flexramBases)); - - return instance; -} - -/*! - * brief FLEXRAM module initialization function. - * - * param base FLEXRAM base address. - */ -void FLEXRAM_Init(FLEXRAM_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate ENET clock. */ - CLOCK_EnableClock(s_flexramClocks[FLEXRAM_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* enable all the interrupt status */ - base->INT_STAT_EN |= (uint32_t)kFLEXRAM_InterruptStatusAll; - /* clear all the interrupt status */ - base->INT_STATUS |= (uint32_t)kFLEXRAM_InterruptStatusAll; - /* disable all the interrpt */ - base->INT_SIG_EN = 0U; -} - -/*! - * brief Deinitializes the FLEXRAM. - * - */ -void FLEXRAN_Deinit(FLEXRAM_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate ENET clock. */ - CLOCK_DisableClock(s_flexramClocks[FLEXRAM_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram_allocate.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram_allocate.c deleted file mode 100644 index cf1b3bfaf1..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexram_allocate.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2019-2020 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexram_allocate.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexram" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief FLEXRAM map TCM size to register value - * - * @param tcmBankNum tcm banknumber - * @retval register value correspond to the tcm size - */ -static uint8_t FLEXRAM_MapTcmSizeToRegister(uint8_t tcmBankNum); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint8_t FLEXRAM_MapTcmSizeToRegister(uint8_t tcmBankNum) -{ - uint8_t tcmSizeConfig = 0U; - uint32_t totalTcmSize = 0U; - - /* if bank number is a odd value, use a new bank number which bigger than target */ - do - { - if ((tcmBankNum & (tcmBankNum - 1U)) == 0U) - { - break; - } - } while (++tcmBankNum < (uint8_t)FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS); - - totalTcmSize = (uint32_t)tcmBankNum * ((uint32_t)FSL_FEATURE_FLEXRAM_INTERNAL_RAM_BANK_SIZE >> 10U); - /* get bit '1' position */ - while (totalTcmSize != 0x00U) - { - if ((totalTcmSize & 1U) == 0U) - { - tcmSizeConfig++; - } - else - { - break; - } - totalTcmSize >>= 1U; - } - - return tcmSizeConfig + 1U; -} - -void FLEXRAM_SetTCMSize(uint8_t itcmBankNum, uint8_t dtcmBankNum) -{ - assert(itcmBankNum <= FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS); - assert(dtcmBankNum <= FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS); - - /* dtcm configuration */ - if (dtcmBankNum != 0U) - { - IOMUXC_GPR->GPR14 &= ~IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ_MASK; - IOMUXC_GPR->GPR14 |= IOMUXC_GPR_GPR14_CM7_CFGDTCMSZ(FLEXRAM_MapTcmSizeToRegister(dtcmBankNum)); - IOMUXC_GPR->GPR16 |= IOMUXC_GPR_GPR16_INIT_DTCM_EN_MASK; - } - else - { - IOMUXC_GPR->GPR16 &= ~IOMUXC_GPR_GPR16_INIT_DTCM_EN_MASK; - } - - /* itcm configuration */ - if (itcmBankNum != 0U) - { - IOMUXC_GPR->GPR14 &= ~IOMUXC_GPR_GPR14_CM7_CFGITCMSZ_MASK; - IOMUXC_GPR->GPR14 |= IOMUXC_GPR_GPR14_CM7_CFGITCMSZ(FLEXRAM_MapTcmSizeToRegister(itcmBankNum)); - IOMUXC_GPR->GPR16 |= IOMUXC_GPR_GPR16_INIT_ITCM_EN_MASK; - } - else - { - IOMUXC_GPR->GPR16 &= ~IOMUXC_GPR_GPR16_INIT_ITCM_EN_MASK; - } -} - -/*! - * brief FLEXRAM allocate on-chip ram for OCRAM,ITCM,DTCM - * This function is independent of FLEXRAM_Init, it can be called directly if ram re-allocate - * is needed. - * param config allocate configuration. - * retval kStatus_InvalidArgument the argument is invalid - * kStatus_Success allocate success - */ -status_t FLEXRAM_AllocateRam(flexram_allocate_ram_t *config) -{ - assert(config != NULL); - - uint8_t dtcmBankNum = config->dtcmBankNum; - uint8_t itcmBankNum = config->itcmBankNum; - uint8_t ocramBankNum = config->ocramBankNum; - uint8_t i = 0U; - uint32_t bankCfg = 0U; - status_t status = kStatus_Success; - - /* check the arguments */ - if ((uint8_t)FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS < (dtcmBankNum + itcmBankNum + ocramBankNum)) - { - status = kStatus_InvalidArgument; - } - else - { - /* flexram bank config value */ - for (i = 0U; i < (uint8_t)FSL_FEATURE_FLEXRAM_INTERNAL_RAM_TOTAL_BANK_NUMBERS; i++) - { - if (i < ocramBankNum) - { - bankCfg |= ((uint32_t)kFLEXRAM_BankOCRAM) << (i * 2U); - continue; - } - - if (i < (dtcmBankNum + ocramBankNum)) - { - bankCfg |= ((uint32_t)kFLEXRAM_BankDTCM) << (i * 2U); - continue; - } - - if (i < (dtcmBankNum + ocramBankNum + itcmBankNum)) - { - bankCfg |= ((uint32_t)kFLEXRAM_BankITCM) << (i * 2U); - continue; - } - } - - IOMUXC_GPR->GPR17 = bankCfg; - - /* set TCM size */ - FLEXRAM_SetTCMSize(itcmBankNum, dtcmBankNum); - /* select ram allocate source from FLEXRAM_BANK_CFG */ - FLEXRAM_SetAllocateRamSrc(kFLEXRAM_BankAllocateThroughBankCfg); - } - - return status; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexspi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexspi.c deleted file mode 100644 index 0fdadefabe..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_flexspi.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexspi.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.flexspi" -#endif - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -#define FREQ_1MHz (1000000UL) -#define FLEXSPI_DLLCR_DEFAULT (0x100UL) -#define FLEXSPI_LUT_KEY_VAL (0x5AF05AF0UL) - -enum -{ - kFLEXSPI_DelayCellUnitMin = 75, /* 75ps. */ - kFLEXSPI_DelayCellUnitMax = 225, /* 225ps. */ -}; - -enum -{ - kFLEXSPI_FlashASampleClockSlaveDelayLocked = - FLEXSPI_STS2_ASLVLOCK_MASK, /* Flash A sample clock slave delay line locked. */ - kFLEXSPI_FlashASampleClockRefDelayLocked = - FLEXSPI_STS2_AREFLOCK_MASK, /* Flash A sample clock reference delay line locked. */ - kFLEXSPI_FlashBSampleClockSlaveDelayLocked = - FLEXSPI_STS2_BSLVLOCK_MASK, /* Flash B sample clock slave delay line locked. */ - kFLEXSPI_FlashBSampleClockRefDelayLocked = - FLEXSPI_STS2_BREFLOCK_MASK, /* Flash B sample clock reference delay line locked. */ -}; - -/*! @brief Common sets of flags used by the driver. */ -enum _flexspi_flag_constants -{ - /*! IRQ sources enabled by the non-blocking transactional API. */ - kIrqFlags = kFLEXSPI_IpTxFifoWatermarkEmptyFlag | kFLEXSPI_IpRxFifoWatermarkAvailableFlag | - kFLEXSPI_SequenceExecutionTimeoutFlag | kFLEXSPI_IpCommandSequenceErrorFlag | - kFLEXSPI_IpCommandGrantTimeoutFlag | kFLEXSPI_IpCommandExecutionDoneFlag, - - /*! Errors to check for. */ - kErrorFlags = kFLEXSPI_SequenceExecutionTimeoutFlag | kFLEXSPI_IpCommandSequenceErrorFlag | - kFLEXSPI_IpCommandGrantTimeoutFlag, -}; - -enum _flexspi_transfer_state -{ - kFLEXSPI_Idle = 0x0U, /*!< Transfer is done. */ - kFLEXSPI_BusyWrite = 0x1U, /*!< FLEXSPI is busy write transfer. */ - kFLEXSPI_BusyRead = 0x2U, /*!< FLEXSPI is busy write transfer. */ -}; - -/*! @brief Typedef for interrupt handler. */ -typedef void (*flexspi_isr_t)(FLEXSPI_Type *base, flexspi_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance number for FLEXSPI. - * - * @param base FLEXSPI base pointer. - */ -uint32_t FLEXSPI_GetInstance(FLEXSPI_Type *base); - -/*! - * @brief Configure flash A/B sample clock DLL. - * - * @param base FLEXSPI base pointer. - * @param config Flash configuration parameters. - */ -static uint32_t FLEXSPI_ConfigureDll(FLEXSPI_Type *base, flexspi_device_config_t *config); - -/*! - * @brief Check and clear IP command execution errors. - * - * @param base FLEXSPI base pointer. - * @param status interrupt status. - */ -status_t FLEXSPI_CheckAndClearError(FLEXSPI_Type *base, uint32_t status); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to flexspi bases for each instance. */ -static FLEXSPI_Type *const s_flexspiBases[] = FLEXSPI_BASE_PTRS; - -/*! @brief Pointers to flexspi IRQ number for each instance. */ -static const IRQn_Type s_flexspiIrqs[] = FLEXSPI_IRQS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Clock name array */ -static const clock_ip_name_t s_flexspiClock[] = FLEXSPI_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ -/*! @brief Pointers to flexspi handles for each instance. */ -static flexspi_handle_t *s_flexspiHandle[ARRAY_SIZE(s_flexspiBases)]; -#endif - -#if defined(FSL_FEATURE_FLEXSPI_HAS_RESET) && FSL_FEATURE_FLEXSPI_HAS_RESET -/*! @brief Pointers to FLEXSPI resets for each instance. */ -static const reset_ip_name_t s_flexspiResets[] = FLEXSPI_RSTS; -#endif - -#if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ -/*! @brief Pointer to flexspi IRQ handler. */ -static flexspi_isr_t s_flexspiIsr; -#endif -/******************************************************************************* - * Code - ******************************************************************************/ - -uint32_t FLEXSPI_GetInstance(FLEXSPI_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_flexspiBases); instance++) - { - if (s_flexspiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_flexspiBases)); - - return instance; -} - -static uint32_t FLEXSPI_ConfigureDll(FLEXSPI_Type *base, flexspi_device_config_t *config) -{ - bool isUnifiedConfig = true; - uint32_t flexspiDllValue; - uint32_t dllValue; - uint32_t temp; - - uint32_t rxSampleClock = (base->MCR0 & FLEXSPI_MCR0_RXCLKSRC_MASK) >> FLEXSPI_MCR0_RXCLKSRC_SHIFT; - switch (rxSampleClock) - { - case (uint32_t)kFLEXSPI_ReadSampleClkLoopbackInternally: - case (uint32_t)kFLEXSPI_ReadSampleClkLoopbackFromDqsPad: - case (uint32_t)kFLEXSPI_ReadSampleClkLoopbackFromSckPad: - isUnifiedConfig = true; - break; - case (uint32_t)kFLEXSPI_ReadSampleClkExternalInputFromDqsPad: - if (config->isSck2Enabled) - { - isUnifiedConfig = true; - } - else - { - isUnifiedConfig = false; - } - break; - default: - assert(false); - break; - } - - if (isUnifiedConfig) - { - flexspiDllValue = FLEXSPI_DLLCR_DEFAULT; /* 1 fixed delay cells in DLL delay chain) */ - } - else - { - if (config->flexspiRootClk >= 100U * FREQ_1MHz) - { - /* DLLEN = 1, SLVDLYTARGET = 0xF, */ - flexspiDllValue = FLEXSPI_DLLCR_DLLEN(1) | FLEXSPI_DLLCR_SLVDLYTARGET(0x0F); - } - else - { - temp = (uint32_t)config->dataValidTime * 1000U; /* Convert data valid time in ns to ps. */ - dllValue = temp / (uint32_t)kFLEXSPI_DelayCellUnitMin; - if (dllValue * (uint32_t)kFLEXSPI_DelayCellUnitMin < temp) - { - dllValue++; - } - flexspiDllValue = FLEXSPI_DLLCR_OVRDEN(1) | FLEXSPI_DLLCR_OVRDVAL(dllValue); - } - } - return flexspiDllValue; -} - -status_t FLEXSPI_CheckAndClearError(FLEXSPI_Type *base, uint32_t status) -{ - status_t result = kStatus_Success; - - /* Check for error. */ - status &= (uint32_t)kErrorFlags; - if (0U != status) - { - /* Select the correct error code.. */ - if (0U != (status & (uint32_t)kFLEXSPI_SequenceExecutionTimeoutFlag)) - { - result = kStatus_FLEXSPI_SequenceExecutionTimeout; - } - else if (0U != (status & (uint32_t)kFLEXSPI_IpCommandSequenceErrorFlag)) - { - result = kStatus_FLEXSPI_IpCommandSequenceError; - } - else if (0U != (status & (uint32_t)kFLEXSPI_IpCommandGrantTimeoutFlag)) - { - result = kStatus_FLEXSPI_IpCommandGrantTimeout; - } - else - { - assert(false); - } - - /* Clear the flags. */ - FLEXSPI_ClearInterruptStatusFlags(base, status); - - /* Reset fifos. These flags clear automatically. */ - base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK; - base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK; - } - - return result; -} - -/*! - * brief Initializes the FLEXSPI module and internal state. - * - * This function enables the clock for FLEXSPI and also configures the FLEXSPI with the - * input configure parameters. Users should call this function before any FLEXSPI operations. - * - * param base FLEXSPI peripheral base address. - * param config FLEXSPI configure structure. - */ -void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config) -{ - uint32_t configValue = 0; - uint8_t i = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the flexspi clock */ - (void)CLOCK_EnableClock(s_flexspiClock[FLEXSPI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_FLEXSPI_HAS_RESET) && FSL_FEATURE_FLEXSPI_HAS_RESET - /* Reset the FLEXSPI module */ - RESET_PeripheralReset(s_flexspiResets[FLEXSPI_GetInstance(base)]); -#endif - - /* Reset peripheral before configuring it. */ - base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; - FLEXSPI_SoftwareReset(base); - - /* Configure MCR0 configuration items. */ - configValue = FLEXSPI_MCR0_RXCLKSRC(config->rxSampleClock) | FLEXSPI_MCR0_DOZEEN(config->enableDoze) | - FLEXSPI_MCR0_IPGRANTWAIT(config->ipGrantTimeoutCycle) | - FLEXSPI_MCR0_AHBGRANTWAIT(config->ahbConfig.ahbGrantTimeoutCycle) | - FLEXSPI_MCR0_SCKFREERUNEN(config->enableSckFreeRunning) | - FLEXSPI_MCR0_HSEN(config->enableHalfSpeedAccess) | - FLEXSPI_MCR0_COMBINATIONEN(config->enableCombination) | -#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN) - FLEXSPI_MCR0_ATDFEN(config->ahbConfig.enableAHBWriteIpTxFifo) | -#endif -#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN) - FLEXSPI_MCR0_ARDFEN(config->ahbConfig.enableAHBWriteIpRxFifo) | -#endif - FLEXSPI_MCR0_MDIS_MASK; - base->MCR0 = configValue; - - /* Configure MCR1 configurations. */ - configValue = - FLEXSPI_MCR1_SEQWAIT(config->seqTimeoutCycle) | FLEXSPI_MCR1_AHBBUSWAIT(config->ahbConfig.ahbBusTimeoutCycle); - base->MCR1 = configValue; - - /* Configure MCR2 configurations. */ - configValue = base->MCR2; - configValue &= ~(FLEXSPI_MCR2_RESUMEWAIT_MASK | FLEXSPI_MCR2_SCKBDIFFOPT_MASK | FLEXSPI_MCR2_SAMEDEVICEEN_MASK | - FLEXSPI_MCR2_CLRAHBBUFOPT_MASK); - configValue |= FLEXSPI_MCR2_RESUMEWAIT(config->ahbConfig.resumeWaitCycle) | - FLEXSPI_MCR2_SCKBDIFFOPT(config->enableSckBDiffOpt) | - FLEXSPI_MCR2_SAMEDEVICEEN(config->enableSameConfigForAll) | - FLEXSPI_MCR2_CLRAHBBUFOPT(config->ahbConfig.enableClearAHBBufferOpt); - - base->MCR2 = configValue; - - /* Configure AHB control items. */ - configValue = base->AHBCR; - configValue &= ~(FLEXSPI_AHBCR_READADDROPT_MASK | FLEXSPI_AHBCR_PREFETCHEN_MASK | FLEXSPI_AHBCR_BUFFERABLEEN_MASK | - FLEXSPI_AHBCR_CACHABLEEN_MASK); - configValue |= FLEXSPI_AHBCR_READADDROPT(config->ahbConfig.enableReadAddressOpt) | - FLEXSPI_AHBCR_PREFETCHEN(config->ahbConfig.enableAHBPrefetch) | - FLEXSPI_AHBCR_BUFFERABLEEN(config->ahbConfig.enableAHBBufferable) | - FLEXSPI_AHBCR_CACHABLEEN(config->ahbConfig.enableAHBCachable); - base->AHBCR = configValue; - - /* Configure AHB rx buffers. */ - for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT; i++) - { - configValue = base->AHBRXBUFCR0[i]; - - configValue &= ~(FLEXSPI_AHBRXBUFCR0_PREFETCHEN_MASK | FLEXSPI_AHBRXBUFCR0_PRIORITY_MASK | - FLEXSPI_AHBRXBUFCR0_MSTRID_MASK | FLEXSPI_AHBRXBUFCR0_BUFSZ_MASK); - configValue |= FLEXSPI_AHBRXBUFCR0_PREFETCHEN(config->ahbConfig.buffer[i].enablePrefetch) | - FLEXSPI_AHBRXBUFCR0_PRIORITY(config->ahbConfig.buffer[i].priority) | - FLEXSPI_AHBRXBUFCR0_MSTRID(config->ahbConfig.buffer[i].masterIndex) | - FLEXSPI_AHBRXBUFCR0_BUFSZ((uint32_t)config->ahbConfig.buffer[i].bufferSize / 8U); - base->AHBRXBUFCR0[i] = configValue; - } - - /* Configure IP Fifo watermarks. */ - base->IPRXFCR &= ~FLEXSPI_IPRXFCR_RXWMRK_MASK; - base->IPRXFCR |= FLEXSPI_IPRXFCR_RXWMRK((uint32_t)config->rxWatermark / 8U - 1U); - base->IPTXFCR &= ~FLEXSPI_IPTXFCR_TXWMRK_MASK; - base->IPTXFCR |= FLEXSPI_IPTXFCR_TXWMRK((uint32_t)config->txWatermark / 8U - 1U); - - /* Reset flash size on all ports */ - for (i = 0; i < (uint32_t)kFLEXSPI_PortCount; i++) - { - base->FLSHCR0[i] = 0; - } -} - -/*! - * brief Gets default settings for FLEXSPI. - * - * param config FLEXSPI configuration structure. - */ -void FLEXSPI_GetDefaultConfig(flexspi_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackInternally; - config->enableSckFreeRunning = false; - config->enableCombination = false; - config->enableDoze = true; - config->enableHalfSpeedAccess = false; - config->enableSckBDiffOpt = false; - config->enableSameConfigForAll = false; - config->seqTimeoutCycle = 0xFFFFU; - config->ipGrantTimeoutCycle = 0xFFU; - config->txWatermark = 8; - config->rxWatermark = 8; -#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ATDFEN) - config->ahbConfig.enableAHBWriteIpTxFifo = false; -#endif -#if !(defined(FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN) && FSL_FEATURE_FLEXSPI_HAS_NO_MCR0_ARDFEN) - config->ahbConfig.enableAHBWriteIpRxFifo = false; -#endif - config->ahbConfig.ahbGrantTimeoutCycle = 0xFFU; - config->ahbConfig.ahbBusTimeoutCycle = 0xFFFFU; - config->ahbConfig.resumeWaitCycle = 0x20U; - (void)memset(config->ahbConfig.buffer, 0, sizeof(config->ahbConfig.buffer)); - /* Use invalid master ID 0xF and buffer size 0 for the first several buffers. */ - for (uint8_t i = 0; i < ((uint8_t)FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 2U); i++) - { - config->ahbConfig.buffer[i].enablePrefetch = true; /* Default enable AHB prefetch. */ - config->ahbConfig.buffer[i].masterIndex = 0xFU; /* Invalid master index which is not used, so will never hit. */ - config->ahbConfig.buffer[i].bufferSize = - 0; /* Default buffer size 0 for buffer0 to buffer(FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 3U)*/ - } - - for (uint8_t i = ((uint8_t)FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT - 2U); - i < (uint8_t)FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT; i++) - { - config->ahbConfig.buffer[i].enablePrefetch = true; /* Default enable AHB prefetch. */ - config->ahbConfig.buffer[i].bufferSize = 256U; /* Default buffer size 256 bytes. */ - } - config->ahbConfig.enableClearAHBBufferOpt = false; - config->ahbConfig.enableReadAddressOpt = false; - config->ahbConfig.enableAHBPrefetch = false; - config->ahbConfig.enableAHBBufferable = false; - config->ahbConfig.enableAHBCachable = false; -} - -/*! - * brief Deinitializes the FLEXSPI module. - * - * Clears the FLEXSPI state and FLEXSPI module registers. - * param base FLEXSPI peripheral base address. - */ -void FLEXSPI_Deinit(FLEXSPI_Type *base) -{ - /* Reset peripheral. */ - FLEXSPI_SoftwareReset(base); -} - -/*! - * brief Configures the connected device parameter. - * - * This function configures the connected device relevant parameters, such as the size, command, and so on. - * The flash configuration value cannot have a default value. The user needs to configure it according to the - * connected device. - * - * param base FLEXSPI peripheral base address. - * param config Flash configuration parameters. - * param port FLEXSPI Operation port. - */ -void FLEXSPI_SetFlashConfig(FLEXSPI_Type *base, flexspi_device_config_t *config, flexspi_port_t port) -{ - uint32_t configValue = 0; - uint32_t statusValue = 0; - uint8_t index = (uint8_t)port >> 1U; /* PortA with index 0, PortB with index 1. */ - - /* Wait for bus idle before change flash configuration. */ - while (!FLEXSPI_GetBusIdleStatus(base)) - { - } - - /* Configure flash size. */ - base->FLSHCR0[port] = config->flashSize; - - /* Configure flash parameters. */ - base->FLSHCR1[port] = FLEXSPI_FLSHCR1_CSINTERVAL(config->CSInterval) | - FLEXSPI_FLSHCR1_CSINTERVALUNIT(config->CSIntervalUnit) | - FLEXSPI_FLSHCR1_TCSH(config->CSHoldTime) | FLEXSPI_FLSHCR1_TCSS(config->CSSetupTime) | - FLEXSPI_FLSHCR1_CAS(config->columnspace) | FLEXSPI_FLSHCR1_WA(config->enableWordAddress); - - /* Configure AHB operation items. */ - configValue = base->FLSHCR2[port]; - - configValue &= ~(FLEXSPI_FLSHCR2_AWRWAITUNIT_MASK | FLEXSPI_FLSHCR2_AWRWAIT_MASK | FLEXSPI_FLSHCR2_AWRSEQNUM_MASK | - FLEXSPI_FLSHCR2_AWRSEQID_MASK | FLEXSPI_FLSHCR2_ARDSEQNUM_MASK | FLEXSPI_FLSHCR2_ARDSEQID_MASK); - - configValue |= - FLEXSPI_FLSHCR2_AWRWAITUNIT(config->AHBWriteWaitUnit) | FLEXSPI_FLSHCR2_AWRWAIT(config->AHBWriteWaitInterval); - - if (config->AWRSeqNumber > 0U) - { - configValue |= FLEXSPI_FLSHCR2_AWRSEQID((uint32_t)config->AWRSeqIndex) | - FLEXSPI_FLSHCR2_AWRSEQNUM((uint32_t)config->AWRSeqNumber - 1U); - } - - if (config->ARDSeqNumber > 0U) - { - configValue |= FLEXSPI_FLSHCR2_ARDSEQID((uint32_t)config->ARDSeqIndex) | - FLEXSPI_FLSHCR2_ARDSEQNUM((uint32_t)config->ARDSeqNumber - 1U); - } - - base->FLSHCR2[port] = configValue; - - /* Configure DLL. */ - configValue = FLEXSPI_ConfigureDll(base, config); - base->DLLCR[index] = configValue; - - /* Configure write mask. */ - if (config->enableWriteMask) - { - base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMOPT1_MASK; - } - else - { - base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMOPT1_MASK; - } - - if (index == 0U) /*PortA*/ - { - base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMENA_MASK; - base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENA(config->enableWriteMask); - } - else - { - base->FLSHCR4 &= ~FLEXSPI_FLSHCR4_WMENB_MASK; - base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENB(config->enableWriteMask); - } - - /* Exit stop mode. */ - base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK; - - /* According to ERR011377, need to delay at least 100 NOPs to ensure the DLL is locked. */ - statusValue = - (index == 0U) ? - ((uint32_t)kFLEXSPI_FlashASampleClockSlaveDelayLocked | - (uint32_t)kFLEXSPI_FlashASampleClockRefDelayLocked) : - ((uint32_t)kFLEXSPI_FlashBSampleClockSlaveDelayLocked | (uint32_t)kFLEXSPI_FlashBSampleClockRefDelayLocked); - - if (0U != (configValue & FLEXSPI_DLLCR_DLLEN_MASK)) - { - /* Wait slave delay line locked and slave reference delay line locked. */ - while ((base->STS2 & statusValue) != statusValue) - { - } - - /* Wait at least 100 NOPs*/ - for (uint8_t delay = 100U; delay > 0U; delay--) - { - __NOP(); - } - } -} - -/*! brief Updates the LUT table. - * - * param base FLEXSPI peripheral base address. - * param index From which index start to update. It could be any index of the LUT table, which - * also allows user to update command content inside a command. Each command consists of up to - * 8 instructions and occupy 4*32-bit memory. - * param cmd Command sequence array. - * param count Number of sequences. - */ -void FLEXSPI_UpdateLUT(FLEXSPI_Type *base, uint32_t index, const uint32_t *cmd, uint32_t count) -{ - assert(index < 64U); - - uint32_t i = 0; - volatile uint32_t *lutBase; - - /* Wait for bus idle before change flash configuration. */ - while (!FLEXSPI_GetBusIdleStatus(base)) - { - } - - /* Unlock LUT for update. */ - base->LUTKEY = FLEXSPI_LUT_KEY_VAL; - base->LUTCR = 0x02; - - lutBase = &base->LUT[index]; - for (i = 0; i < count; i++) - { - *lutBase++ = *cmd++; - } - - /* Lock LUT. */ - base->LUTKEY = FLEXSPI_LUT_KEY_VAL; - base->LUTCR = 0x01; -} - -/*! brief Update read sample clock source - * - * param base FLEXSPI peripheral base address. - * param clockSource clockSource of type #flexspi_read_sample_clock_t - */ -void FLEXSPI_UpdateRxSampleClock(FLEXSPI_Type *base, flexspi_read_sample_clock_t clockSource) -{ - uint32_t mcr0Val; - - /* Wait for bus idle before change flash configuration. */ - while (!FLEXSPI_GetBusIdleStatus(base)) - { - } - - mcr0Val = base->MCR0; - mcr0Val &= ~FLEXSPI_MCR0_RXCLKSRC_MASK; - mcr0Val |= FLEXSPI_MCR0_RXCLKSRC(clockSource); - base->MCR0 = mcr0Val; - - /* Reset peripheral. */ - FLEXSPI_SoftwareReset(base); -} - -/*! - * brief Sends a buffer of data bytes using blocking method. - * note This function blocks via polling until all bytes have been sent. - * param base FLEXSPI peripheral base address - * param buffer The data bytes to send - * param size The number of data bytes to send - * retval kStatus_Success write success without error - * retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout - * retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequence error detected - * retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected - */ -status_t FLEXSPI_WriteBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size) -{ - uint32_t txWatermark = ((base->IPTXFCR & FLEXSPI_IPTXFCR_TXWMRK_MASK) >> FLEXSPI_IPTXFCR_TXWMRK_SHIFT) + 1U; - uint32_t status; - status_t result = kStatus_Success; - uint32_t i = 0; - - /* Send data buffer */ - while (0U != size) - { - /* Wait until there is room in the fifo. This also checks for errors. */ - while (0U == ((status = base->INTR) & (uint32_t)kFLEXSPI_IpTxFifoWatermarkEmptyFlag)) - { - } - - result = FLEXSPI_CheckAndClearError(base, status); - - if (kStatus_Success != result) - { - return result; - } - - /* Write watermark level data into tx fifo . */ - if (size >= 8U * txWatermark) - { - for (i = 0U; i < 2U * txWatermark; i++) - { - base->TFDR[i] = *buffer++; - } - - size = size - 8U * txWatermark; - } - else - { - for (i = 0U; i < (size / 4U + 1U); i++) - { - base->TFDR[i] = *buffer++; - } - size = 0U; - } - - /* Push a watermark level data into IP TX FIFO. */ - base->INTR |= (uint32_t)kFLEXSPI_IpTxFifoWatermarkEmptyFlag; - } - - return result; -} - -/*! - * brief Receives a buffer of data bytes using a blocking method. - * note This function blocks via polling until all bytes have been sent. - * param base FLEXSPI peripheral base address - * param buffer The data bytes to send - * param size The number of data bytes to receive - * retval kStatus_Success read success without error - * retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout - * retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequence error detected - * retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected - */ -status_t FLEXSPI_ReadBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size) -{ - uint32_t rxWatermark = ((base->IPRXFCR & FLEXSPI_IPRXFCR_RXWMRK_MASK) >> FLEXSPI_IPRXFCR_RXWMRK_SHIFT) + 1U; - uint32_t status; - status_t result = kStatus_Success; - uint32_t i = 0; - bool isReturn = false; - - /* Send data buffer */ - while (0U != size) - { - if (size >= 8U * rxWatermark) - { - /* Wait until there is room in the fifo. This also checks for errors. */ - while (0U == ((status = base->INTR) & (uint32_t)kFLEXSPI_IpRxFifoWatermarkAvailableFlag)) - { - result = FLEXSPI_CheckAndClearError(base, status); - - if (kStatus_Success != result) - { - isReturn = true; - break; - } - } - } - else - { - /* Wait fill level. This also checks for errors. */ - while (size > ((((base->IPRXFSTS) & FLEXSPI_IPRXFSTS_FILL_MASK) >> FLEXSPI_IPRXFSTS_FILL_SHIFT) * 8U)) - { - result = FLEXSPI_CheckAndClearError(base, base->INTR); - - if (kStatus_Success != result) - { - isReturn = true; - break; - } - } - } - - if (isReturn) - { - break; - } - - result = FLEXSPI_CheckAndClearError(base, base->INTR); - - if (kStatus_Success != result) - { - break; - } - - /* Read watermark level data from rx fifo . */ - if (size >= 8U * rxWatermark) - { - for (i = 0U; i < 2U * rxWatermark; i++) - { - *buffer++ = base->RFDR[i]; - } - - size = size - 8U * rxWatermark; - } - else - { - for (i = 0U; i < ((size + 3U) / 4U); i++) - { - *buffer++ = base->RFDR[i]; - } - size = 0; - } - - /* Pop out a watermark level datas from IP RX FIFO. */ - base->INTR |= (uint32_t)kFLEXSPI_IpRxFifoWatermarkAvailableFlag; - } - - return result; -} - -/*! - * brief Execute command to transfer a buffer data bytes using a blocking method. - * param base FLEXSPI peripheral base address - * param xfer pointer to the transfer structure. - * retval kStatus_Success command transfer success without error - * retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout - * retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequence error detected - * retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected - */ -status_t FLEXSPI_TransferBlocking(FLEXSPI_Type *base, flexspi_transfer_t *xfer) -{ - uint32_t configValue = 0; - status_t result = kStatus_Success; - - /* Clear sequence pointer before sending data to external devices. */ - base->FLSHCR2[xfer->port] |= FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK; - - /* Clear former pending status before start this transfer. */ - base->INTR |= FLEXSPI_INTR_AHBCMDERR_MASK | FLEXSPI_INTR_IPCMDERR_MASK | FLEXSPI_INTR_AHBCMDGE_MASK | - FLEXSPI_INTR_IPCMDGE_MASK; - - /* Configure base address. */ - base->IPCR0 = xfer->deviceAddress; - - /* Reset fifos. */ - base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK; - base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK; - - /* Configure data size. */ - if ((xfer->cmdType == kFLEXSPI_Read) || (xfer->cmdType == kFLEXSPI_Write) || (xfer->cmdType == kFLEXSPI_Config)) - { - configValue = FLEXSPI_IPCR1_IDATSZ(xfer->dataSize); - } - - /* Configure sequence ID. */ - configValue |= - FLEXSPI_IPCR1_ISEQID((uint32_t)xfer->seqIndex) | FLEXSPI_IPCR1_ISEQNUM((uint32_t)xfer->SeqNumber - 1U); - base->IPCR1 = configValue; - - /* Start Transfer. */ - base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK; - - if ((xfer->cmdType == kFLEXSPI_Write) || (xfer->cmdType == kFLEXSPI_Config)) - { - result = FLEXSPI_WriteBlocking(base, xfer->data, xfer->dataSize); - } - else if (xfer->cmdType == kFLEXSPI_Read) - { - result = FLEXSPI_ReadBlocking(base, xfer->data, xfer->dataSize); - } - else - { - /* Empty else. */ - } - - /* Wait for bus idle. */ - while (!FLEXSPI_GetBusIdleStatus(base)) - { - } - - if (xfer->cmdType == kFLEXSPI_Command) - { - result = FLEXSPI_CheckAndClearError(base, base->INTR); - } - - return result; -} - -/*! - * brief Initializes the FLEXSPI handle which is used in transactional functions. - * - * param base FLEXSPI peripheral base address. - * param handle pointer to flexspi_handle_t structure to store the transfer state. - * param callback pointer to user callback function. - * param userData user parameter passed to the callback function. - */ -void FLEXSPI_TransferCreateHandle(FLEXSPI_Type *base, - flexspi_handle_t *handle, - flexspi_transfer_callback_t callback, - void *userData) -{ - assert(NULL != handle); - - uint32_t instance = FLEXSPI_GetInstance(base); - - /* Zero handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set callback and userData. */ - handle->completionCallback = callback; - handle->userData = userData; - -#if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ - /* Save the context in global variables to support the double weak mechanism. */ - s_flexspiHandle[instance] = handle; - s_flexspiIsr = FLEXSPI_TransferHandleIRQ; -#endif - - /* Enable NVIC interrupt. */ - (void)EnableIRQ(s_flexspiIrqs[instance]); -} - -/*! - * brief Performs a interrupt non-blocking transfer on the FLEXSPI bus. - * - * note Calling the API returns immediately after transfer initiates. The user needs - * to call FLEXSPI_GetTransferCount to poll the transfer status to check whether - * the transfer is finished. If the return status is not kStatus_FLEXSPI_Busy, the transfer - * is finished. For FLEXSPI_Read, the dataSize should be multiple of rx watermark level, or - * FLEXSPI could not read data properly. - * - * param base FLEXSPI peripheral base address. - * param handle pointer to flexspi_handle_t structure which stores the transfer state. - * param xfer pointer to flexspi_transfer_t structure. - * retval kStatus_Success Successfully start the data transmission. - * retval kStatus_FLEXSPI_Busy Previous transmission still not finished. - */ -status_t FLEXSPI_TransferNonBlocking(FLEXSPI_Type *base, flexspi_handle_t *handle, flexspi_transfer_t *xfer) -{ - uint32_t configValue = 0; - status_t result = kStatus_Success; - - assert(NULL != handle); - assert(NULL != xfer); - - /* Check if the I2C bus is idle - if not return busy status. */ - if (handle->state != (uint32_t)kFLEXSPI_Idle) - { - result = kStatus_FLEXSPI_Busy; - } - else - { - handle->data = xfer->data; - handle->dataSize = xfer->dataSize; - handle->transferTotalSize = xfer->dataSize; - handle->state = (xfer->cmdType == kFLEXSPI_Read) ? (uint32_t)kFLEXSPI_BusyRead : (uint32_t)kFLEXSPI_BusyWrite; - - /* Clear sequence pointer before sending data to external devices. */ - base->FLSHCR2[xfer->port] |= FLEXSPI_FLSHCR2_CLRINSTRPTR_MASK; - - /* Clear former pending status before start this transfer. */ - base->INTR |= FLEXSPI_INTR_AHBCMDERR_MASK | FLEXSPI_INTR_IPCMDERR_MASK | FLEXSPI_INTR_AHBCMDGE_MASK | - FLEXSPI_INTR_IPCMDGE_MASK; - - /* Configure base address. */ - base->IPCR0 = xfer->deviceAddress; - - /* Reset fifos. */ - base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK; - base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK; - - /* Configure data size. */ - if ((xfer->cmdType == kFLEXSPI_Read) || (xfer->cmdType == kFLEXSPI_Write)) - { - configValue = FLEXSPI_IPCR1_IDATSZ(xfer->dataSize); - } - - /* Configure sequence ID. */ - configValue |= - FLEXSPI_IPCR1_ISEQID((uint32_t)xfer->seqIndex) | FLEXSPI_IPCR1_ISEQNUM((uint32_t)xfer->SeqNumber - 1U); - base->IPCR1 = configValue; - - /* Start Transfer. */ - base->IPCMD |= FLEXSPI_IPCMD_TRG_MASK; - - if (handle->state == (uint32_t)kFLEXSPI_BusyRead) - { - FLEXSPI_EnableInterrupts(base, (uint32_t)kFLEXSPI_IpRxFifoWatermarkAvailableFlag | - (uint32_t)kFLEXSPI_SequenceExecutionTimeoutFlag | - (uint32_t)kFLEXSPI_IpCommandSequenceErrorFlag | - (uint32_t)kFLEXSPI_IpCommandGrantTimeoutFlag | - (uint32_t)kFLEXSPI_IpCommandExecutionDoneFlag); - } - else - { - FLEXSPI_EnableInterrupts( - base, (uint32_t)kFLEXSPI_IpTxFifoWatermarkEmptyFlag | (uint32_t)kFLEXSPI_SequenceExecutionTimeoutFlag | - (uint32_t)kFLEXSPI_IpCommandSequenceErrorFlag | (uint32_t)kFLEXSPI_IpCommandGrantTimeoutFlag | - (uint32_t)kFLEXSPI_IpCommandExecutionDoneFlag); - } - } - - return result; -} - -/*! - * brief Gets the master transfer status during a interrupt non-blocking transfer. - * - * param base FLEXSPI peripheral base address. - * param handle pointer to flexspi_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the non-blocking transaction. - * retval kStatus_InvalidArgument count is Invalid. - * retval kStatus_Success Successfully return the count. - */ -status_t FLEXSPI_TransferGetCount(FLEXSPI_Type *base, flexspi_handle_t *handle, size_t *count) -{ - assert(NULL != handle); - - status_t result = kStatus_Success; - - if (handle->state == (uint32_t)kFLEXSPI_Idle) - { - result = kStatus_NoTransferInProgress; - } - else - { - *count = handle->transferTotalSize - handle->dataSize; - } - - return result; -} - -/*! - * brief Aborts an interrupt non-blocking transfer early. - * - * note This API can be called at any time when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base FLEXSPI peripheral base address. - * param handle pointer to flexspi_handle_t structure which stores the transfer state - */ -void FLEXSPI_TransferAbort(FLEXSPI_Type *base, flexspi_handle_t *handle) -{ - assert(NULL != handle); - - FLEXSPI_DisableInterrupts(base, (uint32_t)kIrqFlags); - handle->state = (uint32_t)kFLEXSPI_Idle; -} - -/*! - * brief Master interrupt handler. - * - * param base FLEXSPI peripheral base address. - * param handle pointer to flexspi_handle_t structure. - */ -void FLEXSPI_TransferHandleIRQ(FLEXSPI_Type *base, flexspi_handle_t *handle) -{ - uint32_t status; - status_t result; - uint32_t intEnableStatus; - uint32_t txWatermark; - uint32_t rxWatermark; - uint8_t i = 0; - - status = base->INTR; - intEnableStatus = base->INTEN; - - /* Check if interrupt is enabled and status is alerted. */ - if ((status & intEnableStatus) != 0U) - { - result = FLEXSPI_CheckAndClearError(base, status); - - if ((result != kStatus_Success) && (handle->completionCallback != NULL)) - { - FLEXSPI_TransferAbort(base, handle); - if (NULL != handle->completionCallback) - { - handle->completionCallback(base, handle, result, handle->userData); - } - } - else - { - if ((0U != (status & (uint32_t)kFLEXSPI_IpRxFifoWatermarkAvailableFlag)) && - (handle->state == (uint32_t)kFLEXSPI_BusyRead)) - { - rxWatermark = ((base->IPRXFCR & FLEXSPI_IPRXFCR_RXWMRK_MASK) >> FLEXSPI_IPRXFCR_RXWMRK_SHIFT) + 1U; - - /* Read watermark level data from rx fifo . */ - if (handle->dataSize >= 8U * rxWatermark) - { - /* Read watermark level data from rx fifo . */ - for (i = 0U; i < 2U * rxWatermark; i++) - { - *handle->data++ = base->RFDR[i]; - } - - handle->dataSize = handle->dataSize - 8U * rxWatermark; - } - else - { - for (i = 0; i < (handle->dataSize + 3U) / 4U; i++) - { - *handle->data++ = base->RFDR[i]; - } - handle->dataSize = 0; - } - /* Pop out a watermark level data from IP RX FIFO. */ - base->INTR |= (uint32_t)kFLEXSPI_IpRxFifoWatermarkAvailableFlag; - } - - if (0U != (status & (uint32_t)kFLEXSPI_IpCommandExecutionDoneFlag)) - { - base->INTR |= (uint32_t)kFLEXSPI_IpCommandExecutionDoneFlag; - - FLEXSPI_TransferAbort(base, handle); - - if (NULL != handle->completionCallback) - { - handle->completionCallback(base, handle, kStatus_Success, handle->userData); - } - } - - /* TX FIFO empty interrupt, push watermark level data into tx FIFO. */ - if ((0U != (status & (uint32_t)kFLEXSPI_IpTxFifoWatermarkEmptyFlag)) && - (handle->state == (uint32_t)kFLEXSPI_BusyWrite)) - { - if (0U != handle->dataSize) - { - txWatermark = ((base->IPTXFCR & FLEXSPI_IPTXFCR_TXWMRK_MASK) >> FLEXSPI_IPTXFCR_TXWMRK_SHIFT) + 1U; - /* Write watermark level data into tx fifo . */ - if (handle->dataSize >= 8U * txWatermark) - { - for (i = 0; i < 2U * txWatermark; i++) - { - base->TFDR[i] = *handle->data++; - } - - handle->dataSize = handle->dataSize - 8U * txWatermark; - } - else - { - for (i = 0; i < (handle->dataSize / 4U + 1U); i++) - { - base->TFDR[i] = *handle->data++; - } - handle->dataSize = 0; - } - - /* Push a watermark level data into IP TX FIFO. */ - base->INTR |= (uint32_t)kFLEXSPI_IpTxFifoWatermarkEmptyFlag; - } - } - else - { - /* Empty else */ - } - } - } - else - { - /* Empty else */ - } -} - -#if defined(FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ) && FSL_DRIVER_TRANSFER_DOUBLE_WEAK_IRQ -#if defined(FLEXSPI) -void FLEXSPI_DriverIRQHandler(void) -{ - s_flexspiIsr(FLEXSPI, s_flexspiHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(FLEXSPI0) -void FLEXSPI0_DriverIRQHandler(void) -{ - s_flexspiIsr(FLEXSPI0, s_flexspiHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#if defined(FLEXSPI1) -void FLEXSPI1_DriverIRQHandler(void) -{ - s_flexspiIsr(FLEXSPI1, s_flexspiHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(LSIO__FLEXSPI0) -void LSIO_OCTASPI0_INT_DriverIRQHandler(void) -{ - s_flexspiIsr(LSIO__FLEXSPI0, s_flexspiHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#if defined(LSIO__FLEXSPI1) -void LSIO_OCTASPI1_INT_DriverIRQHandler(void) -{ - s_flexspiIsr(LSIO__FLEXSPI1, s_flexspiHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(FSL_FEATURE_FLEXSPI_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_FLEXSPI_HAS_SHARED_IRQ0_IRQ1 - -void FLEXSPI0_FLEXSPI1_DriverIRQHandler(void) -{ - /* If handle is registered, treat the transfer function is enabled. */ - if (NULL != s_flexspiHandle[0]) - { - s_flexspiIsr(FLEXSPI0, s_flexspiHandle[0]); - } - if (NULL != s_flexspiHandle[1]) - { - s_flexspiIsr(FLEXSPI1, s_flexspiHandle[1]); - } -} -#endif - -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpc.c deleted file mode 100644 index e5cef48d1b..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_gpc.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.gpc_1" -#endif - -/*! - * brief Enable the IRQ. - * - * param base GPC peripheral base address. - * param irqId ID number of IRQ to be enabled, available range is 32-159. 0-31 is available in some platforms. - */ -void GPC_EnableIRQ(GPC_Type *base, uint32_t irqId) -{ - uint32_t irqRegNum = irqId / 32U; - uint32_t irqRegShiftNum = irqId % 32U; - - assert(irqRegNum <= GPC_IMR_COUNT); - -#if ((defined FSL_FEATURE_GPC_HAS_IRQ_0_31) && FSL_FEATURE_GPC_HAS_IRQ_0_31) - if (irqRegNum == GPC_IMR_COUNT) - { - base->IMR5 &= ~(1UL << irqRegShiftNum); - } - else - { - base->IMR[irqRegNum] &= ~(1UL << irqRegShiftNum); - } -#else - assert(irqRegNum > 0U); - base->IMR[irqRegNum - 1UL] &= ~(1UL << irqRegShiftNum); -#endif /* FSL_FEATURE_GPC_HAS_IRQ_0_31 */ -} - -/*! - * brief Disable the IRQ. - * - * param base GPC peripheral base address. - * param irqId ID number of IRQ to be disabled, available range is 32-159. 0-31 is available in some platforms. - */ -void GPC_DisableIRQ(GPC_Type *base, uint32_t irqId) -{ - uint32_t irqRegNum = irqId / 32U; - uint32_t irqRegShiftNum = irqId % 32U; - - assert(irqRegNum <= GPC_IMR_COUNT); - -#if ((defined FSL_FEATURE_GPC_HAS_IRQ_0_31) && FSL_FEATURE_GPC_HAS_IRQ_0_31) - if (irqRegNum == GPC_IMR_COUNT) - { - base->IMR5 |= (1UL << irqRegShiftNum); - } - else - { - base->IMR[irqRegNum] |= (1UL << irqRegShiftNum); - } -#else - assert(irqRegNum > 0U); - base->IMR[irqRegNum - 1UL] |= (1UL << irqRegShiftNum); -#endif /* FSL_FEATURE_GPC_HAS_IRQ_0_31 */ -} - -/*! - * brief Get the IRQ/Event flag. - * - * param base GPC peripheral base address. - * param irqId ID number of IRQ to be enabled, available range is 32-159. 0-31 is available in some platforms. - * return Indicated IRQ/Event is asserted or not. - */ -bool GPC_GetIRQStatusFlag(GPC_Type *base, uint32_t irqId) -{ - uint32_t irqRegNum = irqId / 32U; - uint32_t irqRegShiftNum = irqId % 32U; - uint32_t ret; - - assert(irqRegNum <= GPC_IMR_COUNT); - -#if ((defined FSL_FEATURE_GPC_HAS_IRQ_0_31) && FSL_FEATURE_GPC_HAS_IRQ_0_31) - if (irqRegNum == GPC_IMR_COUNT) - { - ret = base->ISR5 & (1UL << irqRegShiftNum); - } - else - { - ret = base->ISR[irqRegNum] & (1UL << irqRegShiftNum); - } -#else - assert(irqRegNum > 0U); - ret = base->ISR[irqRegNum - 1UL] & (1UL << irqRegShiftNum); -#endif /* FSL_FEATURE_GPC_HAS_IRQ_0_31 */ - - return (1UL << irqRegShiftNum) == ret; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpio.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpio.c deleted file mode 100644 index a3f864defc..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpio.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_gpio.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.igpio" -#endif - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Array of GPIO peripheral base address. */ -static GPIO_Type *const s_gpioBases[] = GPIO_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of GPIO clock name. */ -static const clock_ip_name_t s_gpioClock[] = GPIO_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Gets the GPIO instance according to the GPIO base - * - * @param base GPIO peripheral base pointer(PTA, PTB, PTC, etc.) - * @retval GPIO instance - */ -static uint32_t GPIO_GetInstance(GPIO_Type *base); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t GPIO_GetInstance(GPIO_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0U; instance < ARRAY_SIZE(s_gpioBases); instance++) - { - if (s_gpioBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_gpioBases)); - - return instance; -} - -/*! - * brief Initializes the GPIO peripheral according to the specified - * parameters in the initConfig. - * - * param base GPIO base pointer. - * param pin Specifies the pin number - * param initConfig pointer to a ref gpio_pin_config_t structure that - * contains the configuration information. - */ -void GPIO_PinInit(GPIO_Type *base, uint32_t pin, const gpio_pin_config_t *Config) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable GPIO clock. */ - uint32_t instance = GPIO_GetInstance(base); - - /* If The clock IP is valid, enable the clock gate. */ - if ((instance < ARRAY_SIZE(s_gpioClock)) && (kCLOCK_IpInvalid != s_gpioClock[instance])) - { - CLOCK_EnableClock(s_gpioClock[instance]); - } -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Register reset to default value */ - base->IMR &= ~(1UL << pin); - - /* Configure GPIO pin direction */ - if (Config->direction == kGPIO_DigitalInput) - { - base->GDIR &= ~(1UL << pin); - } - else - { - GPIO_PinWrite(base, pin, Config->outputLogic); - base->GDIR |= (1UL << pin); - } - - /* Configure GPIO pin interrupt mode */ - GPIO_SetPinInterruptConfig(base, pin, Config->interruptMode); -} - -/*! - * brief Sets the output level of the individual GPIO pin to logic 1 or 0. - * - * param base GPIO base pointer. - * param pin GPIO port pin number. - * param output GPIOpin output logic level. - * - 0: corresponding pin output low-logic level. - * - 1: corresponding pin output high-logic level. - */ -void GPIO_PinWrite(GPIO_Type *base, uint32_t pin, uint8_t output) -{ - assert(pin < 32U); - if (output == 0U) - { - base->DR &= ~(1UL << pin); /* Set pin output to low level.*/ - } - else - { - base->DR |= (1UL << pin); /* Set pin output to high level.*/ - } -} - -/*! - * brief Sets the current pin interrupt mode. - * - * param base GPIO base pointer. - * param pin GPIO port pin number. - * param pininterruptMode pointer to a ref gpio_interrupt_mode_t structure - * that contains the interrupt mode information. - */ -void GPIO_PinSetInterruptConfig(GPIO_Type *base, uint32_t pin, gpio_interrupt_mode_t pinInterruptMode) -{ - volatile uint32_t *icr; - uint32_t icrShift; - - icrShift = pin; - - /* Register reset to default value */ - base->EDGE_SEL &= ~(1UL << pin); - - if (pin < 16U) - { - icr = &(base->ICR1); - } - else - { - icr = &(base->ICR2); - icrShift -= 16U; - } - switch (pinInterruptMode) - { - case (kGPIO_IntLowLevel): - *icr &= ~(3UL << (2UL * icrShift)); - break; - case (kGPIO_IntHighLevel): - *icr = (*icr & (~(3UL << (2UL * icrShift)))) | (1UL << (2UL * icrShift)); - break; - case (kGPIO_IntRisingEdge): - *icr = (*icr & (~(3UL << (2UL * icrShift)))) | (2UL << (2UL * icrShift)); - break; - case (kGPIO_IntFallingEdge): - *icr |= (3UL << (2UL * icrShift)); - break; - case (kGPIO_IntRisingOrFallingEdge): - base->EDGE_SEL |= (1UL << pin); - break; - default:; /* Intentional empty default */ - break; - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpt.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpt.c deleted file mode 100644 index 050ebf1f5c..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_gpt.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_gpt.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.gpt" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to GPT bases for each instance. */ -static GPT_Type *const s_gptBases[] = GPT_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to GPT clocks for each instance. */ -static const clock_ip_name_t s_gptClocks[] = GPT_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t GPT_GetInstance(GPT_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0U; instance < ARRAY_SIZE(s_gptBases); instance++) - { - if (s_gptBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_gptBases)); - - return instance; -} - -/*! - * brief Initialize GPT to reset state and initialize running mode. - * - * param base GPT peripheral base address. - * param initConfig GPT mode setting configuration. - */ -void GPT_Init(GPT_Type *base, const gpt_config_t *initConfig) -{ - assert(NULL != initConfig); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate the GPT clock*/ - (void)CLOCK_EnableClock(s_gptClocks[GPT_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - base->CR = 0U; - - GPT_SoftwareReset(base); - - base->CR = - (initConfig->enableFreeRun ? GPT_CR_FRR_MASK : 0UL) | (initConfig->enableRunInWait ? GPT_CR_WAITEN_MASK : 0UL) | - (initConfig->enableRunInStop ? GPT_CR_STOPEN_MASK : 0UL) | - (initConfig->enableRunInDoze ? GPT_CR_DOZEEN_MASK : 0UL) | - (initConfig->enableRunInDbg ? GPT_CR_DBGEN_MASK : 0UL) | (initConfig->enableMode ? GPT_CR_ENMOD_MASK : 0UL); - - GPT_SetClockSource(base, initConfig->clockSource); - GPT_SetClockDivider(base, initConfig->divider); -} - -/*! - * brief Disables the module and gates the GPT clock. - * - * param base GPT peripheral base address. - */ -void GPT_Deinit(GPT_Type *base) -{ - /* Disable GPT timers */ - base->CR = 0U; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Gate the GPT clock*/ - (void)CLOCK_DisableClock(s_gptClocks[GPT_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Fills in the GPT configuration structure with default settings. - * - * The default values are: - * code - * config->clockSource = kGPT_ClockSource_Periph; - * config->divider = 1U; - * config->enableRunInStop = true; - * config->enableRunInWait = true; - * config->enableRunInDoze = false; - * config->enableRunInDbg = false; - * config->enableFreeRun = false; - * config->enableMode = true; - * endcode - * param config Pointer to the user configuration structure. - */ -void GPT_GetDefaultConfig(gpt_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->clockSource = kGPT_ClockSource_Periph; - config->divider = 1U; - config->enableRunInStop = true; - config->enableRunInWait = true; - config->enableRunInDoze = false; - config->enableRunInDbg = false; - config->enableFreeRun = false; - config->enableMode = true; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_kpp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_kpp.c deleted file mode 100644 index 8c0b1958be..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_kpp.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2017, 2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_kpp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.kpp" -#endif - -#define KPP_KEYPAD_SCAN_TIMES (3U) -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to SEMC clocks for each instance. */ -static const clock_ip_name_t s_kppClock[FSL_FEATURE_SOC_KPP_COUNT] = KPP_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Pointers to SEMC bases for each instance. */ -static KPP_Type *const s_kppBases[] = KPP_BASE_PTRS; - -/*! @brief Pointers to KPP IRQ number for each instance. */ -static const IRQn_Type s_kppIrqs[] = KPP_IRQS; -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t KPP_GetInstance(KPP_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_kppBases); instance++) - { - if (s_kppBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_kppBases)); - - return instance; -} -static void KPP_Mdelay(uint64_t tickets) -{ - while ((tickets--) != 0UL) - { - __NOP(); - } -} - -/*! - * brief KPP initialize. - * This function ungates the KPP clock and initializes KPP. - * This function must be called before calling any other KPP driver functions. - * - * param base KPP peripheral base address. - * param configure The KPP configuration structure pointer. - */ -void KPP_Init(KPP_Type *base, kpp_config_t *configure) -{ - assert(configure); - - uint32_t instance = KPP_GetInstance(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Un-gate sdram controller clock. */ - CLOCK_EnableClock(s_kppClock[KPP_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Clear all. */ - base->KPSR &= (uint16_t)(~(KPP_KPSR_KRIE_MASK | KPP_KPSR_KDIE_MASK)); - - /* Enable the keypad row and set the column strobe output to open drain. */ - base->KPCR = KPP_KPCR_KRE(configure->activeRow); - base->KPDR = KPP_KPDR_KCD((uint8_t) ~(configure->activeColumn)); - base->KPCR |= KPP_KPCR_KCO(configure->activeColumn); - - /* Set the input direction for row and output direction for column. */ - base->KDDR = KPP_KDDR_KCDD(configure->activeColumn) | KPP_KDDR_KRDD((uint8_t) ~(configure->activeRow)); - - /* Clear the status flag and enable the interrupt. */ - base->KPSR = KPP_KPSR_KPKR_MASK | KPP_KPSR_KPKD_MASK | KPP_KPSR_KDSC_MASK | configure->interrupt; - - if ((configure->interrupt) != 0U) - { - /* Enable at the Interrupt */ - (void)EnableIRQ(s_kppIrqs[instance]); - } -} - -/*! - * brief Deinitializes the KPP module and gates the clock. - * This function gates the KPP clock. As a result, the KPP - * module doesn't work after calling this function. - * - * param base KPP peripheral base address. - */ -void KPP_Deinit(KPP_Type *base) -{ - /* Disable interrupts and disable all rows. */ - base->KPSR &= (uint16_t)(~(KPP_KPSR_KRIE_MASK | KPP_KPSR_KDIE_MASK)); - base->KPCR = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable KPP clock. */ - CLOCK_DisableClock(s_kppClock[KPP_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Keypad press scanning. - * - * This function will scanning all columns and rows. so - * all scanning data will be stored in the data pointer. - * - * param base KPP peripheral base address. - * param data KPP key press scanning data. The data buffer should be prepared with - * length at least equal to KPP_KEYPAD_COLUMNNUM_MAX * KPP_KEYPAD_ROWNUM_MAX. - * the data pointer is recommended to be a array like uint8_t data[KPP_KEYPAD_COLUMNNUM_MAX]. - * for example the data[2] = 4, that means in column 1 row 2 has a key press event. - * param clockSrc_Hz Source clock. - */ -void KPP_keyPressScanning(KPP_Type *base, uint8_t *data, uint32_t clockSrc_Hz) -{ - assert(data); - - uint16_t kppKCO = base->KPCR & KPP_KPCR_KCO_MASK; - uint8_t columIndex = 0; - uint8_t activeColumn = (uint8_t)((base->KPCR & KPP_KPCR_KCO_MASK) >> KPP_KPCR_KCO_SHIFT); - uint8_t times; - uint8_t rowData[KPP_KEYPAD_SCAN_TIMES][KPP_KEYPAD_COLUMNNUM_MAX]; - bool press = false; - uint8_t column; - - /* Initialize row data to zero. */ - (void)memset(&rowData[0][0], 0, sizeof(rowData)); - - /* Scanning. */ - /* Configure the column data to 1 according to column numbers. */ - base->KPDR = KPP_KPDR_KCD_MASK; - /* Configure column to totem pole for quick discharge of keypad capacitance. */ - base->KPCR &= (uint16_t)(((uint16_t)~kppKCO) | KPP_KPCR_KRE_MASK); - /* Recover. */ - base->KPCR |= kppKCO; - /* Three times scanning. */ - for (times = 0; times < KPP_KEYPAD_SCAN_TIMES; times++) - { - for (columIndex = 0; columIndex < KPP_KEYPAD_COLUMNNUM_MAX; columIndex++) - { - column = activeColumn & (1U << columIndex); - if (column != 0U) - { - /* Set the single column line to 0. */ - base->KPDR = KPP_KPDR_KCD(~(uint16_t)column); - /* Take 100us delays. */ - KPP_Mdelay(((uint64_t)clockSrc_Hz / 10000000UL)); - /* Read row data. */ - rowData[times][columIndex] = (uint8_t)(~(base->KPDR & KPP_KPDR_KRD_MASK)); - } - else - { - /* Read row data. */ - rowData[times][columIndex] = 0; - } - } - } - - /* Return all columns to 0 in preparation for standby mode. */ - base->KPDR &= (uint16_t)(~KPP_KPDR_KCD_MASK); - - /* Check if three time scan data is the same. */ - for (columIndex = 0; columIndex < KPP_KEYPAD_COLUMNNUM_MAX; columIndex++) - { - if (((uint8_t)(rowData[0][columIndex] & rowData[1][columIndex]) & rowData[2][columIndex]) != 0U) - { - press = true; - } - } - - if (press) - { - (void)memcpy(data, &rowData[0][0], sizeof(rowData[0])); - } - else - { - (void)memset(data, 0, sizeof(rowData[0])); - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c.c deleted file mode 100644 index f8d6f55e95..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c.c +++ /dev/null @@ -1,2315 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpi2c.h" -#include <stdlib.h> -#include <string.h> - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpi2c" -#endif - -/*! @brief Common sets of flags used by the driver. */ -enum -{ - /*! All flags which are cleared by the driver upon starting a transfer. */ - kMasterClearFlags = kLPI2C_MasterEndOfPacketFlag | kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | - kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | kLPI2C_MasterPinLowTimeoutFlag | - kLPI2C_MasterDataMatchFlag, - - /*! IRQ sources enabled by the non-blocking transactional API. */ - kMasterIrqFlags = kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterTxReadyFlag | kLPI2C_MasterRxReadyFlag | - kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | kLPI2C_MasterPinLowTimeoutFlag | - kLPI2C_MasterFifoErrFlag, - - /*! Errors to check for. */ - kMasterErrorFlags = kLPI2C_MasterNackDetectFlag | kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | - kLPI2C_MasterPinLowTimeoutFlag, - - /*! All flags which are cleared by the driver upon starting a transfer. */ - kSlaveClearFlags = kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveBitErrFlag | - kLPI2C_SlaveFifoErrFlag, - - /*! IRQ sources enabled by the non-blocking transactional API. */ - kSlaveIrqFlags = kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | - kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag | - kLPI2C_SlaveTransmitAckFlag | kLPI2C_SlaveAddressValidFlag, - - /*! Errors to check for. */ - kSlaveErrorFlags = kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag, -}; - -/* ! @brief LPI2C master fifo commands. */ -enum -{ - kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */ - kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */ - kStopCmd = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */ - kStartCmd = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */ -}; - -/*! - * @brief Default watermark values. - * - * The default watermarks are set to zero. - */ -enum -{ - kDefaultTxWatermark = 0, - kDefaultRxWatermark = 0, -}; - -/*! @brief States for the state machine used by transactional APIs. */ -enum -{ - kIdleState = 0, - kSendCommandState, - kIssueReadCommandState, - kTransferDataState, - kStopState, - kWaitForCompletionState, -}; - -/*! @brief Typedef for master interrupt handler. */ -typedef void (*lpi2c_master_isr_t)(LPI2C_Type *base, lpi2c_master_handle_t *handle); - -/*! @brief Typedef for slave interrupt handler. */ -typedef void (*lpi2c_slave_isr_t)(LPI2C_Type *base, lpi2c_slave_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/* Not static so it can be used from fsl_lpi2c_edma.c. */ -uint32_t LPI2C_GetInstance(LPI2C_Type *base); - -static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz, - uint32_t width_ns, - uint32_t maxCycles, - uint32_t prescaler); - -static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base); - -static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone); - -static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle); - -static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags); - -static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/*! @brief Array to map LPI2C instance number to base pointer. */ -static LPI2C_Type *const kLpi2cBases[] = LPI2C_BASE_PTRS; - -/*! @brief Array to map LPI2C instance number to IRQ number. */ -static IRQn_Type const kLpi2cIrqs[] = LPI2C_IRQS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Array to map LPI2C instance number to clock gate enum. */ -static clock_ip_name_t const kLpi2cClocks[] = LPI2C_CLOCKS; - -#if defined(LPI2C_PERIPH_CLOCKS) -/*! @brief Array to map LPI2C instance number to pheripheral clock gate enum. */ -static const clock_ip_name_t kLpi2cPeriphClocks[] = LPI2C_PERIPH_CLOCKS; -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Pointer to master IRQ handler for each instance. */ -static lpi2c_master_isr_t s_lpi2cMasterIsr; - -/*! @brief Pointers to master handles for each instance. */ -static lpi2c_master_handle_t *s_lpi2cMasterHandle[ARRAY_SIZE(kLpi2cBases)]; - -/*! @brief Pointer to slave IRQ handler for each instance. */ -static lpi2c_slave_isr_t s_lpi2cSlaveIsr; - -/*! @brief Pointers to slave handles for each instance. */ -static lpi2c_slave_handle_t *s_lpi2cSlaveHandle[ARRAY_SIZE(kLpi2cBases)]; - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * @brief Returns an instance number given a base address. - * - * If an invalid base address is passed, debug builds will assert. Release builds will just return - * instance number 0. - * - * @param base The LPI2C peripheral base address. - * @return LPI2C instance number starting from 0. - */ -uint32_t LPI2C_GetInstance(LPI2C_Type *base) -{ - uint32_t instance; - for (instance = 0U; instance < ARRAY_SIZE(kLpi2cBases); ++instance) - { - if (kLpi2cBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(kLpi2cBases)); - return instance; -} - -/*! - * @brief Computes a cycle count for a given time in nanoseconds. - * @param sourceClock_Hz LPI2C functional clock frequency in Hertz. - * @param width_ns Desired with in nanoseconds. - * @param maxCycles Maximum cycle count, determined by the number of bits wide the cycle count field is. - * @param prescaler LPI2C prescaler setting. Pass 1 if the prescaler should not be used, as for slave glitch widths. - */ -static uint32_t LPI2C_GetCyclesForWidth(uint32_t sourceClock_Hz, - uint32_t width_ns, - uint32_t maxCycles, - uint32_t prescaler) -{ - assert(sourceClock_Hz > 0U); - assert(prescaler > 0U); - - uint32_t busCycle_ns = 1000000U / (sourceClock_Hz / prescaler / 1000U); - uint32_t cycles = 0U; - - /* Search for the cycle count just below the desired glitch width. */ - while ((((cycles + 1U) * busCycle_ns) < width_ns) && (cycles + 1U < maxCycles)) - { - ++cycles; - } - - /* If we end up with zero cycles, then set the filter to a single cycle unless the */ - /* bus clock is greater than 10x the desired glitch width. */ - if ((cycles == 0U) && (busCycle_ns <= (width_ns * 10U))) - { - cycles = 1U; - } - - return cycles; -} - -/*! - * @brief Convert provided flags to status code, and clear any errors if present. - * @param base The LPI2C peripheral base address. - * @param status Current status flags value that will be checked. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_PinLowTimeout - * @retval #kStatus_LPI2C_ArbitrationLost - * @retval #kStatus_LPI2C_Nak - * @retval #kStatus_LPI2C_FifoError - */ -/* Not static so it can be used from fsl_lpi2c_edma.c. */ -status_t LPI2C_MasterCheckAndClearError(LPI2C_Type *base, uint32_t status) -{ - status_t result = kStatus_Success; - - /* Check for error. These errors cause a stop to automatically be sent. We must */ - /* clear the errors before a new transfer can start. */ - status &= (uint32_t)kMasterErrorFlags; - if (0U != status) - { - /* Select the correct error code. Ordered by severity, with bus issues first. */ - if (0U != (status & (uint32_t)kLPI2C_MasterPinLowTimeoutFlag)) - { - result = kStatus_LPI2C_PinLowTimeout; - } - else if (0U != (status & (uint32_t)kLPI2C_MasterArbitrationLostFlag)) - { - result = kStatus_LPI2C_ArbitrationLost; - } - else if (0U != (status & (uint32_t)kLPI2C_MasterNackDetectFlag)) - { - result = kStatus_LPI2C_Nak; - } - else if (0U != (status & (uint32_t)kLPI2C_MasterFifoErrFlag)) - { - result = kStatus_LPI2C_FifoError; - } - else - { - ; /* Intentional empty */ - } - - /* Clear the flags. */ - LPI2C_MasterClearStatusFlags(base, status); - - /* Reset fifos. These flags clear automatically. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; - } - else - { - ; /* Intentional empty */ - } - - return result; -} - -/*! - * @brief Wait until there is room in the tx fifo. - * @param base The LPI2C peripheral base address. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_PinLowTimeout - * @retval #kStatus_LPI2C_ArbitrationLost - * @retval #kStatus_LPI2C_Nak - * @retval #kStatus_LPI2C_FifoError - */ -static status_t LPI2C_MasterWaitForTxReady(LPI2C_Type *base) -{ - uint32_t status; - size_t txCount; - size_t txFifoSize = (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base); - -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - do - { - status_t result; - - /* Get the number of words in the tx fifo and compute empty slots. */ - LPI2C_MasterGetFifoCounts(base, NULL, &txCount); - txCount = txFifoSize - txCount; - - /* Check for error flags. */ - status = LPI2C_MasterGetStatusFlags(base); - result = LPI2C_MasterCheckAndClearError(base, status); - if (kStatus_Success != result) - { - return result; - } -#if I2C_RETRY_TIMES - } while ((0U == txCount) && (0U != --waitTimes)); - - if (0U == waitTimes) - { - return kStatus_LPI2C_Timeout; - } -#else - } while (0U == txCount); -#endif - - return kStatus_Success; -} - -/*! - * @brief Make sure the bus isn't already busy. - * - * A busy bus is allowed if we are the one driving it. - * - * @param base The LPI2C peripheral base address. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_Busy - */ -/* Not static so it can be used from fsl_lpi2c_edma.c. */ -status_t LPI2C_CheckForBusyBus(LPI2C_Type *base) -{ - status_t ret = kStatus_Success; - - uint32_t status = LPI2C_MasterGetStatusFlags(base); - if ((0U != (status & (uint32_t)kLPI2C_MasterBusBusyFlag)) && (0U == (status & (uint32_t)kLPI2C_MasterBusyFlag))) - { - ret = kStatus_LPI2C_Busy; - } - - return ret; -} - -/*! - * brief Provides a default configuration for the LPI2C master peripheral. - * - * This function provides the following default configuration for the LPI2C master peripheral: - * code - * masterConfig->enableMaster = true; - * masterConfig->debugEnable = false; - * masterConfig->ignoreAck = false; - * masterConfig->pinConfig = kLPI2C_2PinOpenDrain; - * masterConfig->baudRate_Hz = 100000U; - * masterConfig->busIdleTimeout_ns = 0U; - * masterConfig->pinLowTimeout_ns = 0U; - * masterConfig->sdaGlitchFilterWidth_ns = 0U; - * masterConfig->sclGlitchFilterWidth_ns = 0U; - * masterConfig->hostRequest.enable = false; - * masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin; - * masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh; - * endcode - * - * After calling this function, you can override any settings in order to customize the configuration, - * prior to initializing the master driver with LPI2C_MasterInit(). - * - * param[out] masterConfig User provided configuration structure for default values. Refer to #lpi2c_master_config_t. - */ -void LPI2C_MasterGetDefaultConfig(lpi2c_master_config_t *masterConfig) -{ - /* Initializes the configure structure to zero. */ - (void)memset(masterConfig, 0, sizeof(*masterConfig)); - - masterConfig->enableMaster = true; - masterConfig->debugEnable = false; - masterConfig->enableDoze = true; - masterConfig->ignoreAck = false; - masterConfig->pinConfig = kLPI2C_2PinOpenDrain; - masterConfig->baudRate_Hz = 100000U; - masterConfig->busIdleTimeout_ns = 0U; - masterConfig->pinLowTimeout_ns = 0U; - masterConfig->sdaGlitchFilterWidth_ns = 0U; - masterConfig->sclGlitchFilterWidth_ns = 0U; - masterConfig->hostRequest.enable = false; - masterConfig->hostRequest.source = kLPI2C_HostRequestExternalPin; - masterConfig->hostRequest.polarity = kLPI2C_HostRequestPinActiveHigh; -} - -/*! - * brief Initializes the LPI2C master peripheral. - * - * This function enables the peripheral clock and initializes the LPI2C master peripheral as described by the user - * provided configuration. A software reset is performed prior to configuration. - * - * param base The LPI2C peripheral base address. - * param masterConfig User provided peripheral configuration. Use LPI2C_MasterGetDefaultConfig() to get a set of - * defaults - * that you can override. - * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the baud rate divisors, - * filter widths, and timeout periods. - */ -void LPI2C_MasterInit(LPI2C_Type *base, const lpi2c_master_config_t *masterConfig, uint32_t sourceClock_Hz) -{ - uint32_t prescaler; - uint32_t cycles; - uint32_t cfgr2; - uint32_t value; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPI2C_GetInstance(base); - - /* Ungate the clock. */ - CLOCK_EnableClock(kLpi2cClocks[instance]); -#if defined(LPI2C_PERIPH_CLOCKS) - /* Ungate the functional clock in initialize function. */ - CLOCK_EnableClock(kLpi2cPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Reset peripheral before configuring it. */ - LPI2C_MasterReset(base); - - /* Doze bit: 0 is enable, 1 is disable */ - base->MCR = LPI2C_MCR_DBGEN(masterConfig->debugEnable) | LPI2C_MCR_DOZEN(!(masterConfig->enableDoze)); - - /* host request */ - value = base->MCFGR0; - value &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK | LPI2C_MCFGR0_HRSEL_MASK)); - value |= LPI2C_MCFGR0_HREN(masterConfig->hostRequest.enable) | - LPI2C_MCFGR0_HRPOL(masterConfig->hostRequest.polarity) | - LPI2C_MCFGR0_HRSEL(masterConfig->hostRequest.source); - base->MCFGR0 = value; - - /* pin config and ignore ack */ - value = base->MCFGR1; - value &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK); - value |= LPI2C_MCFGR1_PINCFG(masterConfig->pinConfig); - value |= LPI2C_MCFGR1_IGNACK(masterConfig->ignoreAck); - base->MCFGR1 = value; - - LPI2C_MasterSetWatermarks(base, (size_t)kDefaultTxWatermark, (size_t)kDefaultRxWatermark); - - LPI2C_MasterSetBaudRate(base, sourceClock_Hz, masterConfig->baudRate_Hz); - - /* Configure glitch filters and bus idle and pin low timeouts. */ - prescaler = (base->MCFGR1 & LPI2C_MCFGR1_PRESCALE_MASK) >> LPI2C_MCFGR1_PRESCALE_SHIFT; - cfgr2 = base->MCFGR2; - if (0U != (masterConfig->busIdleTimeout_ns)) - { - cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->busIdleTimeout_ns, - (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler); - cfgr2 &= ~LPI2C_MCFGR2_BUSIDLE_MASK; - cfgr2 |= LPI2C_MCFGR2_BUSIDLE(cycles); - } - if (0U != (masterConfig->sdaGlitchFilterWidth_ns)) - { - cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sdaGlitchFilterWidth_ns, - (LPI2C_MCFGR2_FILTSDA_MASK >> LPI2C_MCFGR2_FILTSDA_SHIFT), 1U); - cfgr2 &= ~LPI2C_MCFGR2_FILTSDA_MASK; - cfgr2 |= LPI2C_MCFGR2_FILTSDA(cycles); - } - if (0U != masterConfig->sclGlitchFilterWidth_ns) - { - cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->sclGlitchFilterWidth_ns, - (LPI2C_MCFGR2_FILTSCL_MASK >> LPI2C_MCFGR2_FILTSCL_SHIFT), 1U); - cfgr2 &= ~LPI2C_MCFGR2_FILTSCL_MASK; - cfgr2 |= LPI2C_MCFGR2_FILTSCL(cycles); - } - base->MCFGR2 = cfgr2; - if (0U != masterConfig->pinLowTimeout_ns) - { - cycles = LPI2C_GetCyclesForWidth(sourceClock_Hz, masterConfig->pinLowTimeout_ns / 256U, - (LPI2C_MCFGR2_BUSIDLE_MASK >> LPI2C_MCFGR2_BUSIDLE_SHIFT), prescaler); - base->MCFGR3 = (base->MCFGR3 & ~LPI2C_MCFGR3_PINLOW_MASK) | LPI2C_MCFGR3_PINLOW(cycles); - } - - LPI2C_MasterEnable(base, masterConfig->enableMaster); -} - -/*! - * brief Deinitializes the LPI2C master peripheral. - * - * This function disables the LPI2C master peripheral and gates the clock. It also performs a software - * reset to restore the peripheral to reset conditions. - * - * param base The LPI2C peripheral base address. - */ -void LPI2C_MasterDeinit(LPI2C_Type *base) -{ - /* Restore to reset state. */ - LPI2C_MasterReset(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPI2C_GetInstance(base); - - /* Gate clock. */ - CLOCK_DisableClock(kLpi2cClocks[instance]); -#if defined(LPI2C_PERIPH_CLOCKS) - /* Gate the functional clock. */ - CLOCK_DisableClock(kLpi2cPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Configures LPI2C master data match feature. - * - * param base The LPI2C peripheral base address. - * param config Settings for the data match feature. - */ -void LPI2C_MasterConfigureDataMatch(LPI2C_Type *base, const lpi2c_data_match_config_t *config) -{ - /* Disable master mode. */ - bool wasEnabled = (0U != ((base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT)); - LPI2C_MasterEnable(base, false); - - base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_MATCFG_MASK) | LPI2C_MCFGR1_MATCFG(config->matchMode); - base->MCFGR0 = (base->MCFGR0 & ~LPI2C_MCFGR0_RDMO_MASK) | LPI2C_MCFGR0_RDMO(config->rxDataMatchOnly); - base->MDMR = LPI2C_MDMR_MATCH0(config->match0) | LPI2C_MDMR_MATCH1(config->match1); - - /* Restore master mode. */ - if (wasEnabled) - { - LPI2C_MasterEnable(base, true); - } -} - -/*! - * brief Sets the I2C bus frequency for master transactions. - * - * The LPI2C master is automatically disabled and re-enabled as necessary to configure the baud - * rate. Do not call this function during a transfer, or the transfer is aborted. - * - * note Please note that the second parameter is the clock frequency of LPI2C module, the third - * parameter means user configured bus baudrate, this implementation is different from other I2C drivers - * which use baudrate configuration as second parameter and source clock frequency as third parameter. - * - * param base The LPI2C peripheral base address. - * param sourceClock_Hz LPI2C functional clock frequency in Hertz. - * param baudRate_Hz Requested bus frequency in Hertz. - */ -void LPI2C_MasterSetBaudRate(LPI2C_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Hz) -{ - uint32_t prescale = 0U; - uint32_t bestPre = 0U; - uint32_t bestClkHi = 0U; - uint32_t absError = 0U; - uint32_t bestError = 0xffffffffu; - uint32_t value; - uint32_t clkHiCycle; - uint32_t computedRate; - uint32_t i; - bool wasEnabled; - - /* Disable master mode. */ - wasEnabled = (0U != ((base->MCR & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT)); - LPI2C_MasterEnable(base, false); - - /* Baud rate = (sourceClock_Hz/2^prescale)/(CLKLO+1+CLKHI+1 + ROUNDDOWN((2+FILTSCL)/2^prescale) */ - /* Assume CLKLO = 2*CLKHI, SETHOLD = CLKHI, DATAVD = CLKHI/2. */ - for (prescale = 1U; prescale <= 128U; prescale = 2U * prescale) - { - if (bestError == 0U) - { - break; - } - - for (clkHiCycle = 1U; clkHiCycle < 32U; clkHiCycle++) - { - if (clkHiCycle == 1U) - { - computedRate = (sourceClock_Hz / prescale) / (1U + 3U + 2U + 2U / prescale); - } - else - { - computedRate = (sourceClock_Hz / prescale) / (3U * clkHiCycle + 2U + 2U / prescale); - } - - absError = baudRate_Hz > computedRate ? baudRate_Hz - computedRate : computedRate - baudRate_Hz; - - if (absError < bestError) - { - bestPre = prescale; - bestClkHi = clkHiCycle; - bestError = absError; - - /* If the error is 0, then we can stop searching because we won't find a better match. */ - if (absError == 0U) - { - break; - } - } - } - } - - /* Standard, fast, fast mode plus and ultra-fast transfers. */ - value = LPI2C_MCCR0_CLKHI(bestClkHi); - - if (bestClkHi < 2U) - { - value |= (uint32_t)(LPI2C_MCCR0_CLKLO(3UL) | LPI2C_MCCR0_SETHOLD(2UL) | LPI2C_MCCR0_DATAVD(1UL)); - } - else - { - value |= - LPI2C_MCCR0_CLKLO(2UL * bestClkHi) | LPI2C_MCCR0_SETHOLD(bestClkHi) | LPI2C_MCCR0_DATAVD(bestClkHi / 2UL); - } - - base->MCCR0 = value; - - for (i = 0U; i < 8U; i++) - { - if (bestPre == (1UL << i)) - { - bestPre = i; - break; - } - } - base->MCFGR1 = (base->MCFGR1 & ~LPI2C_MCFGR1_PRESCALE_MASK) | LPI2C_MCFGR1_PRESCALE(bestPre); - - /* Restore master mode. */ - if (wasEnabled) - { - LPI2C_MasterEnable(base, true); - } -} - -/*! - * brief Sends a START signal and slave address on the I2C bus. - * - * This function is used to initiate a new master mode transfer. First, the bus state is checked to ensure - * that another master is not occupying the bus. Then a START signal is transmitted, followed by the - * 7-bit address specified in the a address parameter. Note that this function does not actually wait - * until the START and address are successfully sent on the bus before returning. - * - * param base The LPI2C peripheral base address. - * param address 7-bit slave device address, in bits [6:0]. - * param dir Master transfer direction, either #kLPI2C_Read or #kLPI2C_Write. This parameter is used to set - * the R/w bit (bit 0) in the transmitted slave address. - * retval #kStatus_Success START signal and address were successfully enqueued in the transmit FIFO. - * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. - */ -status_t LPI2C_MasterStart(LPI2C_Type *base, uint8_t address, lpi2c_direction_t dir) -{ - /* Return an error if the bus is already in use not by us. */ - status_t result = LPI2C_CheckForBusyBus(base); - if (kStatus_Success != result) - { - return result; - } - - /* Clear all flags. */ - LPI2C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags); - - /* Turn off auto-stop option. */ - base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; - - /* Wait until there is room in the fifo. */ - result = LPI2C_MasterWaitForTxReady(base); - if (kStatus_Success != result) - { - return result; - } - - /* Issue start command. */ - base->MTDR = (uint32_t)kStartCmd | (((uint32_t)address << 1U) | (uint32_t)dir); - - return kStatus_Success; -} - -/*! - * brief Sends a STOP signal on the I2C bus. - * - * This function does not return until the STOP signal is seen on the bus, or an error occurs. - * - * param base The LPI2C peripheral base address. - * retval #kStatus_Success The STOP signal was successfully sent on the bus and the transaction terminated. - * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. - * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. - * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. - * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. - * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. - */ -status_t LPI2C_MasterStop(LPI2C_Type *base) -{ - /* Wait until there is room in the fifo. */ - status_t result = LPI2C_MasterWaitForTxReady(base); - if (kStatus_Success != result) - { - return result; - } - - /* Send the STOP signal */ - base->MTDR = (uint32_t)kStopCmd; - -/* Wait for the stop detected flag to set, indicating the transfer has completed on the bus. */ -/* Also check for errors while waiting. */ -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - -#if I2C_RETRY_TIMES - while ((result == kStatus_Success) && (0U != --waitTimes)) -#else - while (result == kStatus_Success) -#endif - { - uint32_t status = LPI2C_MasterGetStatusFlags(base); - - /* Check for error flags. */ - result = LPI2C_MasterCheckAndClearError(base, status); - - /* Check if the stop was sent successfully. */ - if ((0U != (status & (uint32_t)kLPI2C_MasterStopDetectFlag)) && - (0U != (status & (uint32_t)kLPI2C_MasterTxReadyFlag))) - { - LPI2C_MasterClearStatusFlags(base, (uint32_t)kLPI2C_MasterStopDetectFlag); - break; - } - } - -#if I2C_RETRY_TIMES - if (0U == waitTimes) - { - return kStatus_LPI2C_Timeout; - } -#endif - - return result; -} - -/*! - * brief Performs a polling receive transfer on the I2C bus. - * - * param base The LPI2C peripheral base address. - * param rxBuff The pointer to the data to be transferred. - * param rxSize The length in bytes of the data to be transferred. - * retval #kStatus_Success Data was received successfully. - * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. - * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. - * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. - * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. - * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. - */ -status_t LPI2C_MasterReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize) -{ - status_t result; - uint8_t *buf; -#if I2C_RETRY_TIMES - uint32_t waitTimes; -#endif - - assert(NULL != rxBuff); - - /* Handle empty read. */ - if (rxSize == 0U) - { - return kStatus_Success; - } - - /* Wait until there is room in the command fifo. */ - result = LPI2C_MasterWaitForTxReady(base); - if (kStatus_Success != result) - { - return result; - } - - /* Issue command to receive data. */ - base->MTDR = ((uint32_t)kRxDataCmd) | LPI2C_MTDR_DATA(rxSize - 1U); - - /* Receive data */ - buf = (uint8_t *)rxBuff; - while (0U != (rxSize--)) - { -#if I2C_RETRY_TIMES - waitTimes = I2C_RETRY_TIMES; -#endif - /* Read LPI2C receive fifo register. The register includes a flag to indicate whether */ - /* the FIFO is empty, so we can both get the data and check if we need to keep reading */ - /* using a single register read. */ - uint32_t value; - do - { - /* Check for errors. */ - result = LPI2C_MasterCheckAndClearError(base, LPI2C_MasterGetStatusFlags(base)); - if (kStatus_Success != result) - { - return result; - } - - value = base->MRDR; -#if I2C_RETRY_TIMES - } while ((0U != (value & LPI2C_MRDR_RXEMPTY_MASK)) && (0U != --waitTimes)); - if (0U == waitTimes) - { - return kStatus_LPI2C_Timeout; - } -#else - } while (0U != (value & LPI2C_MRDR_RXEMPTY_MASK)); -#endif - - *buf++ = (uint8_t)(value & LPI2C_MRDR_DATA_MASK); - } - - return kStatus_Success; -} - -/*! - * brief Performs a polling send transfer on the I2C bus. - * - * Sends up to a txSize number of bytes to the previously addressed slave device. The slave may - * reply with a NAK to any byte in order to terminate the transfer early. If this happens, this - * function returns #kStatus_LPI2C_Nak. - * - * param base The LPI2C peripheral base address. - * param txBuff The pointer to the data to be transferred. - * param txSize The length in bytes of the data to be transferred. - * retval #kStatus_Success Data was sent successfully. - * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. - * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. - * retval #kStatus_LPI2C_FifoError FIFO under run or over run. - * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. - * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. - */ -status_t LPI2C_MasterSend(LPI2C_Type *base, void *txBuff, size_t txSize) -{ - uint8_t *buf = (uint8_t *)txBuff; - - assert(NULL != txBuff); - - /* Send data buffer */ - while (0U != (txSize--)) - { - /* Wait until there is room in the fifo. This also checks for errors. */ - status_t result = LPI2C_MasterWaitForTxReady(base); - if (kStatus_Success != result) - { - return result; - } - - /* Write byte into LPI2C master data register. */ - base->MTDR = *buf++; - } - - return kStatus_Success; -} - -/*! - * brief Performs a master polling transfer on the I2C bus. - * - * note The API does not return until the transfer succeeds or fails due - * to error happens during transfer. - * - * param base The LPI2C peripheral base address. - * param transfer Pointer to the transfer structure. - * retval #kStatus_Success Data was received successfully. - * retval #kStatus_LPI2C_Busy Another master is currently utilizing the bus. - * retval #kStatus_LPI2C_Nak The slave device sent a NAK in response to a byte. - * retval #kStatus_LPI2C_FifoError FIFO under run or overrun. - * retval #kStatus_LPI2C_ArbitrationLost Arbitration lost error. - * retval #kStatus_LPI2C_PinLowTimeout SCL or SDA were held low longer than the timeout. - */ -status_t LPI2C_MasterTransferBlocking(LPI2C_Type *base, lpi2c_master_transfer_t *transfer) -{ - status_t result = kStatus_Success; - uint16_t commandBuffer[7]; - uint32_t cmdCount = 0U; - - assert(NULL != transfer); - assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); - - /* Return an error if the bus is already in use not by us. */ - result = LPI2C_CheckForBusyBus(base); - if (kStatus_Success != result) - { - return result; - } - - /* Clear all flags. */ - LPI2C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags); - - /* Turn off auto-stop option. */ - base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; - - lpi2c_direction_t direction = (0U != transfer->subaddressSize) ? kLPI2C_Write : transfer->direction; - if (0U == (transfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag)) - { - commandBuffer[cmdCount++] = - (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)direction); - } - - /* Subaddress, MSB first. */ - if (0U != transfer->subaddressSize) - { - uint32_t subaddressRemaining = transfer->subaddressSize; - while (0U != subaddressRemaining--) - { - uint8_t subaddressByte = (uint8_t)((transfer->subaddress >> (8U * subaddressRemaining)) & 0xffU); - commandBuffer[cmdCount++] = subaddressByte; - } - } - - /* Reads need special handling. */ - if ((0U != transfer->dataSize) && (transfer->direction == kLPI2C_Read)) - { - /* Need to send repeated start if switching directions to read. */ - if (direction == kLPI2C_Write) - { - commandBuffer[cmdCount++] = - (uint16_t)kStartCmd | - (uint16_t)((uint16_t)((uint16_t)transfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read); - } - } - - /* Send command buffer */ - uint32_t index = 0U; - while (0U != cmdCount--) - { - /* Wait until there is room in the fifo. This also checks for errors. */ - result = LPI2C_MasterWaitForTxReady(base); - if (kStatus_Success != result) - { - return result; - } - - /* Write byte into LPI2C master data register. */ - base->MTDR = commandBuffer[index]; - index++; - } - - /* Transmit data. */ - if ((transfer->direction == kLPI2C_Write) && (transfer->dataSize > 0U)) - { - /* Send Data. */ - result = LPI2C_MasterSend(base, transfer->data, transfer->dataSize); - } - - /* Receive Data. */ - if ((transfer->direction == kLPI2C_Read) && (transfer->dataSize > 0U)) - { - result = LPI2C_MasterReceive(base, transfer->data, transfer->dataSize); - } - - if (kStatus_Success != result) - { - return result; - } - - if ((transfer->flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U) - { - result = LPI2C_MasterStop(base); - } - - return result; -} - -/*! - * brief Creates a new handle for the LPI2C master non-blocking APIs. - * - * The creation of a handle is for use with the non-blocking APIs. Once a handle - * is created, there is not a corresponding destroy handle. If the user wants to - * terminate a transfer, the LPI2C_MasterTransferAbort() API shall be called. - * - * - * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice - * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to - * enable the associated INTMUX IRQ in application. - * - * param base The LPI2C peripheral base address. - * param[out] handle Pointer to the LPI2C master driver handle. - * param callback User provided pointer to the asynchronous callback function. - * param userData User provided pointer to the application callback data. - */ -void LPI2C_MasterTransferCreateHandle(LPI2C_Type *base, - lpi2c_master_handle_t *handle, - lpi2c_master_transfer_callback_t callback, - void *userData) -{ - uint32_t instance; - - assert(NULL != handle); - - /* Clear out the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Look up instance number */ - instance = LPI2C_GetInstance(base); - - /* Save base and instance. */ - handle->completionCallback = callback; - handle->userData = userData; - - /* Save this handle for IRQ use. */ - s_lpi2cMasterHandle[instance] = handle; - - /* Set irq handler. */ - s_lpi2cMasterIsr = LPI2C_MasterTransferHandleIRQ; - - /* Clear internal IRQ enables and enable NVIC IRQ. */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kMasterIrqFlags); - - /* Enable NVIC IRQ, this only enables the IRQ directly connected to the NVIC. - In some cases the LPI2C IRQ is configured through INTMUX, user needs to enable - INTMUX IRQ in application code. */ - (void)EnableIRQ(kLpi2cIrqs[instance]); -} - -/*! - * @brief Execute states until FIFOs are exhausted. - * @param handle Master nonblocking driver handle. - * @param[out] isDone Set to true if the transfer has completed. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_PinLowTimeout - * @retval #kStatus_LPI2C_ArbitrationLost - * @retval #kStatus_LPI2C_Nak - * @retval #kStatus_LPI2C_FifoError - */ -static status_t LPI2C_RunTransferStateMachine(LPI2C_Type *base, lpi2c_master_handle_t *handle, bool *isDone) -{ - uint32_t status; - status_t result = kStatus_Success; - lpi2c_master_transfer_t *xfer; - size_t txCount; - size_t rxCount; - size_t txFifoSize = (size_t)FSL_FEATURE_LPI2C_FIFO_SIZEn(base); - bool state_complete = false; - uint16_t sendval; - - /* Set default isDone return value. */ - *isDone = false; - - /* Check for errors. */ - status = LPI2C_MasterGetStatusFlags(base); - /* For the last byte, nack flag is expected. - Do not check and clear kLPI2C_MasterNackDetectFlag for the last byte, - in case FIFO is emptied when stop command has not been sent. */ - if (handle->remainingBytes == 0U) - { - status &= ~(uint32_t)kLPI2C_MasterNackDetectFlag; - } - result = LPI2C_MasterCheckAndClearError(base, status); - if (kStatus_Success != result) - { - return result; - } - - /* Get pointer to private data. */ - xfer = &handle->transfer; - - /* Get fifo counts and compute room in tx fifo. */ - LPI2C_MasterGetFifoCounts(base, &rxCount, &txCount); - txCount = txFifoSize - txCount; - - while (!state_complete) - { - /* Execute the state. */ - switch (handle->state) - { - case (uint8_t)kSendCommandState: - /* Make sure there is room in the tx fifo for the next command. */ - if (0U == txCount--) - { - state_complete = true; - break; - } - - /* Issue command. buf is a uint8_t* pointing at the uint16 command array. */ - sendval = ((uint16_t)(*handle->buf)) | ((uint16_t)(*(handle->buf + 1U)) << 8U); - base->MTDR = sendval; - handle->buf++; - handle->buf++; - - /* Count down until all commands are sent. */ - if (--handle->remainingBytes == 0U) - { - /* Choose next state and set up buffer pointer and count. */ - if (0U != xfer->dataSize) - { - /* Either a send or receive transfer is next. */ - handle->state = (uint8_t)kTransferDataState; - handle->buf = (uint8_t *)xfer->data; - handle->remainingBytes = (uint16_t)xfer->dataSize; - if (xfer->direction == kLPI2C_Read) - { - /* Disable TX interrupt */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterTxReadyFlag); - } - } - else - { - /* No transfer, so move to stop state. */ - handle->state = (uint8_t)kStopState; - } - } - break; - - case (uint8_t)kIssueReadCommandState: - /* Make sure there is room in the tx fifo for the read command. */ - if (0U == txCount--) - { - state_complete = true; - break; - } - - base->MTDR = (uint32_t)kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1U); - - /* Move to transfer state. */ - handle->state = (uint8_t)kTransferDataState; - if (xfer->direction == kLPI2C_Read) - { - /* Disable TX interrupt */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kLPI2C_MasterTxReadyFlag); - } - break; - - case (uint8_t)kTransferDataState: - if (xfer->direction == kLPI2C_Write) - { - /* Make sure there is room in the tx fifo. */ - if (0U == txCount--) - { - state_complete = true; - break; - } - - /* Put byte to send in fifo. */ - base->MTDR = *(handle->buf)++; - } - else - { - /* XXX handle receive sizes > 256, use kIssueReadCommandState */ - /* Make sure there is data in the rx fifo. */ - if (0U == rxCount--) - { - state_complete = true; - break; - } - - /* Read byte from fifo. */ - *(handle->buf)++ = (uint8_t)(base->MRDR & LPI2C_MRDR_DATA_MASK); - } - - /* Move to stop when the transfer is done. */ - if (--handle->remainingBytes == 0U) - { - if (xfer->direction == kLPI2C_Write) - { - state_complete = true; - } - handle->state = (uint8_t)kStopState; - } - break; - - case (uint8_t)kStopState: - /* Only issue a stop transition if the caller requested it. */ - if ((xfer->flags & (uint32_t)kLPI2C_TransferNoStopFlag) == 0U) - { - /* Make sure there is room in the tx fifo for the stop command. */ - if (0U == txCount--) - { - state_complete = true; - break; - } - - base->MTDR = (uint32_t)kStopCmd; - } - else - { - /* Caller doesn't want to send a stop, so we're done now. */ - *isDone = true; - state_complete = true; - break; - } - handle->state = (uint8_t)kWaitForCompletionState; - break; - - case (uint8_t)kWaitForCompletionState: - /* We stay in this state until the stop state is detected. */ - if (0U != (status & (uint32_t)kLPI2C_MasterStopDetectFlag)) - { - *isDone = true; - } - state_complete = true; - break; - default: - assert(false); - break; - } - } - return result; -} - -/*! - * @brief Prepares the transfer state machine and fills in the command buffer. - * @param handle Master nonblocking driver handle. - */ -static void LPI2C_InitTransferStateMachine(lpi2c_master_handle_t *handle) -{ - lpi2c_master_transfer_t *xfer = &handle->transfer; - - /* Handle no start option. */ - if (0U != (xfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag)) - { - if (xfer->direction == kLPI2C_Read) - { - /* Need to issue read command first. */ - handle->state = (uint8_t)kIssueReadCommandState; - } - else - { - /* Start immediately in the data transfer state. */ - handle->state = (uint8_t)kTransferDataState; - } - - handle->buf = (uint8_t *)xfer->data; - handle->remainingBytes = (uint16_t)xfer->dataSize; - } - else - { - uint16_t *cmd = (uint16_t *)&handle->commandBuffer; - uint32_t cmdCount = 0U; - - /* Initial direction depends on whether a subaddress was provided, and of course the actual */ - /* data transfer direction. */ - lpi2c_direction_t direction = (0U != xfer->subaddressSize) ? kLPI2C_Write : xfer->direction; - - /* Start command. */ - cmd[cmdCount++] = - (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction); - - /* Subaddress, MSB first. */ - if (0U != xfer->subaddressSize) - { - uint32_t subaddressRemaining = xfer->subaddressSize; - while (0U != (subaddressRemaining--)) - { - uint8_t subaddressByte = (uint8_t)((xfer->subaddress >> (8U * subaddressRemaining)) & 0xffU); - cmd[cmdCount++] = subaddressByte; - } - } - - /* Reads need special handling. */ - if ((0U != xfer->dataSize) && (xfer->direction == kLPI2C_Read)) - { - /* Need to send repeated start if switching directions to read. */ - if (direction == kLPI2C_Write) - { - cmd[cmdCount++] = (uint16_t)kStartCmd | - (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read); - } - - /* Read command. */ - cmd[cmdCount++] = (uint16_t)((uint32_t)kRxDataCmd | LPI2C_MTDR_DATA(xfer->dataSize - 1U)); - } - - /* Set up state machine for transferring the commands. */ - handle->state = (uint8_t)kSendCommandState; - handle->remainingBytes = (uint16_t)cmdCount; - handle->buf = (uint8_t *)&handle->commandBuffer; - } -} - -/*! - * brief Performs a non-blocking transaction on the I2C bus. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * param transfer The pointer to the transfer descriptor. - * retval #kStatus_Success The transaction was started successfully. - * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or a non-blocking - * transaction is already in progress. - */ -status_t LPI2C_MasterTransferNonBlocking(LPI2C_Type *base, - lpi2c_master_handle_t *handle, - lpi2c_master_transfer_t *transfer) -{ - status_t result; - - assert(NULL != handle); - assert(NULL != transfer); - assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); - - /* Return busy if another transaction is in progress. */ - if (handle->state != (uint8_t)kIdleState) - { - return kStatus_LPI2C_Busy; - } - - /* Return an error if the bus is already in use not by us. */ - result = LPI2C_CheckForBusyBus(base); - if (kStatus_Success != result) - { - return result; - } - - /* Disable LPI2C IRQ sources while we configure stuff. */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kMasterIrqFlags); - - /* Reset FIFO in case there are data. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; - - /* Save transfer into handle. */ - handle->transfer = *transfer; - - /* Generate commands to send. */ - LPI2C_InitTransferStateMachine(handle); - - /* Clear all flags. */ - LPI2C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags); - - /* Turn off auto-stop option. */ - base->MCFGR1 &= ~LPI2C_MCFGR1_AUTOSTOP_MASK; - - /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ - LPI2C_MasterEnableInterrupts(base, (uint32_t)kMasterIrqFlags); - - return result; -} - -/*! - * brief Returns number of bytes transferred so far. - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * param[out] count Number of bytes transferred so far by the non-blocking transaction. - * retval #kStatus_Success - * retval #kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t LPI2C_MasterTransferGetCount(LPI2C_Type *base, lpi2c_master_handle_t *handle, size_t *count) -{ - assert(NULL != handle); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state == (uint8_t)kIdleState) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - uint8_t state; - uint16_t remainingBytes; - uint32_t dataSize; - - /* Cache some fields with IRQs disabled. This ensures all field values */ - /* are synchronized with each other during an ongoing transfer. */ - uint32_t irqs = LPI2C_MasterGetEnabledInterrupts(base); - LPI2C_MasterDisableInterrupts(base, irqs); - state = handle->state; - remainingBytes = handle->remainingBytes; - dataSize = handle->transfer.dataSize; - LPI2C_MasterEnableInterrupts(base, irqs); - - /* Get transfer count based on current transfer state. */ - switch (state) - { - case (uint8_t)kIdleState: - case (uint8_t)kSendCommandState: - case ( - uint8_t)kIssueReadCommandState: /* XXX return correct value for this state when >256 reads are supported */ - *count = 0; - break; - - case (uint8_t)kTransferDataState: - *count = dataSize - remainingBytes; - break; - - case (uint8_t)kStopState: - case (uint8_t)kWaitForCompletionState: - default: - *count = dataSize; - break; - } - - return kStatus_Success; -} - -/*! - * brief Terminates a non-blocking LPI2C master transmission early. - * - * note It is not safe to call this function from an IRQ handler that has a higher priority than the - * LPI2C peripheral's IRQ priority. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * retval #kStatus_Success A transaction was successfully aborted. - * retval #kStatus_LPI2C_Idle There is not a non-blocking transaction currently in progress. - */ -void LPI2C_MasterTransferAbort(LPI2C_Type *base, lpi2c_master_handle_t *handle) -{ - if (handle->state != (uint8_t)kIdleState) - { - /* Disable internal IRQ enables. */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kMasterIrqFlags); - - /* Reset fifos. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; - - /* Send a stop command to finalize the transfer. */ - base->MTDR = (uint32_t)kStopCmd; - - /* Reset handle. */ - handle->state = (uint8_t)kIdleState; - } -} - -/*! - * brief Reusable routine to handle master interrupts. - * note This function does not need to be called unless you are reimplementing the - * nonblocking API's interrupt handler routines to add special functionality. - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - */ -void LPI2C_MasterTransferHandleIRQ(LPI2C_Type *base, lpi2c_master_handle_t *handle) -{ - bool isDone = false; - status_t result; - size_t txCount; - - /* Don't do anything if we don't have a valid handle. */ - if (NULL == handle) - { - return; - } - - if (handle->state == (uint8_t)kIdleState) - { - return; - } - - result = LPI2C_RunTransferStateMachine(base, handle, &isDone); - - if ((result != kStatus_Success) || isDone) - { - /* Handle error, terminate xfer */ - if (result != kStatus_Success) - { - LPI2C_MasterTransferAbort(base, handle); - } - /* Check whether there is data in tx FIFO not sent out, is there is then the last transfer was NACKed by slave - */ - LPI2C_MasterGetFifoCounts(base, NULL, &txCount); - if (txCount != 0U) - { - result = kStatus_LPI2C_Nak; - /* Reset fifos. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; - /* Send a stop command to finalize the transfer. */ - base->MTDR = (uint32_t)kStopCmd; - } - /* Disable internal IRQ enables. */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kMasterIrqFlags); - - /* Set handle to idle state. */ - handle->state = (uint8_t)kIdleState; - - /* Invoke callback. */ - if (NULL != handle->completionCallback) - { - handle->completionCallback(base, handle, result, handle->userData); - } - } -} - -/*! - * brief Provides a default configuration for the LPI2C slave peripheral. - * - * This function provides the following default configuration for the LPI2C slave peripheral: - * code - * slaveConfig->enableSlave = true; - * slaveConfig->address0 = 0U; - * slaveConfig->address1 = 0U; - * slaveConfig->addressMatchMode = kLPI2C_MatchAddress0; - * slaveConfig->filterDozeEnable = true; - * slaveConfig->filterEnable = true; - * slaveConfig->enableGeneralCall = false; - * slaveConfig->sclStall.enableAck = false; - * slaveConfig->sclStall.enableTx = true; - * slaveConfig->sclStall.enableRx = true; - * slaveConfig->sclStall.enableAddress = true; - * slaveConfig->ignoreAck = false; - * slaveConfig->enableReceivedAddressRead = false; - * slaveConfig->sdaGlitchFilterWidth_ns = 0; - * slaveConfig->sclGlitchFilterWidth_ns = 0; - * slaveConfig->dataValidDelay_ns = 0; - * slaveConfig->clockHoldTime_ns = 0; - * endcode - * - * After calling this function, override any settings to customize the configuration, - * prior to initializing the master driver with LPI2C_SlaveInit(). Be sure to override at least the a - * address0 member of the configuration structure with the desired slave address. - * - * param[out] slaveConfig User provided configuration structure that is set to default values. Refer to - * #lpi2c_slave_config_t. - */ -void LPI2C_SlaveGetDefaultConfig(lpi2c_slave_config_t *slaveConfig) -{ - /* Initializes the configure structure to zero. */ - (void)memset(slaveConfig, 0, sizeof(*slaveConfig)); - - slaveConfig->enableSlave = true; - slaveConfig->address0 = 0U; - slaveConfig->address1 = 0U; - slaveConfig->addressMatchMode = kLPI2C_MatchAddress0; - slaveConfig->filterDozeEnable = true; - slaveConfig->filterEnable = true; - slaveConfig->enableGeneralCall = false; - slaveConfig->sclStall.enableAck = false; - slaveConfig->sclStall.enableTx = true; - slaveConfig->sclStall.enableRx = true; - slaveConfig->sclStall.enableAddress = false; - slaveConfig->ignoreAck = false; - slaveConfig->enableReceivedAddressRead = false; - slaveConfig->sdaGlitchFilterWidth_ns = 0U; /* TODO determine default width values */ - slaveConfig->sclGlitchFilterWidth_ns = 0U; - slaveConfig->dataValidDelay_ns = 0U; - slaveConfig->clockHoldTime_ns = 0U; -} - -/*! - * brief Initializes the LPI2C slave peripheral. - * - * This function enables the peripheral clock and initializes the LPI2C slave peripheral as described by the user - * provided configuration. - * - * param base The LPI2C peripheral base address. - * param slaveConfig User provided peripheral configuration. Use LPI2C_SlaveGetDefaultConfig() to get a set of defaults - * that you can override. - * param sourceClock_Hz Frequency in Hertz of the LPI2C functional clock. Used to calculate the filter widths, - * data valid delay, and clock hold time. - */ -void LPI2C_SlaveInit(LPI2C_Type *base, const lpi2c_slave_config_t *slaveConfig, uint32_t sourceClock_Hz) -{ - uint32_t tmpCycle; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPI2C_GetInstance(base); - - /* Ungate the clock. */ - CLOCK_EnableClock(kLpi2cClocks[instance]); -#if defined(LPI2C_PERIPH_CLOCKS) - /* Ungate the functional clock in initialize function. */ - CLOCK_EnableClock(kLpi2cPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Restore to reset conditions. */ - LPI2C_SlaveReset(base); - - /* Configure peripheral. */ - base->SAMR = LPI2C_SAMR_ADDR0(slaveConfig->address0) | LPI2C_SAMR_ADDR1(slaveConfig->address1); - - base->SCFGR1 = - LPI2C_SCFGR1_ADDRCFG(slaveConfig->addressMatchMode) | LPI2C_SCFGR1_IGNACK(slaveConfig->ignoreAck) | - LPI2C_SCFGR1_RXCFG(slaveConfig->enableReceivedAddressRead) | LPI2C_SCFGR1_GCEN(slaveConfig->enableGeneralCall) | - LPI2C_SCFGR1_ACKSTALL(slaveConfig->sclStall.enableAck) | LPI2C_SCFGR1_TXDSTALL(slaveConfig->sclStall.enableTx) | - LPI2C_SCFGR1_RXSTALL(slaveConfig->sclStall.enableRx) | - LPI2C_SCFGR1_ADRSTALL(slaveConfig->sclStall.enableAddress); - - tmpCycle = - LPI2C_SCFGR2_FILTSDA(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sdaGlitchFilterWidth_ns, - (LPI2C_SCFGR2_FILTSDA_MASK >> LPI2C_SCFGR2_FILTSDA_SHIFT), 1U)); - tmpCycle |= - LPI2C_SCFGR2_FILTSCL(LPI2C_GetCyclesForWidth(sourceClock_Hz, slaveConfig->sclGlitchFilterWidth_ns, - (LPI2C_SCFGR2_FILTSCL_MASK >> LPI2C_SCFGR2_FILTSCL_SHIFT), 1U)); - tmpCycle |= LPI2C_SCFGR2_DATAVD(LPI2C_GetCyclesForWidth( - sourceClock_Hz, slaveConfig->dataValidDelay_ns, (LPI2C_SCFGR2_DATAVD_MASK >> LPI2C_SCFGR2_DATAVD_SHIFT), 1U)); - - base->SCFGR2 = tmpCycle | LPI2C_SCFGR2_CLKHOLD(LPI2C_GetCyclesForWidth( - sourceClock_Hz, slaveConfig->clockHoldTime_ns, - (LPI2C_SCFGR2_CLKHOLD_MASK >> LPI2C_SCFGR2_CLKHOLD_SHIFT), 1U)); - - /* Save SCR to last so we don't enable slave until it is configured */ - base->SCR = LPI2C_SCR_FILTDZ(slaveConfig->filterDozeEnable) | LPI2C_SCR_FILTEN(slaveConfig->filterEnable) | - LPI2C_SCR_SEN(slaveConfig->enableSlave); -} - -/*! - * brief Deinitializes the LPI2C slave peripheral. - * - * This function disables the LPI2C slave peripheral and gates the clock. It also performs a software - * reset to restore the peripheral to reset conditions. - * - * param base The LPI2C peripheral base address. - */ -void LPI2C_SlaveDeinit(LPI2C_Type *base) -{ - LPI2C_SlaveReset(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPI2C_GetInstance(base); - - /* Gate the clock. */ - CLOCK_DisableClock(kLpi2cClocks[instance]); - -#if defined(LPI2C_PERIPH_CLOCKS) - /* Gate the functional clock. */ - CLOCK_DisableClock(kLpi2cPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * @brief Convert provided flags to status code, and clear any errors if present. - * @param base The LPI2C peripheral base address. - * @param status Current status flags value that will be checked. - * @retval #kStatus_Success - * @retval #kStatus_LPI2C_BitError - * @retval #kStatus_LPI2C_FifoError - */ -static status_t LPI2C_SlaveCheckAndClearError(LPI2C_Type *base, uint32_t flags) -{ - status_t result = kStatus_Success; - - flags &= (uint32_t)kSlaveErrorFlags; - if (0U != flags) - { - if (0U != (flags & (uint32_t)kLPI2C_SlaveBitErrFlag)) - { - result = kStatus_LPI2C_BitError; - } - else if (0U != (flags & (uint32_t)kLPI2C_SlaveFifoErrFlag)) - { - result = kStatus_LPI2C_FifoError; - } - else - { - ; /* Intentional empty */ - } - - /* Clear the errors. */ - LPI2C_SlaveClearStatusFlags(base, flags); - } - else - { - ; /* Intentional empty */ - } - - return result; -} - -/*! - * brief Performs a polling send transfer on the I2C bus. - * - * param base The LPI2C peripheral base address. - * param txBuff The pointer to the data to be transferred. - * param txSize The length in bytes of the data to be transferred. - * param[out] actualTxSize - * return Error or success status returned by API. - */ -status_t LPI2C_SlaveSend(LPI2C_Type *base, void *txBuff, size_t txSize, size_t *actualTxSize) -{ - uint8_t *buf = (uint8_t *)txBuff; - size_t remaining = txSize; - - assert(NULL != txBuff); - -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - /* Clear stop flag. */ - LPI2C_SlaveClearStatusFlags(base, - (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag); - - while (0U != remaining) - { - uint32_t flags; - status_t result; - - /* Wait until we can transmit. */ - do - { - /* Check for errors */ - flags = LPI2C_SlaveGetStatusFlags(base); - result = LPI2C_SlaveCheckAndClearError(base, flags); - if (kStatus_Success != result) - { - if (NULL != actualTxSize) - { - *actualTxSize = txSize - remaining; - } - return result; - } -#if I2C_RETRY_TIMES - } while ((0U == (flags & ((uint32_t)kLPI2C_SlaveTxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag | - (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) && - (0U != --waitTimes)); - if (0U == waitTimes) - { - return kStatus_LPI2C_Timeout; - } -#else - } while (0U == (flags & ((uint32_t)kLPI2C_SlaveTxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag | - (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))); -#endif - - /* Send a byte. */ - if (0U != (flags & (uint32_t)kLPI2C_SlaveTxReadyFlag)) - { - base->STDR = *buf++; - --remaining; - } - - /* Exit loop if we see a stop or restart in transfer*/ - if ((0U != (flags & ((uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) && - (remaining != 0U)) - { - LPI2C_SlaveClearStatusFlags( - base, (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag); - break; - } - } - - if (NULL != actualTxSize) - { - *actualTxSize = txSize - remaining; - } - - return kStatus_Success; -} - -/*! - * brief Performs a polling receive transfer on the I2C bus. - * - * param base The LPI2C peripheral base address. - * param rxBuff The pointer to the data to be transferred. - * param rxSize The length in bytes of the data to be transferred. - * param[out] actualRxSize - * return Error or success status returned by API. - */ -status_t LPI2C_SlaveReceive(LPI2C_Type *base, void *rxBuff, size_t rxSize, size_t *actualRxSize) -{ - uint8_t *buf = (uint8_t *)rxBuff; - size_t remaining = rxSize; - - assert(NULL != rxBuff); - -#if I2C_RETRY_TIMES - uint32_t waitTimes = I2C_RETRY_TIMES; -#endif - - /* Clear stop flag. */ - LPI2C_SlaveClearStatusFlags(base, - (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag); - - while (0U != remaining) - { - uint32_t flags; - status_t result; - - /* Wait until we can receive. */ - do - { - /* Check for errors */ - flags = LPI2C_SlaveGetStatusFlags(base); - result = LPI2C_SlaveCheckAndClearError(base, flags); - if (kStatus_Success != result) - { - if (NULL != actualRxSize) - { - *actualRxSize = rxSize - remaining; - } - return result; - } -#if I2C_RETRY_TIMES - } while ((0U == (flags & ((uint32_t)kLPI2C_SlaveRxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag | - (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) && - (0U != --waitTimes)); - if (0U == waitTimes) - { - return kStatus_LPI2C_Timeout; - } -#else - } while (0U == (flags & ((uint32_t)kLPI2C_SlaveRxReadyFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag | - (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))); -#endif - - /* Receive a byte. */ - if (0U != (flags & (uint32_t)kLPI2C_SlaveRxReadyFlag)) - { - *buf++ = (uint8_t)(base->SRDR & LPI2C_SRDR_DATA_MASK); - --remaining; - } - - /* Exit loop if we see a stop or restart */ - if ((0U != (flags & ((uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag))) && - (remaining != 0U)) - { - LPI2C_SlaveClearStatusFlags( - base, (uint32_t)kLPI2C_SlaveStopDetectFlag | (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag); - break; - } - } - - if (NULL != actualRxSize) - { - *actualRxSize = rxSize - remaining; - } - - return kStatus_Success; -} - -/*! - * brief Creates a new handle for the LPI2C slave non-blocking APIs. - * - * The creation of a handle is for use with the non-blocking APIs. Once a handle - * is created, there is not a corresponding destroy handle. If the user wants to - * terminate a transfer, the LPI2C_SlaveTransferAbort() API shall be called. - * - * note The function also enables the NVIC IRQ for the input LPI2C. Need to notice - * that on some SoCs the LPI2C IRQ is connected to INTMUX, in this case user needs to - * enable the associated INTMUX IRQ in application. - - * param base The LPI2C peripheral base address. - * param[out] handle Pointer to the LPI2C slave driver handle. - * param callback User provided pointer to the asynchronous callback function. - * param userData User provided pointer to the application callback data. - */ -void LPI2C_SlaveTransferCreateHandle(LPI2C_Type *base, - lpi2c_slave_handle_t *handle, - lpi2c_slave_transfer_callback_t callback, - void *userData) -{ - uint32_t instance; - - assert(NULL != handle); - - /* Clear out the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Look up instance number */ - instance = LPI2C_GetInstance(base); - - /* Save base and instance. */ - handle->callback = callback; - handle->userData = userData; - - /* Save this handle for IRQ use. */ - s_lpi2cSlaveHandle[instance] = handle; - - /* Set irq handler. */ - s_lpi2cSlaveIsr = LPI2C_SlaveTransferHandleIRQ; - - /* Clear internal IRQ enables and enable NVIC IRQ. */ - LPI2C_SlaveDisableInterrupts(base, (uint32_t)kSlaveIrqFlags); - (void)EnableIRQ(kLpi2cIrqs[instance]); - - /* Nack by default. */ - base->STAR = LPI2C_STAR_TXNACK_MASK; -} - -/*! - * brief Starts accepting slave transfers. - * - * Call this API after calling I2C_SlaveInit() and LPI2C_SlaveTransferCreateHandle() to start processing - * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the - * callback that was passed into the call to LPI2C_SlaveTransferCreateHandle(). The callback is always invoked - * from the interrupt context. - * - * The set of events received by the callback is customizable. To do so, set the a eventMask parameter to - * the OR'd combination of #lpi2c_slave_transfer_event_t enumerators for the events you wish to receive. - * The #kLPI2C_SlaveTransmitEvent and #kLPI2C_SlaveReceiveEvent events are always enabled and do not need - * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and - * receive events that are always enabled. In addition, the #kLPI2C_SlaveAllEvents constant is provided as - * a convenient way to enable all events. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. - * param eventMask Bit mask formed by OR'ing together #lpi2c_slave_transfer_event_t enumerators to specify - * which events to send to the callback. Other accepted values are 0 to get a default set of - * only the transmit and receive events, and #kLPI2C_SlaveAllEvents to enable all events. - * - * retval #kStatus_Success Slave transfers were successfully started. - * retval #kStatus_LPI2C_Busy Slave transfers have already been started on this handle. - */ -status_t LPI2C_SlaveTransferNonBlocking(LPI2C_Type *base, lpi2c_slave_handle_t *handle, uint32_t eventMask) -{ - uint32_t status; - - assert(NULL != handle); - - /* Return busy if another transaction is in progress. */ - if (handle->isBusy) - { - return kStatus_LPI2C_Busy; - } - - /* Return an error if the bus is already in use not by us. */ - status = LPI2C_SlaveGetStatusFlags(base); - if ((0U != (status & (uint32_t)kLPI2C_SlaveBusBusyFlag)) && (0U == (status & (uint32_t)kLPI2C_SlaveBusyFlag))) - { - return kStatus_LPI2C_Busy; - } - - /* Disable LPI2C IRQ sources while we configure stuff. */ - LPI2C_SlaveDisableInterrupts(base, (uint32_t)kSlaveIrqFlags); - - /* Clear transfer in handle. */ - (void)memset(&handle->transfer, 0, sizeof(handle->transfer)); - - /* Record that we're busy. */ - handle->isBusy = true; - - /* Set up event mask. tx and rx are always enabled. */ - handle->eventMask = eventMask | (uint32_t)kLPI2C_SlaveTransmitEvent | (uint32_t)kLPI2C_SlaveReceiveEvent; - - /* Ack by default. */ - base->STAR = 0U; - - /* Clear all flags. */ - LPI2C_SlaveClearStatusFlags(base, (uint32_t)kSlaveClearFlags); - - /* Enable LPI2C internal IRQ sources. NVIC IRQ was enabled in CreateHandle() */ - LPI2C_SlaveEnableInterrupts(base, (uint32_t)kSlaveIrqFlags); - - return kStatus_Success; -} - -/*! - * brief Gets the slave transfer status during a non-blocking transfer. - * param base The LPI2C peripheral base address. - * param handle Pointer to i2c_slave_handle_t structure. - * param[out] count Pointer to a value to hold the number of bytes transferred. May be NULL if the count is not - * required. - * retval #kStatus_Success - * retval #kStatus_NoTransferInProgress - */ -status_t LPI2C_SlaveTransferGetCount(LPI2C_Type *base, lpi2c_slave_handle_t *handle, size_t *count) -{ - assert(NULL != handle); - - if (count == NULL) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (!handle->isBusy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - /* For an active transfer, just return the count from the handle. */ - *count = handle->transferredCount; - - return kStatus_Success; -} - -/*! - * brief Aborts the slave non-blocking transfers. - * note This API could be called at any time to stop slave for handling the bus events. - * param base The LPI2C peripheral base address. - * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. - * retval #kStatus_Success - * retval #kStatus_LPI2C_Idle - */ -void LPI2C_SlaveTransferAbort(LPI2C_Type *base, lpi2c_slave_handle_t *handle) -{ - assert(NULL != handle); - - /* Return idle if no transaction is in progress. */ - if (handle->isBusy) - { - /* Disable LPI2C IRQ sources. */ - LPI2C_SlaveDisableInterrupts(base, (uint32_t)kSlaveIrqFlags); - - /* Nack by default. */ - base->STAR = LPI2C_STAR_TXNACK_MASK; - - /* Reset transfer info. */ - (void)memset(&handle->transfer, 0, sizeof(handle->transfer)); - - /* We're no longer busy. */ - handle->isBusy = false; - } -} - -/*! - * brief Reusable routine to handle slave interrupts. - * note This function does not need to be called unless you are reimplementing the - * non blocking API's interrupt handler routines to add special functionality. - * param base The LPI2C peripheral base address. - * param handle Pointer to #lpi2c_slave_handle_t structure which stores the transfer state. - */ -void LPI2C_SlaveTransferHandleIRQ(LPI2C_Type *base, lpi2c_slave_handle_t *handle) -{ - uint32_t flags; - lpi2c_slave_transfer_t *xfer; - - /* Check for a valid handle in case of a spurious interrupt. */ - if (NULL == handle) - { - return; - } - - xfer = &handle->transfer; - - /* Get status flags. */ - flags = LPI2C_SlaveGetStatusFlags(base); - - if (0U != (flags & ((uint32_t)kLPI2C_SlaveBitErrFlag | (uint32_t)kLPI2C_SlaveFifoErrFlag))) - { - xfer->event = kLPI2C_SlaveCompletionEvent; - xfer->completionStatus = LPI2C_SlaveCheckAndClearError(base, flags); - - if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveCompletionEvent)) && (NULL != handle->callback)) - { - handle->callback(base, xfer, handle->userData); - } - return; - } - if (0U != (flags & (((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag) | ((uint32_t)kLPI2C_SlaveStopDetectFlag)))) - { - xfer->event = (0U != (flags & (uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag)) ? kLPI2C_SlaveRepeatedStartEvent : - kLPI2C_SlaveCompletionEvent; - xfer->receivedAddress = 0U; - xfer->completionStatus = kStatus_Success; - xfer->transferredCount = handle->transferredCount; - - if (xfer->event == kLPI2C_SlaveCompletionEvent) - { - handle->isBusy = false; - } - - if (handle->wasTransmit) - { - /* Subtract one from the transmit count to offset the fact that LPI2C asserts the */ - /* tx flag before it sees the nack from the master-receiver, thus causing one more */ - /* count that the master actually receives. */ - --xfer->transferredCount; - handle->wasTransmit = false; - } - - /* Clear the flag. */ - LPI2C_SlaveClearStatusFlags( - base, flags & ((uint32_t)kLPI2C_SlaveRepeatedStartDetectFlag | (uint32_t)kLPI2C_SlaveStopDetectFlag)); - - /* Revert to sending an Ack by default, in case we sent a Nack for receive. */ - base->STAR = 0U; - - if ((0U != (handle->eventMask & (uint32_t)xfer->event)) && (NULL != handle->callback)) - { - handle->callback(base, xfer, handle->userData); - } - - /* Clean up transfer info on completion, after the callback has been invoked. */ - (void)memset(&handle->transfer, 0, sizeof(handle->transfer)); - } - if (0U != (flags & (uint32_t)kLPI2C_SlaveAddressValidFlag)) - { - xfer->event = kLPI2C_SlaveAddressMatchEvent; - xfer->receivedAddress = (uint8_t)(base->SASR & LPI2C_SASR_RADDR_MASK); - - /* Update handle status to busy because slave is addressed. */ - handle->isBusy = true; - if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveAddressMatchEvent)) && (NULL != handle->callback)) - { - handle->callback(base, xfer, handle->userData); - } - } - if (0U != (flags & (uint32_t)kLPI2C_SlaveTransmitAckFlag)) - { - xfer->event = kLPI2C_SlaveTransmitAckEvent; - - if ((0U != (handle->eventMask & (uint32_t)kLPI2C_SlaveTransmitAckEvent)) && (NULL != handle->callback)) - { - handle->callback(base, xfer, handle->userData); - } - } - - /* Handle transmit and receive. */ - if (0U != (flags & (uint32_t)kLPI2C_SlaveTxReadyFlag)) - { - handle->wasTransmit = true; - - /* If we're out of data, invoke callback to get more. */ - if ((NULL == xfer->data) || (0U == xfer->dataSize)) - { - xfer->event = kLPI2C_SlaveTransmitEvent; - if (NULL != handle->callback) - { - handle->callback(base, xfer, handle->userData); - } - - /* Clear the transferred count now that we have a new buffer. */ - handle->transferredCount = 0U; - } - - /* Transmit a byte. */ - if ((NULL != xfer->data) && (0U != xfer->dataSize)) - { - base->STDR = *xfer->data++; - --xfer->dataSize; - ++handle->transferredCount; - } - } - if (0U != (flags & (uint32_t)kLPI2C_SlaveRxReadyFlag)) - { - /* If we're out of room in the buffer, invoke callback to get another. */ - if ((NULL == xfer->data) || (0U == xfer->dataSize)) - { - xfer->event = kLPI2C_SlaveReceiveEvent; - if (NULL != handle->callback) - { - handle->callback(base, xfer, handle->userData); - } - - /* Clear the transferred count now that we have a new buffer. */ - handle->transferredCount = 0U; - } - - /* Receive a byte. */ - if ((NULL != xfer->data) && (0U != xfer->dataSize)) - { - *xfer->data++ = (uint8_t)base->SRDR; - --xfer->dataSize; - ++handle->transferredCount; - } - else - { - /* We don't have any room to receive more data, so send a nack. */ - base->STAR = LPI2C_STAR_TXNACK_MASK; - } - } -} - -#if !(defined(FSL_FEATURE_I2C_HAS_NO_IRQ) && FSL_FEATURE_I2C_HAS_NO_IRQ) -/*! - * @brief Shared IRQ handler that can call both master and slave ISRs. - * - * The master and slave ISRs are called through function pointers in order to decouple - * this code from the ISR functions. Without this, the linker would always pull in both - * ISRs and every function they call, even if only the functional API was used. - * - * @param base The LPI2C peripheral base address. - * @param instance The LPI2C peripheral instance number. - */ -static void LPI2C_CommonIRQHandler(LPI2C_Type *base, uint32_t instance) -{ - /* Check for master IRQ. */ - if ((0U != (base->MCR & LPI2C_MCR_MEN_MASK)) && (NULL != s_lpi2cMasterIsr)) - { - /* Master mode. */ - s_lpi2cMasterIsr(base, s_lpi2cMasterHandle[instance]); - } - - /* Check for slave IRQ. */ - if ((0U != (base->SCR & LPI2C_SCR_SEN_MASK)) && (NULL != s_lpi2cSlaveIsr)) - { - /* Slave mode. */ - s_lpi2cSlaveIsr(base, s_lpi2cSlaveHandle[instance]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(LPI2C0) -/* Implementation of LPI2C0 handler named in startup code. */ -void LPI2C0_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C0, 0U); -} -#endif - -#if defined(LPI2C1) -/* Implementation of LPI2C1 handler named in startup code. */ -void LPI2C1_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C1, 1U); -} -#endif - -#if defined(LPI2C2) -/* Implementation of LPI2C2 handler named in startup code. */ -void LPI2C2_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C2, 2U); -} -#endif - -#if defined(LPI2C3) -/* Implementation of LPI2C3 handler named in startup code. */ -void LPI2C3_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C3, 3U); -} -#endif - -#if defined(LPI2C4) -/* Implementation of LPI2C4 handler named in startup code. */ -void LPI2C4_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C4, 4U); -} -#endif - -#if defined(LPI2C5) -/* Implementation of LPI2C5 handler named in startup code. */ -void LPI2C5_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C5, 5U); -} -#endif - -#if defined(LPI2C6) -/* Implementation of LPI2C6 handler named in startup code. */ -void LPI2C6_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(LPI2C6, 6U); -} -#endif - -#if defined(CM4_0__LPI2C) -/* Implementation of CM4_0__LPI2C handler named in startup code. */ -void M4_0_LPI2C_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(CM4_0__LPI2C, LPI2C_GetInstance(CM4_0__LPI2C)); -} -#endif - -#if defined(CM4__LPI2C) -/* Implementation of CM4__LPI2C handler named in startup code. */ -void M4_LPI2C_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(CM4__LPI2C, LPI2C_GetInstance(CM4__LPI2C)); -} -#endif - -#if defined(CM4_1__LPI2C) -/* Implementation of CM4_1__LPI2C handler named in startup code. */ -void M4_1_LPI2C_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(CM4_1__LPI2C, LPI2C_GetInstance(CM4_1__LPI2C)); -} -#endif - -#if defined(DMA__LPI2C0) -/* Implementation of DMA__LPI2C0 handler named in startup code. */ -void DMA_I2C0_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(DMA__LPI2C0, LPI2C_GetInstance(DMA__LPI2C0)); -} -#endif - -#if defined(DMA__LPI2C1) -/* Implementation of DMA__LPI2C1 handler named in startup code. */ -void DMA_I2C1_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(DMA__LPI2C1, LPI2C_GetInstance(DMA__LPI2C1)); -} -#endif - -#if defined(DMA__LPI2C2) -/* Implementation of DMA__LPI2C2 handler named in startup code. */ -void DMA_I2C2_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(DMA__LPI2C2, LPI2C_GetInstance(DMA__LPI2C2)); -} -#endif - -#if defined(DMA__LPI2C3) -/* Implementation of DMA__LPI2C3 handler named in startup code. */ -void DMA_I2C3_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(DMA__LPI2C3, LPI2C_GetInstance(DMA__LPI2C3)); -} -#endif - -#if defined(DMA__LPI2C4) -/* Implementation of DMA__LPI2C3 handler named in startup code. */ -void DMA_I2C4_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(DMA__LPI2C4, LPI2C_GetInstance(DMA__LPI2C4)); -} -#endif - -#if defined(ADMA__LPI2C0) -/* Implementation of DMA__LPI2C0 handler named in startup code. */ -void ADMA_I2C0_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(ADMA__LPI2C0, LPI2C_GetInstance(ADMA__LPI2C0)); -} -#endif - -#if defined(ADMA__LPI2C1) -/* Implementation of DMA__LPI2C1 handler named in startup code. */ -void ADMA_I2C1_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(ADMA__LPI2C1, LPI2C_GetInstance(ADMA__LPI2C1)); -} -#endif - -#if defined(ADMA__LPI2C2) -/* Implementation of DMA__LPI2C2 handler named in startup code. */ -void ADMA_I2C2_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(ADMA__LPI2C2, LPI2C_GetInstance(ADMA__LPI2C2)); -} -#endif - -#if defined(ADMA__LPI2C3) -/* Implementation of DMA__LPI2C3 handler named in startup code. */ -void ADMA_I2C3_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(ADMA__LPI2C3, LPI2C_GetInstance(ADMA__LPI2C3)); -} -#endif - -#if defined(ADMA__LPI2C4) -/* Implementation of DMA__LPI2C3 handler named in startup code. */ -void ADMA_I2C4_INT_DriverIRQHandler(void) -{ - LPI2C_CommonIRQHandler(ADMA__LPI2C4, LPI2C_GetInstance(ADMA__LPI2C4)); -} -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c_edma.c deleted file mode 100644 index c325405bf9..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpi2c_edma.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpi2c_edma.h" -#include <stdlib.h> -#include <string.h> - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpi2c_edma" -#endif - -/* @brief Mask to align an address to 32 bytes. */ -#define ALIGN_32_MASK (0x1fU) - -/*! @brief Common sets of flags used by the driver. */ -enum _lpi2c_flag_constants -{ - /*! All flags which are cleared by the driver upon starting a transfer. */ - kMasterClearFlags = kLPI2C_MasterEndOfPacketFlag | kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | - kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | kLPI2C_MasterPinLowTimeoutFlag | - kLPI2C_MasterDataMatchFlag, - - /*! IRQ sources enabled by the non-blocking transactional API. */ - kMasterIrqFlags = kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterTxReadyFlag | kLPI2C_MasterRxReadyFlag | - kLPI2C_MasterStopDetectFlag | kLPI2C_MasterNackDetectFlag | kLPI2C_MasterPinLowTimeoutFlag | - kLPI2C_MasterFifoErrFlag, - - /*! Errors to check for. */ - kMasterErrorFlags = kLPI2C_MasterNackDetectFlag | kLPI2C_MasterArbitrationLostFlag | kLPI2C_MasterFifoErrFlag | - kLPI2C_MasterPinLowTimeoutFlag, - - /*! All flags which are cleared by the driver upon starting a transfer. */ - kSlaveClearFlags = kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveStopDetectFlag | kLPI2C_SlaveBitErrFlag | - kLPI2C_SlaveFifoErrFlag, - - /*! IRQ sources enabled by the non-blocking transactional API. */ - kSlaveIrqFlags = kLPI2C_SlaveTxReadyFlag | kLPI2C_SlaveRxReadyFlag | kLPI2C_SlaveStopDetectFlag | - kLPI2C_SlaveRepeatedStartDetectFlag | kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag | - kLPI2C_SlaveTransmitAckFlag | kLPI2C_SlaveAddressValidFlag, - - /*! Errors to check for. */ - kSlaveErrorFlags = kLPI2C_SlaveFifoErrFlag | kLPI2C_SlaveBitErrFlag, -}; - -/* ! @brief LPI2C master fifo commands. */ -enum _lpi2c_master_fifo_cmd -{ - kTxDataCmd = LPI2C_MTDR_CMD(0x0U), /*!< Transmit DATA[7:0] */ - kRxDataCmd = LPI2C_MTDR_CMD(0X1U), /*!< Receive (DATA[7:0] + 1) bytes */ - kStopCmd = LPI2C_MTDR_CMD(0x2U), /*!< Generate STOP condition */ - kStartCmd = LPI2C_MTDR_CMD(0x4U), /*!< Generate(repeated) START and transmit address in DATA[[7:0] */ -}; - -/*! @brief States for the state machine used by transactional APIs. */ -enum _lpi2c_transfer_states -{ - kIdleState = 0, - kSendCommandState, - kIssueReadCommandState, - kTransferDataState, - kStopState, - kWaitForCompletionState, -}; - -/*! @brief Typedef for interrupt handler. */ -typedef void (*lpi2c_isr_t)(LPI2C_Type *base, void *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle); - -static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -static uint32_t lpi2c_edma_RecSetting = 0x02; - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Create a new handle for the LPI2C master DMA APIs. - * - * The creation of a handle is for use with the DMA APIs. Once a handle - * is created, there is not a corresponding destroy handle. If the user wants to - * terminate a transfer, the LPI2C_MasterTransferAbortEDMA() API shall be called. - * - * For devices where the LPI2C send and receive DMA requests are OR'd together, the a txDmaHandle - * parameter is ignored and may be set to NULL. - * - * param base The LPI2C peripheral base address. - * param[out] handle Pointer to the LPI2C master driver handle. - * param rxDmaHandle Handle for the eDMA receive channel. Created by the user prior to calling this function. - * param txDmaHandle Handle for the eDMA transmit channel. Created by the user prior to calling this function. - * param callback User provided pointer to the asynchronous callback function. - * param userData User provided pointer to the application callback data. - */ -void LPI2C_MasterCreateEDMAHandle(LPI2C_Type *base, - lpi2c_master_edma_handle_t *handle, - edma_handle_t *rxDmaHandle, - edma_handle_t *txDmaHandle, - lpi2c_master_edma_transfer_callback_t callback, - void *userData) -{ - assert(handle); - assert(rxDmaHandle); - assert(txDmaHandle); - - /* Clear out the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set up the handle. For combined rx/tx DMA requests, the tx channel handle is set to the rx handle */ - /* in order to make the transfer API code simpler. */ - handle->base = base; - handle->completionCallback = callback; - handle->userData = userData; - handle->rx = rxDmaHandle; - handle->tx = (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) > 0) ? txDmaHandle : rxDmaHandle; - - /* Set DMA channel completion callbacks. */ - EDMA_SetCallback(handle->rx, LPI2C_MasterEDMACallback, handle); - if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0) - { - EDMA_SetCallback(handle->tx, LPI2C_MasterEDMACallback, handle); - } -} - -/*! - * @brief Prepares the command buffer with the sequence of commands needed to send the requested transaction. - * @param handle Master DMA driver handle. - * @return Number of command words. - */ -static uint32_t LPI2C_GenerateCommands(lpi2c_master_edma_handle_t *handle) -{ - lpi2c_master_transfer_t *xfer = &handle->transfer; - uint16_t *cmd = (uint16_t *)&handle->commandBuffer; - uint32_t cmdCount = 0; - - /* Handle no start option. */ - if ((xfer->flags & (uint32_t)kLPI2C_TransferNoStartFlag) != 0U) - { - if (xfer->direction == kLPI2C_Read) - { - /* Need to issue read command first. */ - cmd[cmdCount++] = (uint16_t)kRxDataCmd | (uint16_t)LPI2C_MTDR_DATA(xfer->dataSize - 1U); - } - } - else - { - /* - * Initial direction depends on whether a subaddress was provided, and of course the actual - * data transfer direction. - */ - lpi2c_direction_t direction = (xfer->subaddressSize != 0U) ? kLPI2C_Write : xfer->direction; - - /* Start command. */ - cmd[cmdCount++] = - (uint16_t)kStartCmd | (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)direction); - - /* Subaddress, MSB first. */ - if (xfer->subaddressSize != 0U) - { - uint32_t subaddressRemaining = xfer->subaddressSize; - while (0U != subaddressRemaining--) - { - uint8_t subaddressByte = (uint8_t)(xfer->subaddress >> (8U * subaddressRemaining)) & 0xffU; - cmd[cmdCount++] = subaddressByte; - } - } - - /* Reads need special handling because we have to issue a read command and maybe a repeated start. */ - if ((xfer->dataSize != 0U) && (xfer->direction == kLPI2C_Read)) - { - /* Need to send repeated start if switching directions to read. */ - if (direction == kLPI2C_Write) - { - cmd[cmdCount++] = (uint16_t)kStartCmd | - (uint16_t)((uint16_t)((uint16_t)xfer->slaveAddress << 1U) | (uint16_t)kLPI2C_Read); - } - - /* Read command. */ - cmd[cmdCount++] = (uint16_t)kRxDataCmd | (uint16_t)LPI2C_MTDR_DATA(xfer->dataSize - 1U); - } - } - - return cmdCount; -} - -/*! - * brief Performs a non-blocking DMA-based transaction on the I2C bus. - * - * The callback specified when the a handle was created is invoked when the transaction has - * completed. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * param transfer The pointer to the transfer descriptor. - * retval #kStatus_Success The transaction was started successfully. - * retval #kStatus_LPI2C_Busy Either another master is currently utilizing the bus, or another DMA - * transaction is already in progress. - */ -status_t LPI2C_MasterTransferEDMA(LPI2C_Type *base, - lpi2c_master_edma_handle_t *handle, - lpi2c_master_transfer_t *transfer) -{ - status_t result; - - assert(handle); - assert(transfer); - assert(transfer->subaddressSize <= sizeof(transfer->subaddress)); - - /* Return busy if another transaction is in progress. */ - if (handle->isBusy) - { - return kStatus_LPI2C_Busy; - } - - /* Return an error if the bus is already in use not by us. */ - result = LPI2C_CheckForBusyBus(base); - if (result != kStatus_Success) - { - return result; - } - - /* We're now busy. */ - handle->isBusy = true; - - /* Disable LPI2C IRQ and DMA sources while we configure stuff. */ - LPI2C_MasterDisableInterrupts(base, (uint32_t)kMasterIrqFlags); - LPI2C_MasterEnableDMA(base, false, false); - - /* Clear all flags. */ - LPI2C_MasterClearStatusFlags(base, (uint32_t)kMasterClearFlags); - - /* Save transfer into handle. */ - handle->transfer = *transfer; - - /* Generate commands to send. */ - uint32_t commandCount = LPI2C_GenerateCommands(handle); - - /* If the user is transmitting no data with no start or stop, then just go ahead and invoke the callback. */ - if ((0U == commandCount) && (transfer->dataSize == 0U)) - { - if (handle->completionCallback != NULL) - { - handle->completionCallback(base, handle, kStatus_Success, handle->userData); - } - return kStatus_Success; - } - - /* Reset DMA channels. */ - EDMA_ResetChannel(handle->rx->base, handle->rx->channel); - if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0) - { - EDMA_ResetChannel(handle->tx->base, handle->tx->channel); - } - - /* Get a 32-byte aligned TCD pointer. */ - edma_tcd_t *tcd = (edma_tcd_t *)((uint32_t)(&handle->tcds[1]) & (~ALIGN_32_MASK)); - - bool hasSendData = (transfer->direction == kLPI2C_Write) && (transfer->dataSize != 0U); - bool hasReceiveData = (transfer->direction == kLPI2C_Read) && (transfer->dataSize != 0U); - - edma_transfer_config_t transferConfig; - edma_tcd_t *linkTcd = NULL; - - /* Set up data transmit. */ - if (hasSendData) - { - uint32_t *srcAddr = (uint32_t *)transfer->data; - transferConfig.srcAddr = (uint32_t)srcAddr; - transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base); - transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.srcOffset = (int16_t)sizeof(uint8_t); - transferConfig.destOffset = 0; - transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to fill fifo */ - transferConfig.majorLoopCounts = transfer->dataSize; - - /* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */ - handle->nbytes = (uint8_t)transferConfig.minorLoopBytes; - - if (commandCount != 0U) - { - /* Create a software TCD, which will be chained after the commands. */ - EDMA_TcdReset(tcd); - EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL); - EDMA_TcdEnableInterrupts(tcd, (uint32_t)kEDMA_MajorInterruptEnable); - linkTcd = tcd; - } - else - { - /* User is only transmitting data with no required commands, so this transfer can stand alone. */ - EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, NULL); - EDMA_EnableChannelInterrupts(handle->tx->base, handle->tx->channel, (uint32_t)kEDMA_MajorInterruptEnable); - } - } - else if (hasReceiveData) - { - uint32_t *srcAddr = (uint32_t *)transfer->data; - /* Set up data receive. */ - transferConfig.srcAddr = (uint32_t)LPI2C_MasterGetRxFifoAddress(base); - transferConfig.destAddr = (uint32_t)srcAddr; - transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.srcOffset = 0; - transferConfig.destOffset = (int16_t)sizeof(uint8_t); - transferConfig.minorLoopBytes = sizeof(uint8_t); /* TODO optimize to empty fifo */ - transferConfig.majorLoopCounts = transfer->dataSize; - - /* Store the initially configured eDMA minor byte transfer count into the LPI2C handle */ - handle->nbytes = (uint8_t)transferConfig.minorLoopBytes; - - if ((FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0) || (0U == commandCount)) - { - /* We can put this receive transfer on its own DMA channel. */ - EDMA_SetTransferConfig(handle->rx->base, handle->rx->channel, &transferConfig, NULL); - EDMA_EnableChannelInterrupts(handle->rx->base, handle->rx->channel, (uint32_t)kEDMA_MajorInterruptEnable); - } - else - { - /* For shared rx/tx DMA requests, when there are commands, create a software TCD of - enabling rx dma and disabling tx dma, which will be chained onto the commands transfer, - and create another software TCD of transfering data and chain it onto the last TCD. - Notice that in this situation assume tx/rx uses same channel */ - EDMA_TcdReset(tcd); - EDMA_TcdSetTransferConfig(tcd, &transferConfig, NULL); - EDMA_TcdEnableInterrupts(tcd, (uint32_t)kEDMA_MajorInterruptEnable); - - transferConfig.srcAddr = (uint32_t)&lpi2c_edma_RecSetting; - transferConfig.destAddr = (uint32_t) & (base->MDER); - transferConfig.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfig.srcOffset = 0; - transferConfig.destOffset = (int16_t)sizeof(uint8_t); - transferConfig.minorLoopBytes = sizeof(uint8_t); - transferConfig.majorLoopCounts = 1; - - edma_tcd_t *tcdSetRxClearTxDMA = (edma_tcd_t *)((uint32_t)(&handle->tcds[2]) & (~ALIGN_32_MASK)); - - EDMA_TcdReset(tcdSetRxClearTxDMA); - EDMA_TcdSetTransferConfig(tcdSetRxClearTxDMA, &transferConfig, tcd); - linkTcd = tcdSetRxClearTxDMA; - } - } - else - { - /* No data to send */ - } - - /* Set up commands transfer. */ - if (commandCount != 0U) - { - transferConfig.srcAddr = (uint32_t)handle->commandBuffer; - transferConfig.destAddr = (uint32_t)LPI2C_MasterGetTxFifoAddress(base); - transferConfig.srcTransferSize = kEDMA_TransferSize2Bytes; - transferConfig.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfig.srcOffset = (int16_t)sizeof(uint16_t); - transferConfig.destOffset = 0; - transferConfig.minorLoopBytes = sizeof(uint16_t); /* TODO optimize to fill fifo */ - transferConfig.majorLoopCounts = commandCount; - - EDMA_SetTransferConfig(handle->tx->base, handle->tx->channel, &transferConfig, linkTcd); - } - - /* Start DMA transfer. */ - if (hasReceiveData || (0 == FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base))) - { - EDMA_StartTransfer(handle->rx); - } - - if ((hasSendData || (commandCount != 0U)) && (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0)) - { - EDMA_StartTransfer(handle->tx); - } - - /* Enable DMA in both directions. This actually kicks of the transfer. */ - LPI2C_MasterEnableDMA(base, true, true); - - return result; -} - -/*! - * brief Returns number of bytes transferred so far. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * param[out] count Number of bytes transferred so far by the non-blocking transaction. - * retval #kStatus_Success - * retval #kStatus_NoTransferInProgress There is not a DMA transaction currently in progress. - */ -status_t LPI2C_MasterTransferGetCountEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle, size_t *count) -{ - assert(handle); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (!handle->isBusy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - uint32_t remaining = handle->transfer.dataSize; - - /* If the DMA is still on a commands transfer that chains to the actual data transfer, */ - /* we do nothing and return the number of transferred bytes as zero. */ - if (EDMA_GetNextTCDAddress(handle->tx) == 0U) - { - if (handle->transfer.direction == kLPI2C_Write) - { - remaining = - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->tx->base, handle->tx->channel); - } - else - { - remaining = - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->rx->base, handle->rx->channel); - } - } - - *count = handle->transfer.dataSize - remaining; - - return kStatus_Success; -} - -/*! - * brief Terminates a non-blocking LPI2C master transmission early. - * - * note It is not safe to call this function from an IRQ handler that has a higher priority than the - * eDMA peripheral's IRQ priority. - * - * param base The LPI2C peripheral base address. - * param handle Pointer to the LPI2C master driver handle. - * retval #kStatus_Success A transaction was successfully aborted. - * retval #kStatus_LPI2C_Idle There is not a DMA transaction currently in progress. - */ -status_t LPI2C_MasterTransferAbortEDMA(LPI2C_Type *base, lpi2c_master_edma_handle_t *handle) -{ - /* Catch when there is not an active transfer. */ - if (!handle->isBusy) - { - return kStatus_LPI2C_Idle; - } - - /* Terminate DMA transfers. */ - EDMA_AbortTransfer(handle->rx); - if (FSL_FEATURE_LPI2C_HAS_SEPARATE_DMA_RX_TX_REQn(base) != 0) - { - EDMA_AbortTransfer(handle->tx); - } - - /* Reset fifos. */ - base->MCR |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK; - - /* Send a stop command to finalize the transfer. */ - base->MTDR = (uint32_t)kStopCmd; - - /* Reset handle. */ - handle->isBusy = false; - - return kStatus_Success; -} - -/*! - * @brief DMA completion callback. - * @param dmaHandle DMA channel handle for the channel that completed. - * @param userData User data associated with the channel handle. For this callback, the user data is the - * LPI2C DMA driver handle. - * @param isTransferDone Whether the DMA transfer has completed. - * @param tcds Number of TCDs that completed. - */ -static void LPI2C_MasterEDMACallback(edma_handle_t *dmaHandle, void *userData, bool isTransferDone, uint32_t tcds) -{ - lpi2c_master_edma_handle_t *handle = (lpi2c_master_edma_handle_t *)userData; - - if (NULL == handle) - { - return; - } - - /* Check for errors. */ - status_t result = LPI2C_MasterCheckAndClearError(handle->base, LPI2C_MasterGetStatusFlags(handle->base)); - - /* Done with this transaction. */ - handle->isBusy = false; - - if (0U == (handle->transfer.flags & (uint32_t)kLPI2C_TransferNoStopFlag)) - { - /* Send a stop command to finalize the transfer. */ - handle->base->MTDR = (uint32_t)kStopCmd; - } - - /* Invoke callback. */ - if (handle->completionCallback != NULL) - { - handle->completionCallback(handle->base, handle, result, handle->userData); - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi.c deleted file mode 100644 index 4917a01c9e..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi.c +++ /dev/null @@ -1,2221 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpspi.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpspi" -#endif - -/*! - * @brief Default watermark values. - * - * The default watermarks are set to zero. - */ -enum _lpspi_default_watermarks -{ - kLpspiDefaultTxWatermark = 0, - kLpspiDefaultRxWatermark = 0, -}; - -/*! @brief Typedef for master interrupt handler. */ -typedef void (*lpspi_master_isr_t)(LPSPI_Type *base, lpspi_master_handle_t *handle); - -/*! @brief Typedef for slave interrupt handler. */ -typedef void (*lpspi_slave_isr_t)(LPSPI_Type *base, lpspi_slave_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Configures the LPSPI peripheral chip select polarity. - * - * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and - * configures the Pcs signal to operate with the desired characteristic. - * - * @param base LPSPI peripheral address. - * @param pcs The particular peripheral chip select (parameter value is of type lpspi_which_pcs_t) for which we wish to - * apply the active high or active low characteristic. - * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of - * type lpspi_pcs_polarity_config_t. - */ -static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base, - lpspi_which_pcs_t pcs, - lpspi_pcs_polarity_config_t activeLowOrHigh); - -/*! - * @brief Combine the write data for 1 byte to 4 bytes. - * This is not a public API. - */ -static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap); - -/*! - * @brief Separate the read data for 1 byte to 4 bytes. - * This is not a public API. - */ -static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap); - -/*! - * @brief Master fill up the TX FIFO with data. - * This is not a public API. - */ -static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle); - -/*! - * @brief Master finish up a transfer. - * It would call back if there is callback function and set the state to idle. - * This is not a public API. - */ -static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle); - -/*! - * @brief Slave fill up the TX FIFO with data. - * This is not a public API. - */ -static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle); - -/*! - * @brief Slave finish up a transfer. - * It would call back if there is callback function and set the state to idle. - * This is not a public API. - */ -static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle); - -/*! - * @brief LPSPI common interrupt handler. - * - * @param handle pointer to s_lpspiHandle which stores the transfer state. - */ -static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/ -static const uint8_t s_baudratePrescaler[] = {1, 2, 4, 8, 16, 32, 64, 128}; - -/*! @brief Pointers to lpspi bases for each instance. */ -static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS; - -/*! @brief Pointers to lpspi IRQ number for each instance. */ -static const IRQn_Type s_lpspiIRQ[] = LPSPI_IRQS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to lpspi clocks for each instance. */ -static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS; - -#if defined(LPSPI_PERIPH_CLOCKS) -static const clock_ip_name_t s_LpspiPeriphClocks[] = LPSPI_PERIPH_CLOCKS; -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Pointers to lpspi handles for each instance. */ -static void *s_lpspiHandle[ARRAY_SIZE(s_lpspiBases)]; - -/*! @brief Pointer to master IRQ handler for each instance. */ -static lpspi_master_isr_t s_lpspiMasterIsr; -/*! @brief Pointer to slave IRQ handler for each instance. */ -static lpspi_slave_isr_t s_lpspiSlaveIsr; -/* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/ -volatile uint8_t g_lpspiDummyData[ARRAY_SIZE(s_lpspiBases)] = {0}; - -/********************************************************************************************************************** - * Code - *********************************************************************************************************************/ - -/*! - * brief Get the LPSPI instance from peripheral base address. - * - * param base LPSPI peripheral base address. - * return LPSPI instance. - */ -uint32_t LPSPI_GetInstance(LPSPI_Type *base) -{ - uint8_t instance = 0; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_lpspiBases); instance++) - { - if (s_lpspiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_lpspiBases)); - - return instance; -} - -/*! - * brief Set up the dummy data. - * - * param base LPSPI peripheral address. - * param dummyData Data to be transferred when tx buffer is NULL. - * Note: - * This API has no effect when LPSPI in slave interrupt mode, because driver - * will set the TXMSK bit to 1 if txData is NULL, no data is loaded from transmit - * FIFO and output pin is tristated. - */ -void LPSPI_SetDummyData(LPSPI_Type *base, uint8_t dummyData) -{ - uint32_t instance = LPSPI_GetInstance(base); - g_lpspiDummyData[instance] = dummyData; -} - -/*! - * brief Initializes the LPSPI master. - * - * param base LPSPI peripheral address. - * param masterConfig Pointer to structure lpspi_master_config_t. - * param srcClock_Hz Module source input clock in Hertz - */ -void LPSPI_MasterInit(LPSPI_Type *base, const lpspi_master_config_t *masterConfig, uint32_t srcClock_Hz) -{ - assert(masterConfig); - - uint32_t tcrPrescaleValue = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPSPI_GetInstance(base); - /* Enable LPSPI clock */ - (void)CLOCK_EnableClock(s_lpspiClocks[instance]); - -#if defined(LPSPI_PERIPH_CLOCKS) - (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Set LPSPI to master */ - LPSPI_SetMasterSlaveMode(base, kLPSPI_Master); - - /* Set specific PCS to active high or low */ - LPSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow); - - /* Set Configuration Register 1 related setting.*/ - base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK | LPSPI_CFGR1_NOSTALL_MASK)) | - LPSPI_CFGR1_OUTCFG(masterConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(masterConfig->pinCfg) | - LPSPI_CFGR1_NOSTALL(0); - - /* Set baudrate and delay times*/ - (void)LPSPI_MasterSetBaudRate(base, masterConfig->baudRate, srcClock_Hz, &tcrPrescaleValue); - - /* Set default watermarks */ - LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark); - - /* Set Transmit Command Register*/ - base->TCR = LPSPI_TCR_CPOL(masterConfig->cpol) | LPSPI_TCR_CPHA(masterConfig->cpha) | - LPSPI_TCR_LSBF(masterConfig->direction) | LPSPI_TCR_FRAMESZ(masterConfig->bitsPerFrame - 1U) | - LPSPI_TCR_PRESCALE(tcrPrescaleValue) | LPSPI_TCR_PCS(masterConfig->whichPcs); - - LPSPI_Enable(base, true); - - (void)LPSPI_MasterSetDelayTimes(base, masterConfig->pcsToSckDelayInNanoSec, kLPSPI_PcsToSck, srcClock_Hz); - (void)LPSPI_MasterSetDelayTimes(base, masterConfig->lastSckToPcsDelayInNanoSec, kLPSPI_LastSckToPcs, srcClock_Hz); - (void)LPSPI_MasterSetDelayTimes(base, masterConfig->betweenTransferDelayInNanoSec, kLPSPI_BetweenTransfer, - srcClock_Hz); - - LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA); -} - -/*! - * brief Sets the lpspi_master_config_t structure to default values. - * - * This API initializes the configuration structure for LPSPI_MasterInit(). - * The initialized structure can remain unchanged in LPSPI_MasterInit(), or can be modified - * before calling the LPSPI_MasterInit(). - * Example: - * code - * lpspi_master_config_t masterConfig; - * LPSPI_MasterGetDefaultConfig(&masterConfig); - * endcode - * param masterConfig pointer to lpspi_master_config_t structure - */ -void LPSPI_MasterGetDefaultConfig(lpspi_master_config_t *masterConfig) -{ - assert(masterConfig); - - /* Initializes the configure structure to zero. */ - (void)memset(masterConfig, 0, sizeof(*masterConfig)); - - masterConfig->baudRate = 500000; - masterConfig->bitsPerFrame = 8; - masterConfig->cpol = kLPSPI_ClockPolarityActiveHigh; - masterConfig->cpha = kLPSPI_ClockPhaseFirstEdge; - masterConfig->direction = kLPSPI_MsbFirst; - - masterConfig->pcsToSckDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U; - masterConfig->lastSckToPcsDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U; - masterConfig->betweenTransferDelayInNanoSec = 1000000000U / masterConfig->baudRate * 2U; - - masterConfig->whichPcs = kLPSPI_Pcs0; - masterConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; - - masterConfig->pinCfg = kLPSPI_SdiInSdoOut; - masterConfig->dataOutConfig = kLpspiDataOutRetained; -} - -/*! - * brief LPSPI slave configuration. - * - * param base LPSPI peripheral address. - * param slaveConfig Pointer to a structure lpspi_slave_config_t. - */ -void LPSPI_SlaveInit(LPSPI_Type *base, const lpspi_slave_config_t *slaveConfig) -{ - assert(slaveConfig); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPSPI_GetInstance(base); - /* Enable LPSPI clock */ - (void)CLOCK_EnableClock(s_lpspiClocks[instance]); - -#if defined(LPSPI_PERIPH_CLOCKS) - (void)CLOCK_EnableClock(s_LpspiPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - LPSPI_SetMasterSlaveMode(base, kLPSPI_Slave); - - LPSPI_SetOnePcsPolarity(base, slaveConfig->whichPcs, slaveConfig->pcsActiveHighOrLow); - - base->CFGR1 = (base->CFGR1 & ~(LPSPI_CFGR1_OUTCFG_MASK | LPSPI_CFGR1_PINCFG_MASK)) | - LPSPI_CFGR1_OUTCFG(slaveConfig->dataOutConfig) | LPSPI_CFGR1_PINCFG(slaveConfig->pinCfg); - - LPSPI_SetFifoWatermarks(base, (uint32_t)kLpspiDefaultTxWatermark, (uint32_t)kLpspiDefaultRxWatermark); - - base->TCR = LPSPI_TCR_CPOL(slaveConfig->cpol) | LPSPI_TCR_CPHA(slaveConfig->cpha) | - LPSPI_TCR_LSBF(slaveConfig->direction) | LPSPI_TCR_FRAMESZ(slaveConfig->bitsPerFrame - 1U); - - /* This operation will set the dummy data for edma transfer, no effect in interrupt way. */ - LPSPI_SetDummyData(base, LPSPI_DUMMY_DATA); - - LPSPI_Enable(base, true); -} - -/*! - * brief Sets the lpspi_slave_config_t structure to default values. - * - * This API initializes the configuration structure for LPSPI_SlaveInit(). - * The initialized structure can remain unchanged in LPSPI_SlaveInit() or can be modified - * before calling the LPSPI_SlaveInit(). - * Example: - * code - * lpspi_slave_config_t slaveConfig; - * LPSPI_SlaveGetDefaultConfig(&slaveConfig); - * endcode - * param slaveConfig pointer to lpspi_slave_config_t structure. - */ -void LPSPI_SlaveGetDefaultConfig(lpspi_slave_config_t *slaveConfig) -{ - assert(slaveConfig); - - /* Initializes the configure structure to zero. */ - (void)memset(slaveConfig, 0, sizeof(*slaveConfig)); - - slaveConfig->bitsPerFrame = 8; /*!< Bits per frame, minimum 8, maximum 4096.*/ - slaveConfig->cpol = kLPSPI_ClockPolarityActiveHigh; /*!< Clock polarity. */ - slaveConfig->cpha = kLPSPI_ClockPhaseFirstEdge; /*!< Clock phase. */ - slaveConfig->direction = kLPSPI_MsbFirst; /*!< MSB or LSB data shift direction. */ - - slaveConfig->whichPcs = kLPSPI_Pcs0; /*!< Desired Peripheral Chip Select (pcs) */ - slaveConfig->pcsActiveHighOrLow = kLPSPI_PcsActiveLow; /*!< Desired PCS active high or low */ - - slaveConfig->pinCfg = kLPSPI_SdiInSdoOut; - slaveConfig->dataOutConfig = kLpspiDataOutRetained; -} - -/*! - * brief Restores the LPSPI peripheral to reset state. Note that this function - * sets all registers to reset state. As a result, the LPSPI module can't work after calling - * this API. - * param base LPSPI peripheral address. - */ -void LPSPI_Reset(LPSPI_Type *base) -{ - /* Reset all internal logic and registers, except the Control Register. Remains set until cleared by software.*/ - base->CR |= LPSPI_CR_RST_MASK; - - /* Software reset doesn't reset the CR, so manual reset the FIFOs */ - base->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK; - - /* Master logic is not reset and module is disabled.*/ - base->CR = 0x00U; -} - -/*! - * brief De-initializes the LPSPI peripheral. Call this API to disable the LPSPI clock. - * param base LPSPI peripheral address. - */ -void LPSPI_Deinit(LPSPI_Type *base) -{ - /* Reset to default value */ - LPSPI_Reset(base); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPSPI_GetInstance(base); - /* Enable LPSPI clock */ - (void)CLOCK_DisableClock(s_lpspiClocks[instance]); - -#if defined(LPSPI_PERIPH_CLOCKS) - (void)CLOCK_DisableClock(s_LpspiPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -static void LPSPI_SetOnePcsPolarity(LPSPI_Type *base, - lpspi_which_pcs_t pcs, - lpspi_pcs_polarity_config_t activeLowOrHigh) -{ - uint32_t cfgr1Value = 0; - /* Clear the PCS polarity bit */ - cfgr1Value = base->CFGR1 & ~(1UL << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs)); - - /* Configure the PCS polarity bit according to the activeLowOrHigh setting */ - base->CFGR1 = cfgr1Value | ((uint32_t)activeLowOrHigh << (LPSPI_CFGR1_PCSPOL_SHIFT + (uint32_t)pcs)); -} - -/*! - * brief Sets the LPSPI baud rate in bits per second. - * - * This function takes in the desired bitsPerSec (baud rate) and calculates the nearest - * possible baud rate without exceeding the desired baud rate and returns the - * calculated baud rate in bits-per-second. It requires the caller to provide - * the frequency of the module source clock (in Hertz). Note that the baud rate - * does not go into effect until the Transmit Control Register (TCR) is programmed - * with the prescale value. Hence, this function returns the prescale tcrPrescaleValue - * parameter for later programming in the TCR. The higher level - * peripheral driver should alert the user of an out of range baud rate input. - * - * Note that the LPSPI module must first be disabled before configuring this. - * Note that the LPSPI module must be configured for master mode before configuring this. - * - * param base LPSPI peripheral address. - * param baudRate_Bps The desired baud rate in bits per second. - * param srcClock_Hz Module source input clock in Hertz. - * param tcrPrescaleValue The TCR prescale value needed to program the TCR. - * return The actual calculated baud rate. This function may also return a "0" if the - * LPSPI is not configured for master mode or if the LPSPI module is not disabled. - */ - -uint32_t LPSPI_MasterSetBaudRate(LPSPI_Type *base, - uint32_t baudRate_Bps, - uint32_t srcClock_Hz, - uint32_t *tcrPrescaleValue) -{ - assert(tcrPrescaleValue); - - /* For master mode configuration only, if slave mode detected, return 0. - * Also, the LPSPI module needs to be disabled first, if enabled, return 0 - */ - if ((!LPSPI_IsMaster(base)) || ((base->CR & LPSPI_CR_MEN_MASK) != 0U)) - { - return 0U; - } - - uint32_t prescaler, bestPrescaler; - uint32_t scaler, bestScaler; - uint32_t realBaudrate, bestBaudrate; - uint32_t diff, min_diff; - uint32_t desiredBaudrate = baudRate_Bps; - - /* find combination of prescaler and scaler resulting in baudrate closest to the - * requested value - */ - min_diff = 0xFFFFFFFFU; - - /* Set to maximum divisor value bit settings so that if baud rate passed in is less - * than the minimum possible baud rate, then the SPI will be configured to the lowest - * possible baud rate - */ - bestPrescaler = 7; - bestScaler = 255; - - bestBaudrate = 0; /* required to avoid compilation warning */ - - /* In all for loops, if min_diff = 0, the exit for loop*/ - for (prescaler = 0U; prescaler < 8U; prescaler++) - { - if (min_diff == 0U) - { - break; - } - for (scaler = 0U; scaler < 256U; scaler++) - { - if (min_diff == 0U) - { - break; - } - realBaudrate = (srcClock_Hz / (s_baudratePrescaler[prescaler] * (scaler + 2U))); - - /* calculate the baud rate difference based on the conditional statement - * that states that the calculated baud rate must not exceed the desired baud rate - */ - if (desiredBaudrate >= realBaudrate) - { - diff = desiredBaudrate - realBaudrate; - if (min_diff > diff) - { - /* a better match found */ - min_diff = diff; - bestPrescaler = prescaler; - bestScaler = scaler; - bestBaudrate = realBaudrate; - } - } - } - } - - /* Write the best baud rate scalar to the CCR. - * Note, no need to check for error since we've already checked to make sure the module is - * disabled and in master mode. Also, there is a limit on the maximum divider so we will not - * exceed this. - */ - base->CCR = (base->CCR & ~LPSPI_CCR_SCKDIV_MASK) | LPSPI_CCR_SCKDIV(bestScaler); - - /* return the best prescaler value for user to use later */ - *tcrPrescaleValue = bestPrescaler; - - /* return the actual calculated baud rate */ - return bestBaudrate; -} - -/*! - * brief Manually configures a specific LPSPI delay parameter (module must be disabled to - * change the delay values). - * - * This function configures the following: - * SCK to PCS delay, or - * PCS to SCK delay, or - * The configurations must occur between the transfer delay. - * - * The delay names are available in type lpspi_delay_type_t. - * - * The user passes the desired delay along with the delay value. - * This allows the user to directly set the delay values if they have - * pre-calculated them or if they simply wish to manually increment the value. - * - * Note that the LPSPI module must first be disabled before configuring this. - * Note that the LPSPI module must be configured for master mode before configuring this. - * - * param base LPSPI peripheral address. - * param scaler The 8-bit delay value 0x00 to 0xFF (255). - * param whichDelay The desired delay to configure, must be of type lpspi_delay_type_t. - */ -void LPSPI_MasterSetDelayScaler(LPSPI_Type *base, uint32_t scaler, lpspi_delay_type_t whichDelay) -{ - /*These settings are only relevant in master mode */ - switch (whichDelay) - { - case kLPSPI_PcsToSck: - base->CCR = (base->CCR & (~LPSPI_CCR_PCSSCK_MASK)) | LPSPI_CCR_PCSSCK(scaler); - - break; - case kLPSPI_LastSckToPcs: - base->CCR = (base->CCR & (~LPSPI_CCR_SCKPCS_MASK)) | LPSPI_CCR_SCKPCS(scaler); - - break; - case kLPSPI_BetweenTransfer: - base->CCR = (base->CCR & (~LPSPI_CCR_DBT_MASK)) | LPSPI_CCR_DBT(scaler); - - break; - default: - assert(false); - break; - } -} - -/*! - * brief Calculates the delay based on the desired delay input in nanoseconds (module must be - * disabled to change the delay values). - * - * This function calculates the values for the following: - * SCK to PCS delay, or - * PCS to SCK delay, or - * The configurations must occur between the transfer delay. - * - * The delay names are available in type lpspi_delay_type_t. - * - * The user passes the desired delay and the desired delay value in - * nano-seconds. The function calculates the value needed for the desired delay parameter - * and returns the actual calculated delay because an exact delay match may not be possible. In this - * case, the closest match is calculated without going below the desired delay value input. - * It is possible to input a very large delay value that exceeds the capability of the part, in - * which case the maximum supported delay is returned. It is up to the higher level - * peripheral driver to alert the user of an out of range delay input. - * - * Note that the LPSPI module must be configured for master mode before configuring this. And note that - * the delayTime = LPSPI_clockSource / (PRESCALE * Delay_scaler). - * - * param base LPSPI peripheral address. - * param delayTimeInNanoSec The desired delay value in nano-seconds. - * param whichDelay The desired delay to configuration, which must be of type lpspi_delay_type_t. - * param srcClock_Hz Module source input clock in Hertz. - * return actual Calculated delay value in nano-seconds. - */ -uint32_t LPSPI_MasterSetDelayTimes(LPSPI_Type *base, - uint32_t delayTimeInNanoSec, - lpspi_delay_type_t whichDelay, - uint32_t srcClock_Hz) -{ - uint64_t realDelay, bestDelay; - uint32_t scaler, bestScaler; - uint32_t diff, min_diff; - uint64_t initialDelayNanoSec; - uint32_t clockDividedPrescaler; - - /* For delay between transfer, an additional scaler value is needed */ - uint32_t additionalScaler = 0; - - /*As the RM note, the LPSPI baud rate clock is itself divided by the PRESCALE setting, which can vary between - * transfers.*/ - clockDividedPrescaler = - srcClock_Hz / s_baudratePrescaler[(base->TCR & LPSPI_TCR_PRESCALE_MASK) >> LPSPI_TCR_PRESCALE_SHIFT]; - - /* Find combination of prescaler and scaler resulting in the delay closest to the requested value.*/ - min_diff = 0xFFFFFFFFU; - - /* Initialize scaler to max value to generate the max delay */ - bestScaler = 0xFFU; - - /* Calculate the initial (min) delay and maximum possible delay based on the specific delay as - * the delay divisors are slightly different based on which delay we are configuring. - */ - if (whichDelay == kLPSPI_BetweenTransfer) - { - /* First calculate the initial, default delay, note min delay is 2 clock cycles. Due to large size of - calculated values (uint64_t), we need to break up the calculation into several steps to ensure - accurate calculated results - */ - initialDelayNanoSec = 1000000000U; - initialDelayNanoSec *= 2U; - initialDelayNanoSec /= clockDividedPrescaler; - - /* Calculate the maximum delay */ - bestDelay = 1000000000U; - bestDelay *= 257U; /* based on DBT+2, or 255 + 2 */ - bestDelay /= clockDividedPrescaler; - - additionalScaler = 1U; - } - else - { - /* First calculate the initial, default delay, min delay is 1 clock cycle. Due to large size of calculated - values (uint64_t), we need to break up the calculation into several steps to ensure accurate calculated - results. - */ - initialDelayNanoSec = 1000000000U; - initialDelayNanoSec /= clockDividedPrescaler; - - /* Calculate the maximum delay */ - bestDelay = 1000000000U; - bestDelay *= 256U; /* based on SCKPCS+1 or PCSSCK+1, or 255 + 1 */ - bestDelay /= clockDividedPrescaler; - - additionalScaler = 0U; - } - - /* If the initial, default delay is already greater than the desired delay, then - * set the delay to their initial value (0) and return the delay. In other words, - * there is no way to decrease the delay value further. - */ - if (initialDelayNanoSec >= delayTimeInNanoSec) - { - LPSPI_MasterSetDelayScaler(base, 0, whichDelay); - return (uint32_t)initialDelayNanoSec; - } - - /* If min_diff = 0, the exit for loop */ - for (scaler = 0U; scaler < 256U; scaler++) - { - if (min_diff == 0U) - { - break; - } - /* Calculate the real delay value as we cycle through the scaler values. - Due to large size of calculated values (uint64_t), we need to break up the - calculation into several steps to ensure accurate calculated results - */ - realDelay = 1000000000U; - realDelay *= ((uint64_t)scaler + 1UL + (uint64_t)additionalScaler); - realDelay /= clockDividedPrescaler; - - /* calculate the delay difference based on the conditional statement - * that states that the calculated delay must not be less then the desired delay - */ - if (realDelay >= delayTimeInNanoSec) - { - diff = (uint32_t)(realDelay - (uint64_t)delayTimeInNanoSec); - if (min_diff > diff) - { - /* a better match found */ - min_diff = diff; - bestScaler = scaler; - bestDelay = realDelay; - } - } - } - - /* write the best scaler value for the delay */ - LPSPI_MasterSetDelayScaler(base, bestScaler, whichDelay); - - /* return the actual calculated delay value (in ns) */ - return (uint32_t)bestDelay; -} - -/*Transactional APIs -- Master*/ - -/*! - * brief Initializes the LPSPI master handle. - * - * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a - * specified LPSPI instance, call this API once to get the initialized handle. - - * param base LPSPI peripheral address. - * param handle LPSPI handle pointer to lpspi_master_handle_t. - * param callback DSPI callback. - * param userData callback function parameter. - */ -void LPSPI_MasterTransferCreateHandle(LPSPI_Type *base, - lpspi_master_handle_t *handle, - lpspi_master_transfer_callback_t callback, - void *userData) -{ - assert(handle); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - s_lpspiHandle[LPSPI_GetInstance(base)] = handle; - - /* Set irq handler. */ - s_lpspiMasterIsr = LPSPI_MasterTransferHandleIRQ; - - handle->callback = callback; - handle->userData = userData; -} - -/*! - * brief Check the argument for transfer . - * - * param transfer the transfer struct to be used. - * param bitPerFrame The bit size of one frame. - * param bytePerFrame The byte size of one frame. - * return Return true for right and false for wrong. - */ -bool LPSPI_CheckTransferArgument(lpspi_transfer_t *transfer, uint32_t bitsPerFrame, uint32_t bytesPerFrame) -{ - assert(transfer); - - /* If the transfer count is zero, then return immediately.*/ - if (transfer->dataSize == 0U) - { - return false; - } - - /* If both send buffer and receive buffer is null */ - if ((NULL == (transfer->txData)) && (NULL == (transfer->rxData))) - { - return false; - } - - /*The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4 . - *For bytesPerFrame greater than 4 situation: - *the transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4 , - *otherwise , the transfer data size can be integer multiples of bytesPerFrame. - */ - if (bytesPerFrame <= 4U) - { - if ((transfer->dataSize % bytesPerFrame) != 0U) - { - return false; - } - } - else - { - if ((bytesPerFrame % 4U) != 0U) - { - if (transfer->dataSize != bytesPerFrame) - { - return false; - } - } - else - { - if ((transfer->dataSize % bytesPerFrame) != 0U) - { - return false; - } - } - } - - return true; -} - -/*! - * brief LPSPI master transfer data using a polling method. - * - * This function transfers data using a polling method. This is a blocking function, which does not return until all - * transfers have been - * completed. - * - * Note: - * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. - * For bytesPerFrame greater than 4: - * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4. - * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. - * - * param base LPSPI peripheral address. - * param transfer pointer to lpspi_transfer_t structure. - * return status of status_t. - */ -status_t LPSPI_MasterTransferBlocking(LPSPI_Type *base, lpspi_transfer_t *transfer) -{ - assert(transfer); - - uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U; - uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U; - uint32_t temp = 0U; - uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)]; - - if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame)) - { - return kStatus_InvalidArgument; - } - - /* Check that LPSPI is not busy.*/ - if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ModuleBusyFlag) != 0U) - { - return kStatus_LPSPI_Busy; - } - - uint8_t *txData = transfer->txData; - uint8_t *rxData = transfer->rxData; - uint32_t txRemainingByteCount = transfer->dataSize; - uint32_t rxRemainingByteCount = transfer->dataSize; - - uint8_t bytesEachWrite; - uint8_t bytesEachRead; - - uint32_t readData = 0U; - uint32_t wordToSend = - ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24); - - /*The TX and RX FIFO sizes are always the same*/ - uint32_t fifoSize = LPSPI_GetRxFifoSize(base); - uint32_t rxFifoMaxBytes = MIN(bytesPerFrame, 4U) * fifoSize; - uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT; - - bool isPcsContinuous = ((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U); - bool isRxMask = false; - bool isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U); - -#if SPI_RETRY_TIMES - uint32_t waitTimes; -#endif - - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - - if (NULL == rxData) - { - isRxMask = true; - } - - LPSPI_Enable(base, false); - base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK); - /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */ - temp = base->CFGR1; - temp &= LPSPI_CFGR1_PINCFG_MASK; - if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) - { - if (NULL == txData) - { - base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK; - } - /* The 3-wire mode can't send and receive data at the same time. */ - if ((txData != NULL) && (rxData != NULL)) - { - return kStatus_InvalidArgument; - } - } - LPSPI_Enable(base, true); - - base->TCR = - (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) | - LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_PCS(whichPcs); - - if (bytesPerFrame <= 4U) - { - bytesEachWrite = (uint8_t)bytesPerFrame; - bytesEachRead = (uint8_t)bytesPerFrame; - } - else - { - bytesEachWrite = 4U; - bytesEachRead = 4U; - } - - /*Write the TX data until txRemainingByteCount is equal to 0 */ - while (txRemainingByteCount > 0U) - { - if (txRemainingByteCount < bytesEachWrite) - { - bytesEachWrite = (uint8_t)txRemainingByteCount; - } - - /*Wait until TX FIFO is not full*/ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U)) -#else - while (LPSPI_GetTxFifoCount(base) == fifoSize) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - - /* To prevent rxfifo overflow, ensure transmitting and receiving are executed in parallel */ - if (((NULL == rxData) || (rxRemainingByteCount - txRemainingByteCount) < rxFifoMaxBytes)) - { - if (txData != NULL) - { - wordToSend = LPSPI_CombineWriteData(txData, bytesEachWrite, isByteSwap); - txData += bytesEachWrite; - } - - LPSPI_WriteData(base, wordToSend); - txRemainingByteCount -= bytesEachWrite; - } - - /*Check whether there is RX data in RX FIFO . Read out the RX data so that the RX FIFO would not overrun.*/ - if (rxData != NULL) - { -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U)) -#else - while (LPSPI_GetRxFifoCount(base) != 0U) -#endif - { - readData = LPSPI_ReadData(base); - if (rxRemainingByteCount < bytesEachRead) - { - bytesEachRead = (uint8_t)rxRemainingByteCount; - } - - LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap); - rxData += bytesEachRead; - - rxRemainingByteCount -= bytesEachRead; - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - } - } - - /* After write all the data in TX FIFO , should write the TCR_CONTC to 0 to de-assert the PCS. Note that TCR - * register also use the TX FIFO. - */ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetTxFifoCount(base) == fifoSize) && (--waitTimes != 0U)) -#else - while (LPSPI_GetTxFifoCount(base) == fifoSize) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK)); - - /*Read out the RX data in FIFO*/ - if (rxData != NULL) - { - while (rxRemainingByteCount > 0U) - { -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetRxFifoCount(base) != 0U) && (--waitTimes != 0U)) -#else - while (LPSPI_GetRxFifoCount(base) != 0U) -#endif - { - readData = LPSPI_ReadData(base); - - if (rxRemainingByteCount < bytesEachRead) - { - bytesEachRead = (uint8_t)rxRemainingByteCount; - } - - LPSPI_SeparateReadData(rxData, readData, bytesEachRead, isByteSwap); - rxData += bytesEachRead; - - rxRemainingByteCount -= bytesEachRead; - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - } - } - else - { - /* If no RX buffer, then transfer is not complete until transfer complete flag sets */ -#if SPI_RETRY_TIMES - waitTimes = SPI_RETRY_TIMES; - while (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U) && (--waitTimes != 0U)) -#else - while ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) == 0U) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - } - - return kStatus_Success; -} - -/*! - * brief LPSPI master transfer data using an interrupt method. - * - * This function transfers data using an interrupt method. This is a non-blocking function, which returns right away. - * When all data - * is transferred, the callback function is called. - * - * Note: - * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. - * For bytesPerFrame greater than 4: - * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not integer multiples of 4. - * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_master_handle_t structure which stores the transfer state. - * param transfer pointer to lpspi_transfer_t structure. - * return status of status_t. - */ -status_t LPSPI_MasterTransferNonBlocking(LPSPI_Type *base, lpspi_master_handle_t *handle, lpspi_transfer_t *transfer) -{ - assert(handle); - assert(transfer); - - uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U; - uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U; - uint32_t temp = 0U; - uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)]; - bool isPcsContinuous; - uint32_t tmpTimes; - - if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame)) - { - return kStatus_InvalidArgument; - } - - /* Check that we're not busy.*/ - if (handle->state == (uint8_t)kLPSPI_Busy) - { - return kStatus_LPSPI_Busy; - } - - handle->state = (uint8_t)kLPSPI_Busy; - - bool isRxMask = false; - - uint8_t txWatermark; - - uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT; - - handle->txData = transfer->txData; - handle->rxData = transfer->rxData; - handle->txRemainingByteCount = transfer->dataSize; - handle->rxRemainingByteCount = transfer->dataSize; - handle->totalByteCount = transfer->dataSize; - - handle->writeTcrInIsr = false; - - handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U); - handle->readRegRemainingTimes = handle->writeRegRemainingTimes; - - handle->txBuffIfNull = - ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24); - - /*The TX and RX FIFO sizes are always the same*/ - handle->fifoSize = LPSPI_GetRxFifoSize(base); - - handle->isPcsContinuous = ((transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous) != 0U); - isPcsContinuous = handle->isPcsContinuous; - handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U); - - /*Set the RX and TX watermarks to reduce the ISR times.*/ - if (handle->fifoSize > 1U) - { - txWatermark = 1U; - handle->rxWatermark = handle->fifoSize - 2U; - } - else - { - txWatermark = 0U; - handle->rxWatermark = 0U; - } - - LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark); - - LPSPI_Enable(base, false); - /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */ - base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK); - /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */ - temp = base->CFGR1; - temp &= LPSPI_CFGR1_PINCFG_MASK; - if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) - { - if (NULL == handle->txData) - { - base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK; - } - /* The 3-wire mode can't send and receive data at the same time. */ - if ((NULL != handle->txData) && (NULL != handle->rxData)) - { - return kStatus_InvalidArgument; - } - } - LPSPI_Enable(base, true); - - /*Flush FIFO , clear status , disable all the inerrupts.*/ - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - /* If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO). - * For master transfer , we'd better not masked the transmit data in TCR since the transfer flow is hard to - * controlled by software.*/ - if (handle->rxData == NULL) - { - isRxMask = true; - handle->rxRemainingByteCount = 0; - } - - base->TCR = - (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) | - LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_PCS(whichPcs); - - /*Calculate the bytes for write/read the TX/RX register each time*/ - if (bytesPerFrame <= 4U) - { - handle->bytesEachWrite = (uint8_t)bytesPerFrame; - handle->bytesEachRead = (uint8_t)bytesPerFrame; - } - else - { - handle->bytesEachWrite = 4U; - handle->bytesEachRead = 4U; - } - - /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX , - * and you should also enable the INTMUX interupt in your application. - */ - (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]); - - /*TCR is also shared the FIFO , so wait for TCR written.*/ -#if SPI_RETRY_TIMES - uint32_t waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetTxFifoCount(base) != 0U) && (--waitTimes != 0U)) -#else - while (LPSPI_GetTxFifoCount(base) != 0U) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - - /*Fill up the TX data in FIFO */ - LPSPI_MasterTransferFillUpTxFifo(base, handle); - - /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data. - * The IRQ handler will get the status of RX and TX interrupt flags. - */ - if (handle->rxData != NULL) - { - /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there - *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark. - */ - tmpTimes = handle->readRegRemainingTimes; - if (tmpTimes <= handle->rxWatermark) - { - base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(tmpTimes - 1U); - } - - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); - } - else - { - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable); - } - - return kStatus_Success; -} - -static void LPSPI_MasterTransferFillUpTxFifo(LPSPI_Type *base, lpspi_master_handle_t *handle) -{ - assert(handle); - - uint32_t wordToSend = 0; - uint8_t fifoSize = handle->fifoSize; - uint32_t writeRegRemainingTimes = handle->writeRegRemainingTimes; - uint32_t readRegRemainingTimes = handle->readRegRemainingTimes; - size_t txRemainingByteCount = handle->txRemainingByteCount; - uint8_t bytesEachWrite = handle->bytesEachWrite; - bool isByteSwap = handle->isByteSwap; - - /* Make sure the difference in remaining TX and RX byte counts does not exceed FIFO depth - * and that the number of TX FIFO entries does not exceed the FIFO depth. - * But no need to make the protection if there is no rxData. - */ - while ((LPSPI_GetTxFifoCount(base) < fifoSize) && - (((readRegRemainingTimes - writeRegRemainingTimes) < (uint32_t)fifoSize) || (handle->rxData == NULL))) - { - if (txRemainingByteCount < (size_t)bytesEachWrite) - { - handle->bytesEachWrite = (uint8_t)txRemainingByteCount; - bytesEachWrite = handle->bytesEachWrite; - } - - if (handle->txData != NULL) - { - wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap); - handle->txData += bytesEachWrite; - } - else - { - wordToSend = handle->txBuffIfNull; - } - - /*Write the word to TX register*/ - LPSPI_WriteData(base, wordToSend); - - /*Decrease the write TX register times.*/ - --handle->writeRegRemainingTimes; - writeRegRemainingTimes = handle->writeRegRemainingTimes; - - /*Decrease the remaining TX byte count.*/ - handle->txRemainingByteCount -= (size_t)bytesEachWrite; - txRemainingByteCount = handle->txRemainingByteCount; - - if (handle->txRemainingByteCount == 0U) - { - /* If PCS is continuous, update TCR to de-assert PCS */ - if (handle->isPcsContinuous) - { - /* Only write to the TCR if the FIFO has room */ - if (LPSPI_GetTxFifoCount(base) < fifoSize) - { - base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK)); - handle->writeTcrInIsr = false; - } - /* Else, set a global flag to tell the ISR to do write to the TCR */ - else - { - handle->writeTcrInIsr = true; - } - } - break; - } - } -} - -static void LPSPI_MasterTransferComplete(LPSPI_Type *base, lpspi_master_handle_t *handle) -{ - assert(handle); - - /* Disable interrupt requests*/ - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - handle->state = (uint8_t)kLPSPI_Idle; - - if (handle->callback != NULL) - { - handle->callback(base, handle, kStatus_Success, handle->userData); - } -} - -/*! - * brief Gets the master transfer remaining bytes. - * - * This function gets the master transfer remaining bytes. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_master_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the non-blocking transaction. - * return status of status_t. - */ -status_t LPSPI_MasterTransferGetCount(LPSPI_Type *base, lpspi_master_handle_t *handle, size_t *count) -{ - assert(handle); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state != (uint8_t)kLPSPI_Busy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - size_t remainingByte; - - if (handle->rxData != NULL) - { - remainingByte = handle->rxRemainingByteCount; - } - else - { - remainingByte = handle->txRemainingByteCount; - } - - *count = handle->totalByteCount - remainingByte; - - return kStatus_Success; -} - -/*! - * brief LPSPI master abort transfer which uses an interrupt method. - * - * This function aborts a transfer which uses an interrupt method. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_master_handle_t structure which stores the transfer state. - */ -void LPSPI_MasterTransferAbort(LPSPI_Type *base, lpspi_master_handle_t *handle) -{ - assert(handle); - - /* Disable interrupt requests*/ - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - LPSPI_Reset(base); - - handle->state = (uint8_t)kLPSPI_Idle; - handle->txRemainingByteCount = 0; - handle->rxRemainingByteCount = 0; -} - -/*! - * brief LPSPI Master IRQ handler function. - * - * This function processes the LPSPI transmit and receive IRQ. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_master_handle_t structure which stores the transfer state. - */ -void LPSPI_MasterTransferHandleIRQ(LPSPI_Type *base, lpspi_master_handle_t *handle) -{ - assert(handle); - - uint32_t readData; - uint8_t bytesEachRead = handle->bytesEachRead; - bool isByteSwap = handle->isByteSwap; - uint32_t readRegRemainingTimes = handle->readRegRemainingTimes; - - if (handle->rxData != NULL) - { - if (handle->rxRemainingByteCount != 0U) - { - /* First, disable the interrupts to avoid potentially triggering another interrupt - * while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll - * re-enable the interrupts based on the LPSPI state after reading out the FIFO. - */ - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); - - while ((LPSPI_GetRxFifoCount(base) != 0U) && (handle->rxRemainingByteCount != 0U)) - { - /*Read out the data*/ - readData = LPSPI_ReadData(base); - - /*Decrease the read RX register times.*/ - --handle->readRegRemainingTimes; - readRegRemainingTimes = handle->readRegRemainingTimes; - - if (handle->rxRemainingByteCount < (size_t)bytesEachRead) - { - handle->bytesEachRead = (uint8_t)(handle->rxRemainingByteCount); - bytesEachRead = handle->bytesEachRead; - } - - LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap); - handle->rxData += bytesEachRead; - - /*Decrease the remaining RX byte count.*/ - handle->rxRemainingByteCount -= (size_t)bytesEachRead; - } - - /* Re-enable the interrupts only if rxCount indicates there is more data to receive, - * else we may get a spurious interrupt. - * */ - if (handle->rxRemainingByteCount != 0U) - { - /* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */ - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); - } - } - - /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there - *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark. - */ - if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark) - { - base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | - LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U)); - } - } - - if (handle->txRemainingByteCount != 0U) - { - LPSPI_MasterTransferFillUpTxFifo(base, handle); - } - else - { - if ((LPSPI_GetTxFifoCount(base) < (handle->fifoSize))) - { - if ((handle->isPcsContinuous) && (handle->writeTcrInIsr)) - { - base->TCR = (base->TCR & ~(LPSPI_TCR_CONTC_MASK)); - handle->writeTcrInIsr = false; - } - } - } - - if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U) && (!handle->writeTcrInIsr)) - { - /* If no RX buffer, then transfer is not complete until transfer complete flag sets */ - if (handle->rxData == NULL) - { - if ((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransferCompleteFlag) != 0U) - { - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransferCompleteFlag); - /* Complete the transfer and disable the interrupts */ - LPSPI_MasterTransferComplete(base, handle); - } - else - { - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransferCompleteInterruptEnable); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable); - } - } - else - { - /* Complete the transfer and disable the interrupts */ - LPSPI_MasterTransferComplete(base, handle); - } - } -} - -/*Transactional APIs -- Slave*/ -/*! - * brief Initializes the LPSPI slave handle. - * - * This function initializes the LPSPI handle, which can be used for other LPSPI transactional APIs. Usually, for a - * specified LPSPI instance, call this API once to get the initialized handle. - * - * param base LPSPI peripheral address. - * param handle LPSPI handle pointer to lpspi_slave_handle_t. - * param callback DSPI callback. - * param userData callback function parameter. - */ -void LPSPI_SlaveTransferCreateHandle(LPSPI_Type *base, - lpspi_slave_handle_t *handle, - lpspi_slave_transfer_callback_t callback, - void *userData) -{ - assert(handle); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - s_lpspiHandle[LPSPI_GetInstance(base)] = handle; - - /* Set irq handler. */ - s_lpspiSlaveIsr = LPSPI_SlaveTransferHandleIRQ; - - handle->callback = callback; - handle->userData = userData; -} - -/*! - * brief LPSPI slave transfer data using an interrupt method. - * - * This function transfer data using an interrupt method. This is a non-blocking function, which returns right away. - * When all data - * is transferred, the callback function is called. - * - * Note: - * The transfer data size should be integer multiples of bytesPerFrame if bytesPerFrame is less than or equal to 4. - * For bytesPerFrame greater than 4: - * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4. - * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. - * param transfer pointer to lpspi_transfer_t structure. - * return status of status_t. - */ -status_t LPSPI_SlaveTransferNonBlocking(LPSPI_Type *base, lpspi_slave_handle_t *handle, lpspi_transfer_t *transfer) -{ - assert(handle); - assert(transfer); - - uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U; - uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U; - uint32_t temp = 0U; - uint32_t readRegRemainingTimes; - - if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame)) - { - return kStatus_InvalidArgument; - } - - /* Check that we're not busy.*/ - if (handle->state == (uint8_t)kLPSPI_Busy) - { - return kStatus_LPSPI_Busy; - } - handle->state = (uint8_t)kLPSPI_Busy; - - bool isRxMask = false; - bool isTxMask = false; - - uint32_t whichPcs = (transfer->configFlags & LPSPI_SLAVE_PCS_MASK) >> LPSPI_SLAVE_PCS_SHIFT; - - handle->txData = transfer->txData; - handle->rxData = transfer->rxData; - handle->txRemainingByteCount = transfer->dataSize; - handle->rxRemainingByteCount = transfer->dataSize; - handle->totalByteCount = transfer->dataSize; - - handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U); - handle->readRegRemainingTimes = handle->writeRegRemainingTimes; - - /*The TX and RX FIFO sizes are always the same*/ - handle->fifoSize = LPSPI_GetRxFifoSize(base); - - handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_SlaveByteSwap) != 0U); - - /*Set the RX and TX watermarks to reduce the ISR times.*/ - uint8_t txWatermark; - if (handle->fifoSize > 1U) - { - txWatermark = 1U; - handle->rxWatermark = handle->fifoSize - 2U; - } - else - { - txWatermark = 0U; - handle->rxWatermark = 0U; - } - LPSPI_SetFifoWatermarks(base, txWatermark, handle->rxWatermark); - - /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */ - temp = base->CFGR1; - temp &= LPSPI_CFGR1_PINCFG_MASK; - if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) - { - if (NULL == handle->txData) - { - LPSPI_Enable(base, false); - base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK; - LPSPI_Enable(base, true); - } - /* The 3-wire mode can't send and receive data at the same time. */ - if ((handle->txData != NULL) && (handle->rxData != NULL)) - { - return kStatus_InvalidArgument; - } - } - - /*Flush FIFO , clear status , disable all the inerrupts.*/ - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - /*If there is not rxData , can mask the receive data (receive data is not stored in receive FIFO).*/ - if (handle->rxData == NULL) - { - isRxMask = true; - handle->rxRemainingByteCount = 0U; - } - - /*If there is not txData , can mask the transmit data (no data is loaded from transmit FIFO and output pin - * is tristated). - */ - if (handle->txData == NULL) - { - isTxMask = true; - handle->txRemainingByteCount = 0U; - } - - base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | - LPSPI_TCR_TXMSK_MASK | LPSPI_TCR_PCS_MASK)) | - LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(isRxMask) | LPSPI_TCR_TXMSK(isTxMask) | - LPSPI_TCR_PCS(whichPcs); - - /*Calculate the bytes for write/read the TX/RX register each time*/ - if (bytesPerFrame <= 4U) - { - handle->bytesEachWrite = (uint8_t)bytesPerFrame; - handle->bytesEachRead = (uint8_t)bytesPerFrame; - } - else - { - handle->bytesEachWrite = 4U; - handle->bytesEachRead = 4U; - } - - /* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX , - * and you should also enable the INTMUX interupt in your application. - */ - (void)EnableIRQ(s_lpspiIRQ[LPSPI_GetInstance(base)]); - - /*TCR is also shared the FIFO , so wait for TCR written.*/ -#if SPI_RETRY_TIMES - uint32_t waitTimes = SPI_RETRY_TIMES; - while ((LPSPI_GetTxFifoCount(base) != 0U) && (--waitTimes != 0U)) -#else - while (LPSPI_GetTxFifoCount(base) != 0U) -#endif - { - } -#if SPI_RETRY_TIMES - if (waitTimes == 0U) - { - return kStatus_SPI_Timeout; - } -#endif - - /*Fill up the TX data in FIFO */ - if (handle->txData != NULL) - { - LPSPI_SlaveTransferFillUpTxFifo(base, handle); - } - - /* Since SPI is a synchronous interface, we only need to enable the RX interrupt if there is RX data. - * The IRQ handler will get the status of RX and TX interrupt flags. - */ - if (handle->rxData != NULL) - { - /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there - *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark. - */ - readRegRemainingTimes = handle->readRegRemainingTimes; - if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark) - { - base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | LPSPI_FCR_RXWATER(readRegRemainingTimes - 1U); - } - - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); - } - else - { - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable); - } - - if (handle->rxData != NULL) - { - /* RX FIFO overflow request enable */ - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_ReceiveErrorInterruptEnable); - } - if (handle->txData != NULL) - { - /* TX FIFO underflow request enable */ - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TransmitErrorInterruptEnable); - } - - return kStatus_Success; -} - -static void LPSPI_SlaveTransferFillUpTxFifo(LPSPI_Type *base, lpspi_slave_handle_t *handle) -{ - assert(handle); - - uint32_t wordToSend = 0U; - uint8_t bytesEachWrite = handle->bytesEachWrite; - bool isByteSwap = handle->isByteSwap; - - while (LPSPI_GetTxFifoCount(base) < (handle->fifoSize)) - { - if (handle->txRemainingByteCount < (size_t)bytesEachWrite) - { - handle->bytesEachWrite = (uint8_t)handle->txRemainingByteCount; - bytesEachWrite = handle->bytesEachWrite; - } - - wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap); - handle->txData += bytesEachWrite; - - /*Decrease the remaining TX byte count.*/ - handle->txRemainingByteCount -= (size_t)bytesEachWrite; - - /*Write the word to TX register*/ - LPSPI_WriteData(base, wordToSend); - - if (handle->txRemainingByteCount == 0U) - { - break; - } - } -} - -static void LPSPI_SlaveTransferComplete(LPSPI_Type *base, lpspi_slave_handle_t *handle) -{ - assert(handle); - - status_t status = kStatus_Success; - - /* Disable interrupt requests*/ - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - if (handle->state == (uint8_t)kLPSPI_Error) - { - status = kStatus_LPSPI_Error; - } - else - { - status = kStatus_Success; - } - - handle->state = (uint8_t)kLPSPI_Idle; - - if (handle->callback != NULL) - { - handle->callback(base, handle, status, handle->userData); - } -} - -/*! - * brief Gets the slave transfer remaining bytes. - * - * This function gets the slave transfer remaining bytes. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the non-blocking transaction. - * return status of status_t. - */ -status_t LPSPI_SlaveTransferGetCount(LPSPI_Type *base, lpspi_slave_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state != (uint8_t)kLPSPI_Busy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - size_t remainingByte; - - if (handle->rxData != NULL) - { - remainingByte = handle->rxRemainingByteCount; - } - else - { - remainingByte = handle->txRemainingByteCount; - } - - *count = handle->totalByteCount - remainingByte; - - return kStatus_Success; -} - -/*! - * brief LPSPI slave aborts a transfer which uses an interrupt method. - * - * This function aborts a transfer which uses an interrupt method. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. - */ -void LPSPI_SlaveTransferAbort(LPSPI_Type *base, lpspi_slave_handle_t *handle) -{ - assert(handle); - - /* Disable interrupt requests*/ - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable); - - LPSPI_Reset(base); - - handle->state = (uint8_t)kLPSPI_Idle; - handle->txRemainingByteCount = 0U; - handle->rxRemainingByteCount = 0U; -} - -/*! - * brief LPSPI Slave IRQ handler function. - * - * This function processes the LPSPI transmit and receives an IRQ. - * - * param base LPSPI peripheral address. - * param handle pointer to lpspi_slave_handle_t structure which stores the transfer state. - */ -void LPSPI_SlaveTransferHandleIRQ(LPSPI_Type *base, lpspi_slave_handle_t *handle) -{ - assert(handle); - - uint32_t readData; /* variable to store word read from RX FIFO */ - uint32_t wordToSend; /* variable to store word to write to TX FIFO */ - uint8_t bytesEachRead = handle->bytesEachRead; - uint8_t bytesEachWrite = handle->bytesEachWrite; - bool isByteSwap = handle->isByteSwap; - uint32_t readRegRemainingTimes; - - if (handle->rxData != NULL) - { - if (handle->rxRemainingByteCount > 0U) - { - while (LPSPI_GetRxFifoCount(base) != 0U) - { - /*Read out the data*/ - readData = LPSPI_ReadData(base); - - /*Decrease the read RX register times.*/ - --handle->readRegRemainingTimes; - - if (handle->rxRemainingByteCount < (size_t)bytesEachRead) - { - handle->bytesEachRead = (uint8_t)handle->rxRemainingByteCount; - bytesEachRead = handle->bytesEachRead; - } - - LPSPI_SeparateReadData(handle->rxData, readData, bytesEachRead, isByteSwap); - handle->rxData += bytesEachRead; - - /*Decrease the remaining RX byte count.*/ - handle->rxRemainingByteCount -= (size_t)bytesEachRead; - - if ((handle->txRemainingByteCount > 0U) && (handle->txData != NULL)) - { - if (handle->txRemainingByteCount < (size_t)bytesEachWrite) - { - handle->bytesEachWrite = (uint8_t)handle->txRemainingByteCount; - bytesEachWrite = handle->bytesEachWrite; - } - - wordToSend = LPSPI_CombineWriteData(handle->txData, bytesEachWrite, isByteSwap); - handle->txData += bytesEachWrite; - - /*Decrease the remaining TX byte count.*/ - handle->txRemainingByteCount -= (size_t)bytesEachWrite; - - /*Write the word to TX register*/ - LPSPI_WriteData(base, wordToSend); - } - - if (handle->rxRemainingByteCount == 0U) - { - break; - } - } - } - - /*Set rxWatermark to (readRegRemainingTimes-1) if readRegRemainingTimes less than rxWatermark. Otherwise there - *is not RX interrupt for the last datas because the RX count is not greater than rxWatermark. - */ - readRegRemainingTimes = handle->readRegRemainingTimes; - if (readRegRemainingTimes <= (uint32_t)handle->rxWatermark) - { - base->FCR = (base->FCR & (~LPSPI_FCR_RXWATER_MASK)) | - LPSPI_FCR_RXWATER((readRegRemainingTimes > 1U) ? (readRegRemainingTimes - 1U) : (0U)); - } - } - if ((handle->rxData == NULL) && (handle->txRemainingByteCount != 0U) && (handle->txData != NULL)) - { - LPSPI_SlaveTransferFillUpTxFifo(base, handle); - } - - if ((handle->txRemainingByteCount == 0U) && (handle->rxRemainingByteCount == 0U)) - { - /* If no RX buffer, then transfer is not complete until transfer complete flag sets and the TX FIFO empty*/ - if (handle->rxData == NULL) - { - if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_FrameCompleteFlag) != 0U) && - (LPSPI_GetTxFifoCount(base) == 0U)) - { - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag); - /* Complete the transfer and disable the interrupts */ - LPSPI_SlaveTransferComplete(base, handle); - } - else - { - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_FrameCompleteFlag); - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_FrameCompleteInterruptEnable); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | (uint32_t)kLPSPI_RxInterruptEnable); - } - } - else - { - /* Complete the transfer and disable the interrupts */ - LPSPI_SlaveTransferComplete(base, handle); - } - } - - /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */ - if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_TransmitErrorFlag) != 0U) && - ((base->IER & LPSPI_IER_TEIE_MASK) != 0U)) - { - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_TransmitErrorFlag); - /* Change state to error and clear flag */ - if (handle->txData != NULL) - { - handle->state = (uint8_t)kLPSPI_Error; - } - handle->errorCount++; - } - /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */ - if (((LPSPI_GetStatusFlags(base) & (uint32_t)kLPSPI_ReceiveErrorFlag) != 0U) && - ((base->IER & LPSPI_IER_REIE_MASK) != 0U)) - { - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_ReceiveErrorFlag); - /* Change state to error and clear flag */ - if (handle->txData != NULL) - { - handle->state = (uint8_t)kLPSPI_Error; - } - handle->errorCount++; - } -} - -static uint32_t LPSPI_CombineWriteData(uint8_t *txData, uint8_t bytesEachWrite, bool isByteSwap) -{ - assert(txData != NULL); - - uint32_t wordToSend = 0U; - - switch (bytesEachWrite) - { - case 1: - wordToSend = *txData; - ++txData; - break; - - case 2: - if (!isByteSwap) - { - wordToSend = *txData; - ++txData; - wordToSend |= (unsigned)(*txData) << 8U; - ++txData; - } - else - { - wordToSend = (unsigned)(*txData) << 8U; - ++txData; - wordToSend |= *txData; - ++txData; - } - - break; - - case 3: - if (!isByteSwap) - { - wordToSend = *txData; - ++txData; - wordToSend |= (unsigned)(*txData) << 8U; - ++txData; - wordToSend |= (unsigned)(*txData) << 16U; - ++txData; - } - else - { - wordToSend = (unsigned)(*txData) << 16U; - ++txData; - wordToSend |= (unsigned)(*txData) << 8U; - ++txData; - wordToSend |= *txData; - ++txData; - } - break; - - case 4: - if (!isByteSwap) - { - wordToSend = *txData; - ++txData; - wordToSend |= (unsigned)(*txData) << 8U; - ++txData; - wordToSend |= (unsigned)(*txData) << 16U; - ++txData; - wordToSend |= (unsigned)(*txData) << 24U; - ++txData; - } - else - { - wordToSend = (unsigned)(*txData) << 24U; - ++txData; - wordToSend |= (unsigned)(*txData) << 16U; - ++txData; - wordToSend |= (unsigned)(*txData) << 8U; - ++txData; - wordToSend |= *txData; - ++txData; - } - break; - - default: - assert(false); - break; - } - return wordToSend; -} - -static void LPSPI_SeparateReadData(uint8_t *rxData, uint32_t readData, uint8_t bytesEachRead, bool isByteSwap) -{ - assert(rxData); - - switch (bytesEachRead) - { - case 1: - *rxData = (uint8_t)readData; - ++rxData; - break; - - case 2: - if (!isByteSwap) - { - *rxData = (uint8_t)readData; - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - } - else - { - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)readData; - ++rxData; - } - break; - - case 3: - if (!isByteSwap) - { - *rxData = (uint8_t)readData; - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)(readData >> 16); - ++rxData; - } - else - { - *rxData = (uint8_t)(readData >> 16); - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)readData; - ++rxData; - } - break; - - case 4: - if (!isByteSwap) - { - *rxData = (uint8_t)readData; - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)(readData >> 16); - ++rxData; - *rxData = (uint8_t)(readData >> 24); - ++rxData; - } - else - { - *rxData = (uint8_t)(readData >> 24); - ++rxData; - *rxData = (uint8_t)(readData >> 16); - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)readData; - ++rxData; - } - break; - - default: - assert(false); - break; - } -} - -static void LPSPI_CommonIRQHandler(LPSPI_Type *base, void *param) -{ - if (LPSPI_IsMaster(base)) - { - s_lpspiMasterIsr(base, (lpspi_master_handle_t *)param); - } - else - { - s_lpspiSlaveIsr(base, (lpspi_slave_handle_t *)param); - } - SDK_ISR_EXIT_BARRIER; -} - -#if defined(LPSPI0) -void LPSPI0_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[0]); - LPSPI_CommonIRQHandler(LPSPI0, s_lpspiHandle[0]); -} -#endif - -#if defined(LPSPI1) -void LPSPI1_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[1]); - LPSPI_CommonIRQHandler(LPSPI1, s_lpspiHandle[1]); -} -#endif - -#if defined(LPSPI2) -void LPSPI2_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[2]); - LPSPI_CommonIRQHandler(LPSPI2, s_lpspiHandle[2]); -} -#endif - -#if defined(LPSPI3) -void LPSPI3_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[3]); - LPSPI_CommonIRQHandler(LPSPI3, s_lpspiHandle[3]); -} -#endif - -#if defined(LPSPI4) -void LPSPI4_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[4]); - LPSPI_CommonIRQHandler(LPSPI4, s_lpspiHandle[4]); -} -#endif - -#if defined(LPSPI5) -void LPSPI5_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[5]); - LPSPI_CommonIRQHandler(LPSPI5, s_lpspiHandle[5]); -} -#endif - -#if defined(DMA__LPSPI0) -void DMA_SPI0_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]); - LPSPI_CommonIRQHandler(DMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI0)]); -} -#endif - -#if defined(DMA__LPSPI1) -void DMA_SPI1_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]); - LPSPI_CommonIRQHandler(DMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI1)]); -} -#endif -#if defined(DMA__LPSPI2) -void DMA_SPI2_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]); - LPSPI_CommonIRQHandler(DMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI2)]); -} -#endif - -#if defined(DMA__LPSPI3) -void DMA_SPI3_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]); - LPSPI_CommonIRQHandler(DMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(DMA__LPSPI3)]); -} -#endif - -#if defined(ADMA__LPSPI0) -void ADMA_SPI0_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]); - LPSPI_CommonIRQHandler(ADMA__LPSPI0, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI0)]); -} -#endif - -#if defined(ADMA__LPSPI1) -void ADMA_SPI1_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]); - LPSPI_CommonIRQHandler(ADMA__LPSPI1, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI1)]); -} -#endif -#if defined(ADMA__LPSPI2) -void ADMA_SPI2_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]); - LPSPI_CommonIRQHandler(ADMA__LPSPI2, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI2)]); -} -#endif - -#if defined(ADMA__LPSPI3) -void ADMA_SPI3_INT_DriverIRQHandler(void) -{ - assert(s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]); - LPSPI_CommonIRQHandler(ADMA__LPSPI3, s_lpspiHandle[LPSPI_GetInstance(ADMA__LPSPI3)]); -} -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi_edma.c deleted file mode 100644 index 5a19ca0092..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpspi_edma.c +++ /dev/null @@ -1,1154 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpspi_edma.h" - -/*********************************************************************************************************************** - * Definitions - ***********************************************************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpspi_edma" -#endif - -/*! - * @brief Structure definition for dspi_master_edma_private_handle_t. The structure is private. - */ -typedef struct _lpspi_master_edma_private_handle -{ - LPSPI_Type *base; /*!< LPSPI peripheral base address. */ - lpspi_master_edma_handle_t *handle; /*!< lpspi_master_edma_handle_t handle */ -} lpspi_master_edma_private_handle_t; - -/*! - * @brief Structure definition for dspi_slave_edma_private_handle_t. The structure is private. - */ -typedef struct _lpspi_slave_edma_private_handle -{ - LPSPI_Type *base; /*!< LPSPI peripheral base address. */ - lpspi_slave_edma_handle_t *handle; /*!< lpspi_slave_edma_handle_t handle */ -} lpspi_slave_edma_private_handle_t; - -/*********************************************************************************************************************** - * Prototypes - ***********************************************************************************************************************/ - -/*! - * @brief EDMA_LpspiMasterCallback after the LPSPI master transfer completed by using EDMA. - * This is not a public API. - */ -static void EDMA_LpspiMasterCallback(edma_handle_t *edmaHandle, - void *g_lpspiEdmaPrivateHandle, - bool transferDone, - uint32_t tcds); - -/*! - * @brief EDMA_LpspiSlaveCallback after the LPSPI slave transfer completed by using EDMA. - * This is not a public API. - */ -static void EDMA_LpspiSlaveCallback(edma_handle_t *edmaHandle, - void *g_lpspiEdmaPrivateHandle, - bool transferDone, - uint32_t tcds); - -static void LPSPI_SeparateEdmaReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap); - -/*********************************************************************************************************************** - * Variables - ***********************************************************************************************************************/ -/*! @brief Pointers to lpspi bases for each instance. */ -static LPSPI_Type *const s_lpspiBases[] = LPSPI_BASE_PTRS; - -/*! @brief Pointers to lpspi edma handles for each instance. */ -static lpspi_master_edma_private_handle_t s_lpspiMasterEdmaPrivateHandle[ARRAY_SIZE(s_lpspiBases)]; -static lpspi_slave_edma_private_handle_t s_lpspiSlaveEdmaPrivateHandle[ARRAY_SIZE(s_lpspiBases)]; - -/*********************************************************************************************************************** - * Code - ***********************************************************************************************************************/ -static void LPSPI_SeparateEdmaReadData(uint8_t *rxData, uint32_t readData, uint32_t bytesEachRead, bool isByteSwap) -{ - assert(rxData); - - switch (bytesEachRead) - { - case 1: - if (!isByteSwap) - { - *rxData = (uint8_t)readData; - ++rxData; - } - else - { - *rxData = (uint8_t)(readData >> 24); - ++rxData; - } - break; - - case 2: - if (!isByteSwap) - { - *rxData = (uint8_t)readData; - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - } - else - { - *rxData = (uint8_t)(readData >> 16); - ++rxData; - *rxData = (uint8_t)(readData >> 24); - ++rxData; - } - break; - - case 4: - - *rxData = (uint8_t)readData; - ++rxData; - *rxData = (uint8_t)(readData >> 8); - ++rxData; - *rxData = (uint8_t)(readData >> 16); - ++rxData; - *rxData = (uint8_t)(readData >> 24); - ++rxData; - - break; - - default: - assert(false); - break; - } -} - -/*! - * brief Initializes the LPSPI master eDMA handle. - * - * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs. Usually, for a - * specified LPSPI instance, call this API once to get the initialized handle. - * - * Note that the LPSPI eDMA has a separated (Rx and Rx as two sources) or shared (Rx and Tx are the same source) DMA - * request source. - * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and - * Tx DMAMUX source for edmaIntermediaryToTxRegHandle. - * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle. - * - * param base LPSPI peripheral base address. - * param handle LPSPI handle pointer to lpspi_master_edma_handle_t. - * param callback LPSPI callback. - * param userData callback function parameter. - * param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. - * param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t. - */ -void LPSPI_MasterTransferCreateHandleEDMA(LPSPI_Type *base, - lpspi_master_edma_handle_t *handle, - lpspi_master_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *edmaRxRegToRxDataHandle, - edma_handle_t *edmaTxDataToTxRegHandle) -{ - assert(handle); - assert(edmaRxRegToRxDataHandle); - assert(edmaTxDataToTxRegHandle); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - uint32_t instance = LPSPI_GetInstance(base); - - s_lpspiMasterEdmaPrivateHandle[instance].base = base; - s_lpspiMasterEdmaPrivateHandle[instance].handle = handle; - - handle->callback = callback; - handle->userData = userData; - - handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle; - handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle; -} - -/*! - * brief LPSPI master transfer data using eDMA. - * - * This function transfers data using eDMA. This is a non-blocking function, which returns right away. When all data - * is transferred, the callback function is called. - * - * Note: - * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4. - * For bytesPerFrame greater than 4: - * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4. - * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state. - * param transfer pointer to lpspi_transfer_t structure. - * return status of status_t. - */ -status_t LPSPI_MasterTransferEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, lpspi_transfer_t *transfer) -{ - assert(handle); - assert(transfer); - - uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U; - uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U; - uint32_t temp = 0U; - bool isByteSwap; - bool isPcsContinuous; - - if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame)) - { - return kStatus_InvalidArgument; - } - - /*And since the dma transfer can not support 3 bytes .*/ - if ((bytesPerFrame % 4U) == 3U) - { - return kStatus_InvalidArgument; - } - - /* Check that we're not busy.*/ - if (handle->state == (uint8_t)kLPSPI_Busy) - { - return kStatus_LPSPI_Busy; - } - - handle->state = (uint8_t)kLPSPI_Busy; - - uint32_t instance = LPSPI_GetInstance(base); - uint32_t rxAddr = LPSPI_GetRxRegisterAddress(base); - uint32_t txAddr = LPSPI_GetTxRegisterAddress(base); - - uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT; - - /*Because DMA is fast enough , so set the RX and TX watermarks to 0 .*/ - uint8_t txWatermark = 0; - uint8_t rxWatermark = 0; - - /*Used for byte swap*/ - uint32_t dif = 0; - - uint8_t bytesLastWrite = 0; - - bool isThereExtraTxBytes = false; - - uint8_t dummyData = g_lpspiDummyData[instance]; - - edma_transfer_config_t transferConfigRx; - edma_transfer_config_t transferConfigTx; - - edma_tcd_t *softwareTCD_extraBytes = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[1]) & (~0x1FU)); - edma_tcd_t *softwareTCD_pcsContinuous = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[2]) & (~0x1FU)); - - handle->txData = transfer->txData; - handle->rxData = transfer->rxData; - handle->txRemainingByteCount = transfer->dataSize; - handle->rxRemainingByteCount = transfer->dataSize; - handle->totalByteCount = transfer->dataSize; - - handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U); - handle->readRegRemainingTimes = handle->writeRegRemainingTimes; - - handle->txBuffIfNull = - ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24); - - /*The TX and RX FIFO sizes are always the same*/ - handle->fifoSize = LPSPI_GetRxFifoSize(base); - - handle->isPcsContinuous = (bool)(transfer->configFlags & (uint32_t)kLPSPI_MasterPcsContinuous); - handle->isByteSwap = (bool)(transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap); - isPcsContinuous = handle->isPcsContinuous; - isByteSwap = handle->isByteSwap; - - LPSPI_SetFifoWatermarks(base, txWatermark, rxWatermark); - - /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */ - LPSPI_Enable(base, false); - base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK); - /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */ - temp = base->CFGR1; - temp &= LPSPI_CFGR1_PINCFG_MASK; - if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) - { - if (NULL == handle->txData) - { - base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK; - } - /* The 3-wire mode can't send and receive data at the same time. */ - if ((handle->txData != NULL) && (handle->rxData != NULL)) - { - return kStatus_InvalidArgument; - } - } - - LPSPI_Enable(base, true); - - /*Flush FIFO , clear status , disable all the inerrupts.*/ - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - /* For DMA transfer , we'd better not masked the transmit data and receive data in TCR since the transfer flow is - * hard to controlled by software. - */ - base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_BYSW_MASK | LPSPI_TCR_PCS_MASK)) | - LPSPI_TCR_CONT(isPcsContinuous) | LPSPI_TCR_CONTC(0U) | LPSPI_TCR_BYSW(isByteSwap) | - LPSPI_TCR_PCS(whichPcs); - - isThereExtraTxBytes = false; - handle->isThereExtraRxBytes = false; - - /*Calculate the bytes for write/read the TX/RX register each time*/ - if (bytesPerFrame <= 4U) - { - handle->bytesEachWrite = (uint8_t)bytesPerFrame; - handle->bytesEachRead = (uint8_t)bytesPerFrame; - - handle->bytesLastRead = (uint8_t)bytesPerFrame; - } - else - { - handle->bytesEachWrite = 4U; - handle->bytesEachRead = 4U; - - handle->bytesLastRead = 4U; - - if ((transfer->dataSize % 4U) != 0U) - { - bytesLastWrite = (uint8_t)(transfer->dataSize % 4U); - handle->bytesLastRead = bytesLastWrite; - - isThereExtraTxBytes = true; - - --handle->writeRegRemainingTimes; - - --handle->readRegRemainingTimes; - handle->isThereExtraRxBytes = true; - } - } - - LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_LpspiMasterCallback, - &s_lpspiMasterEdmaPrivateHandle[instance]); - - /*Rx*/ - EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); - - if (handle->rxData != NULL) - { - transferConfigRx.destAddr = (uint32_t) & (handle->rxData[0]); - transferConfigRx.destOffset = 1; - } - else - { - transferConfigRx.destAddr = (uint32_t) & (handle->rxBuffIfNull); - transferConfigRx.destOffset = 0; - } - transferConfigRx.destTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0; - switch (handle->bytesEachRead) - { - case (1U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfigRx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize2Bytes; - transferConfigRx.minorLoopBytes = 2; - if (handle->isByteSwap) - { - dif = 2; - } - break; - - case (4U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize4Bytes; - transferConfigRx.minorLoopBytes = 4; - break; - - default: - transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfigRx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigRx.srcAddr = (uint32_t)rxAddr + dif; - transferConfigRx.srcOffset = 0; - - transferConfigRx.majorLoopCounts = handle->readRegRemainingTimes; - - /* Store the initially configured eDMA minor byte transfer count into the LPSPI handle */ - handle->nbytes = (uint8_t)transferConfigRx.minorLoopBytes; - - EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, - &transferConfigRx, NULL); - EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, - (uint32_t)kEDMA_MajorInterruptEnable); - - /*Tx*/ - EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel); - - if (isThereExtraTxBytes) - { - if (handle->txData != NULL) - { - transferConfigTx.srcAddr = (uint32_t) & (transfer->txData[transfer->dataSize - bytesLastWrite]); - transferConfigTx.srcOffset = 1; - } - else - { - transferConfigTx.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigTx.srcOffset = 0; - } - - transferConfigTx.destOffset = 0; - - transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0; - switch (bytesLastWrite) - { - case (1U): - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigTx.minorLoopBytes = 2; - if (handle->isByteSwap) - { - dif = 2; - } - break; - - default: - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigTx.destAddr = (uint32_t)txAddr + dif; - transferConfigTx.majorLoopCounts = 1; - - EDMA_TcdReset(softwareTCD_extraBytes); - - if (handle->isPcsContinuous) - { - EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, softwareTCD_pcsContinuous); - } - else - { - EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, NULL); - } - } - - if (handle->isPcsContinuous) - { - handle->transmitCommand = base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK); - - transferConfigTx.srcAddr = (uint32_t) & (handle->transmitCommand); - transferConfigTx.srcOffset = 0; - - transferConfigTx.destAddr = (uint32_t) & (base->TCR); - transferConfigTx.destOffset = 0; - - transferConfigTx.srcTransferSize = kEDMA_TransferSize4Bytes; - transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes; - transferConfigTx.minorLoopBytes = 4; - transferConfigTx.majorLoopCounts = 1; - - EDMA_TcdReset(softwareTCD_pcsContinuous); - EDMA_TcdSetTransferConfig(softwareTCD_pcsContinuous, &transferConfigTx, NULL); - } - - if (handle->txData != NULL) - { - transferConfigTx.srcAddr = (uint32_t)(handle->txData); - transferConfigTx.srcOffset = 1; - } - else - { - transferConfigTx.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigTx.srcOffset = 0; - } - - transferConfigTx.destOffset = 0; - - transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0U; - switch (handle->bytesEachRead) - { - case (1U): - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigTx.minorLoopBytes = 2; - - if (handle->isByteSwap) - { - dif = 2; - } - break; - - case (4U): - transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes; - transferConfigTx.minorLoopBytes = 4; - break; - - default: - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigTx.destAddr = (uint32_t)txAddr + dif; - - transferConfigTx.majorLoopCounts = handle->writeRegRemainingTimes; - - if (isThereExtraTxBytes) - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigTx, softwareTCD_extraBytes); - } - else if (handle->isPcsContinuous) - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigTx, softwareTCD_pcsContinuous); - } - else - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigTx, NULL); - } - - EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle); - EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); - - LPSPI_EnableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - return kStatus_Success; -} - -static void EDMA_LpspiMasterCallback(edma_handle_t *edmaHandle, - void *g_lpspiEdmaPrivateHandle, - bool transferDone, - uint32_t tcds) -{ - assert(edmaHandle); - assert(g_lpspiEdmaPrivateHandle); - - uint32_t readData; - - lpspi_master_edma_private_handle_t *lpspiEdmaPrivateHandle; - - lpspiEdmaPrivateHandle = (lpspi_master_edma_private_handle_t *)g_lpspiEdmaPrivateHandle; - - size_t rxRemainingByteCount = lpspiEdmaPrivateHandle->handle->rxRemainingByteCount; - uint8_t bytesLastRead = lpspiEdmaPrivateHandle->handle->bytesLastRead; - bool isByteSwap = lpspiEdmaPrivateHandle->handle->isByteSwap; - - LPSPI_DisableDMA(lpspiEdmaPrivateHandle->base, (uint32_t)kLPSPI_TxDmaEnable | (uint32_t)kLPSPI_RxDmaEnable); - - if (lpspiEdmaPrivateHandle->handle->isThereExtraRxBytes) - { - while (LPSPI_GetRxFifoCount(lpspiEdmaPrivateHandle->base) == 0U) - { - } - readData = LPSPI_ReadData(lpspiEdmaPrivateHandle->base); - - if (lpspiEdmaPrivateHandle->handle->rxData != NULL) - { - LPSPI_SeparateEdmaReadData(&(lpspiEdmaPrivateHandle->handle->rxData[rxRemainingByteCount - bytesLastRead]), - readData, bytesLastRead, isByteSwap); - } - } - - lpspiEdmaPrivateHandle->handle->state = (uint8_t)kLPSPI_Idle; - - if (lpspiEdmaPrivateHandle->handle->callback != NULL) - { - lpspiEdmaPrivateHandle->handle->callback(lpspiEdmaPrivateHandle->base, lpspiEdmaPrivateHandle->handle, - kStatus_Success, lpspiEdmaPrivateHandle->handle->userData); - } -} - -/*! - * brief LPSPI master aborts a transfer which is using eDMA. - * - * This function aborts a transfer which is using eDMA. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state. - */ -void LPSPI_MasterTransferAbortEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle) -{ - assert(handle); - - LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle); - EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle); - - handle->state = (uint8_t)kLPSPI_Idle; -} - -/*! - * brief Gets the master eDMA transfer remaining bytes. - * - * This function gets the master eDMA transfer remaining bytes. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_master_edma_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the EDMA transaction. - * return status of status_t. - */ -status_t LPSPI_MasterTransferGetCountEDMA(LPSPI_Type *base, lpspi_master_edma_handle_t *handle, size_t *count) -{ - assert(handle); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state != (uint8_t)kLPSPI_Busy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - size_t remainingByte; - - remainingByte = - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, - handle->edmaRxRegToRxDataHandle->channel); - - *count = handle->totalByteCount - remainingByte; - - return kStatus_Success; -} - -/*! - * brief Initializes the LPSPI slave eDMA handle. - * - * This function initializes the LPSPI eDMA handle which can be used for other LPSPI transactional APIs. Usually, for a - * specified LPSPI instance, call this API once to get the initialized handle. - * - * Note that LPSPI eDMA has a separated (Rx and Tx as two sources) or shared (Rx and Tx as the same source) DMA request - * source. - * - * (1) For a separated DMA request source, enable and set the Rx DMAMUX source for edmaRxRegToRxDataHandle and - * Tx DMAMUX source for edmaTxDataToTxRegHandle. - * (2) For a shared DMA request source, enable and set the Rx/Rx DMAMUX source for edmaRxRegToRxDataHandle . - * - * param base LPSPI peripheral base address. - * param handle LPSPI handle pointer to lpspi_slave_edma_handle_t. - * param callback LPSPI callback. - * param userData callback function parameter. - * param edmaRxRegToRxDataHandle edmaRxRegToRxDataHandle pointer to edma_handle_t. - * param edmaTxDataToTxRegHandle edmaTxDataToTxRegHandle pointer to edma_handle_t. - */ -void LPSPI_SlaveTransferCreateHandleEDMA(LPSPI_Type *base, - lpspi_slave_edma_handle_t *handle, - lpspi_slave_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *edmaRxRegToRxDataHandle, - edma_handle_t *edmaTxDataToTxRegHandle) -{ - assert(handle); - assert(edmaRxRegToRxDataHandle); - assert(edmaTxDataToTxRegHandle); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - uint32_t instance = LPSPI_GetInstance(base); - - s_lpspiSlaveEdmaPrivateHandle[instance].base = base; - s_lpspiSlaveEdmaPrivateHandle[instance].handle = handle; - - handle->callback = callback; - handle->userData = userData; - - handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle; - handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle; -} - -/*! - * brief LPSPI slave transfers data using eDMA. - * - * This function transfers data using eDMA. This is a non-blocking function, which return right away. When all data - * is transferred, the callback function is called. - * - * Note: - * The transfer data size should be an integer multiple of bytesPerFrame if bytesPerFrame is less than or equal to 4. - * For bytesPerFrame greater than 4: - * The transfer data size should be equal to bytesPerFrame if the bytesPerFrame is not an integer multiple of 4. - * Otherwise, the transfer data size can be an integer multiple of bytesPerFrame. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state. - * param transfer pointer to lpspi_transfer_t structure. - * return status of status_t. - */ -status_t LPSPI_SlaveTransferEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, lpspi_transfer_t *transfer) -{ - assert(handle); - assert(transfer); - - uint32_t bitsPerFrame = ((base->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1U; - uint32_t bytesPerFrame = (bitsPerFrame + 7U) / 8U; - uint32_t temp = 0U; - bool isByteSwap; - - uint8_t dummyData = g_lpspiDummyData[LPSPI_GetInstance(base)]; - - if (!LPSPI_CheckTransferArgument(transfer, bitsPerFrame, bytesPerFrame)) - { - return kStatus_InvalidArgument; - } - - /*And since the dma transfer can not support 3 bytes .*/ - if ((bytesPerFrame % 4U) == 3U) - { - return kStatus_InvalidArgument; - } - - /* Check that we're not busy.*/ - if (handle->state == (uint8_t)kLPSPI_Busy) - { - return kStatus_LPSPI_Busy; - } - - handle->state = (uint8_t)kLPSPI_Busy; - - uint32_t rxAddr = LPSPI_GetRxRegisterAddress(base); - uint32_t txAddr = LPSPI_GetTxRegisterAddress(base); - - edma_tcd_t *softwareTCD_extraBytes = (edma_tcd_t *)((uint32_t)(&handle->lpspiSoftwareTCD[1]) & (~0x1FU)); - - uint32_t whichPcs = (transfer->configFlags & LPSPI_MASTER_PCS_MASK) >> LPSPI_MASTER_PCS_SHIFT; - - /*Because DMA is fast enough , so set the RX and TX watermarks to 0 .*/ - uint8_t txWatermark = 0; - uint8_t rxWatermark = 0; - - /*Used for byte swap*/ - uint32_t dif = 0; - - uint8_t bytesLastWrite = 0; - - uint32_t instance = LPSPI_GetInstance(base); - - edma_transfer_config_t transferConfigRx; - edma_transfer_config_t transferConfigTx; - - bool isThereExtraTxBytes = false; - - handle->txData = transfer->txData; - handle->rxData = transfer->rxData; - handle->txRemainingByteCount = transfer->dataSize; - handle->rxRemainingByteCount = transfer->dataSize; - handle->totalByteCount = transfer->dataSize; - - handle->writeRegRemainingTimes = (transfer->dataSize / bytesPerFrame) * ((bytesPerFrame + 3U) / 4U); - handle->readRegRemainingTimes = handle->writeRegRemainingTimes; - - handle->txBuffIfNull = - ((uint32_t)dummyData) | ((uint32_t)dummyData << 8) | ((uint32_t)dummyData << 16) | ((uint32_t)dummyData << 24); - - /*The TX and RX FIFO sizes are always the same*/ - handle->fifoSize = LPSPI_GetRxFifoSize(base); - - handle->isByteSwap = ((transfer->configFlags & (uint32_t)kLPSPI_MasterByteSwap) != 0U); - isByteSwap = handle->isByteSwap; - - LPSPI_SetFifoWatermarks(base, txWatermark, rxWatermark); - - /*Transfers will stall when transmit FIFO is empty or receive FIFO is full. */ - LPSPI_Enable(base, false); - base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK); - /* Check if using 3-wire mode and the txData is NULL, set the output pin to tristated. */ - temp = base->CFGR1; - temp &= LPSPI_CFGR1_PINCFG_MASK; - if ((temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdiInSdiOut)) || (temp == LPSPI_CFGR1_PINCFG(kLPSPI_SdoInSdoOut))) - { - if (NULL == handle->txData) - { - base->CFGR1 |= LPSPI_CFGR1_OUTCFG_MASK; - } - /* The 3-wire mode can't send and receive data at the same time. */ - if ((handle->txData != NULL) && (handle->rxData != NULL)) - { - return kStatus_InvalidArgument; - } - } - - LPSPI_Enable(base, true); - - /*Flush FIFO , clear status , disable all the inerrupts.*/ - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); - - /* For DMA transfer , we'd better not masked the transmit data and receive data in TCR since the transfer flow is - * hard to controlled by software. - */ - base->TCR = (base->TCR & ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_BYSW_MASK)) | - LPSPI_TCR_CONTC(0U) | LPSPI_TCR_BYSW(isByteSwap) | LPSPI_TCR_PCS(whichPcs); - - isThereExtraTxBytes = false; - handle->isThereExtraRxBytes = false; - - /*Calculate the bytes for write/read the TX/RX register each time*/ - if (bytesPerFrame <= 4U) - { - handle->bytesEachWrite = (uint8_t)bytesPerFrame; - handle->bytesEachRead = (uint8_t)bytesPerFrame; - - handle->bytesLastRead = (uint8_t)bytesPerFrame; - } - else - { - handle->bytesEachWrite = 4U; - handle->bytesEachRead = 4U; - - handle->bytesLastRead = 4U; - - if ((transfer->dataSize % 4U) != 0U) - { - bytesLastWrite = (uint8_t)(transfer->dataSize % 4U); - handle->bytesLastRead = bytesLastWrite; - - isThereExtraTxBytes = true; - --handle->writeRegRemainingTimes; - - handle->isThereExtraRxBytes = true; - --handle->readRegRemainingTimes; - } - } - - LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_LpspiSlaveCallback, - &s_lpspiSlaveEdmaPrivateHandle[instance]); - - /*Rx*/ - if (handle->readRegRemainingTimes > 0U) - { - EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel); - - if (handle->rxData != NULL) - { - transferConfigRx.destAddr = (uint32_t) & (handle->rxData[0]); - transferConfigRx.destOffset = 1; - } - else - { - transferConfigRx.destAddr = (uint32_t) & (handle->rxBuffIfNull); - transferConfigRx.destOffset = 0; - } - transferConfigRx.destTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0; - switch (handle->bytesEachRead) - { - case (1U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfigRx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize2Bytes; - transferConfigRx.minorLoopBytes = 2; - if (handle->isByteSwap) - { - dif = 2; - } - break; - - case (4U): - transferConfigRx.srcTransferSize = kEDMA_TransferSize4Bytes; - transferConfigRx.minorLoopBytes = 4; - break; - - default: - transferConfigRx.srcTransferSize = kEDMA_TransferSize1Bytes; - transferConfigRx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigRx.srcAddr = (uint32_t)rxAddr + dif; - transferConfigRx.srcOffset = 0; - - transferConfigRx.majorLoopCounts = handle->readRegRemainingTimes; - - /* Store the initially configured eDMA minor byte transfer count into the DSPI handle */ - handle->nbytes = (uint8_t)transferConfigRx.minorLoopBytes; - - EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, - &transferConfigRx, NULL); - EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel, - (uint32_t)kEDMA_MajorInterruptEnable); - } - - /*Tx*/ - EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel); - - if (isThereExtraTxBytes) - { - if (handle->txData != NULL) - { - transferConfigTx.srcAddr = (uint32_t) & (transfer->txData[transfer->dataSize - bytesLastWrite]); - transferConfigTx.srcOffset = 1; - } - else - { - transferConfigTx.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigTx.srcOffset = 0; - } - - transferConfigTx.destOffset = 0; - - transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0; - switch (bytesLastWrite) - { - case (1U): - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigTx.minorLoopBytes = 2; - if (handle->isByteSwap) - { - dif = 2; - } - break; - - default: - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigTx.destAddr = (uint32_t)txAddr + dif; - transferConfigTx.majorLoopCounts = 1; - - EDMA_TcdReset(softwareTCD_extraBytes); - - EDMA_TcdSetTransferConfig(softwareTCD_extraBytes, &transferConfigTx, NULL); - } - - if (handle->txData != NULL) - { - transferConfigTx.srcAddr = (uint32_t)(handle->txData); - transferConfigTx.srcOffset = 1; - } - else - { - transferConfigTx.srcAddr = (uint32_t)(&handle->txBuffIfNull); - transferConfigTx.srcOffset = 0; - } - - transferConfigTx.destOffset = 0; - - transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes; - - dif = 0; - switch (handle->bytesEachRead) - { - case (1U): - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - if (handle->isByteSwap) - { - dif = 3; - } - break; - - case (2U): - transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes; - transferConfigTx.minorLoopBytes = 2; - - if (handle->isByteSwap) - { - dif = 2; - } - break; - - case (4U): - transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes; - transferConfigTx.minorLoopBytes = 4; - break; - - default: - transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes; - transferConfigTx.minorLoopBytes = 1; - assert(false); - break; - } - - transferConfigTx.destAddr = (uint32_t)txAddr + dif; - - transferConfigTx.majorLoopCounts = handle->writeRegRemainingTimes; - - if (isThereExtraTxBytes) - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigTx, softwareTCD_extraBytes); - } - else - { - EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel, - &transferConfigTx, NULL); - } - - EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle); - EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle); - - LPSPI_EnableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - return kStatus_Success; -} - -static void EDMA_LpspiSlaveCallback(edma_handle_t *edmaHandle, - void *g_lpspiEdmaPrivateHandle, - bool transferDone, - uint32_t tcds) -{ - assert(edmaHandle); - assert(g_lpspiEdmaPrivateHandle); - - uint32_t readData; - - lpspi_slave_edma_private_handle_t *lpspiEdmaPrivateHandle; - - lpspiEdmaPrivateHandle = (lpspi_slave_edma_private_handle_t *)g_lpspiEdmaPrivateHandle; - - size_t rxRemainingByteCount = lpspiEdmaPrivateHandle->handle->rxRemainingByteCount; - uint8_t bytesLastRead = lpspiEdmaPrivateHandle->handle->bytesLastRead; - bool isByteSwap = lpspiEdmaPrivateHandle->handle->isByteSwap; - - LPSPI_DisableDMA(lpspiEdmaPrivateHandle->base, (uint32_t)kLPSPI_TxDmaEnable | (uint32_t)kLPSPI_RxDmaEnable); - - if (lpspiEdmaPrivateHandle->handle->isThereExtraRxBytes) - { - while (LPSPI_GetRxFifoCount(lpspiEdmaPrivateHandle->base) == 0U) - { - } - readData = LPSPI_ReadData(lpspiEdmaPrivateHandle->base); - - if (lpspiEdmaPrivateHandle->handle->rxData != NULL) - { - LPSPI_SeparateEdmaReadData(&(lpspiEdmaPrivateHandle->handle->rxData[rxRemainingByteCount - bytesLastRead]), - readData, bytesLastRead, isByteSwap); - } - } - - lpspiEdmaPrivateHandle->handle->state = (uint8_t)kLPSPI_Idle; - - if (lpspiEdmaPrivateHandle->handle->callback != NULL) - { - lpspiEdmaPrivateHandle->handle->callback(lpspiEdmaPrivateHandle->base, lpspiEdmaPrivateHandle->handle, - kStatus_Success, lpspiEdmaPrivateHandle->handle->userData); - } -} - -/*! - * brief LPSPI slave aborts a transfer which is using eDMA. - * - * This function aborts a transfer which is using eDMA. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state. - */ -void LPSPI_SlaveTransferAbortEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle) -{ - assert(handle); - - LPSPI_DisableDMA(base, (uint32_t)kLPSPI_RxDmaEnable | (uint32_t)kLPSPI_TxDmaEnable); - - EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle); - EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle); - - handle->state = (uint8_t)kLPSPI_Idle; -} - -/*! - * brief Gets the slave eDMA transfer remaining bytes. - * - * This function gets the slave eDMA transfer remaining bytes. - * - * param base LPSPI peripheral base address. - * param handle pointer to lpspi_slave_edma_handle_t structure which stores the transfer state. - * param count Number of bytes transferred so far by the eDMA transaction. - * return status of status_t. - */ -status_t LPSPI_SlaveTransferGetCountEDMA(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, size_t *count) -{ - assert(handle); - - if (NULL == count) - { - return kStatus_InvalidArgument; - } - - /* Catch when there is not an active transfer. */ - if (handle->state != (uint8_t)kLPSPI_Busy) - { - *count = 0; - return kStatus_NoTransferInProgress; - } - - size_t remainingByte; - - remainingByte = - (uint32_t)handle->nbytes * EDMA_GetRemainingMajorLoopCount(handle->edmaRxRegToRxDataHandle->base, - handle->edmaRxRegToRxDataHandle->channel); - - *count = handle->totalByteCount - remainingByte; - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart.c deleted file mode 100644 index 2f02aabe16..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart.c +++ /dev/null @@ -1,2068 +0,0 @@ -/* - * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpuart.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpuart" -#endif - -/* LPUART transfer state. */ -enum -{ - kLPUART_TxIdle, /*!< TX idle. */ - kLPUART_TxBusy, /*!< TX busy. */ - kLPUART_RxIdle, /*!< RX idle. */ - kLPUART_RxBusy /*!< RX busy. */ -}; - -/* Typedef for interrupt handler. */ -typedef void (*lpuart_isr_t)(LPUART_Type *base, lpuart_handle_t *handle); - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Check whether the RX ring buffer is full. - * - * @userData handle LPUART handle pointer. - * @retval true RX ring buffer is full. - * @retval false RX ring buffer is not full. - */ -static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle); - -/*! - * @brief Write to TX register using non-blocking method. - * - * This function writes data to the TX register directly, upper layer must make - * sure the TX register is empty or TX FIFO has empty room before calling this function. - * - * @note This function does not check whether all the data has been sent out to bus, - * so before disable TX, check kLPUART_TransmissionCompleteFlag to ensure the TX is - * finished. - * - * @param base LPUART peripheral base address. - * @param data Start address of the data to write. - * @param length Size of the buffer to be sent. - */ -static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length); - -/*! - * @brief Read RX register using non-blocking method. - * - * This function reads data from the TX register directly, upper layer must make - * sure the RX register is full or TX FIFO has data before calling this function. - * - * @param base LPUART peripheral base address. - * @param data Start address of the buffer to store the received data. - * @param length Size of the buffer. - */ -static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* Array of LPUART peripheral base address. */ -static LPUART_Type *const s_lpuartBases[] = LPUART_BASE_PTRS; -/* Array of LPUART handle. */ -static lpuart_handle_t *s_lpuartHandle[ARRAY_SIZE(s_lpuartBases)]; -/* Array of LPUART IRQ number. */ -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -static const IRQn_Type s_lpuartRxIRQ[] = LPUART_RX_IRQS; -static const IRQn_Type s_lpuartTxIRQ[] = LPUART_TX_IRQS; -#else -static const IRQn_Type s_lpuartIRQ[] = LPUART_RX_TX_IRQS; -#endif -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of LPUART clock name. */ -static const clock_ip_name_t s_lpuartClock[] = LPUART_CLOCKS; - -#if defined(LPUART_PERIPH_CLOCKS) -/* Array of LPUART functional clock name. */ -static const clock_ip_name_t s_lpuartPeriphClocks[] = LPUART_PERIPH_CLOCKS; -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/* LPUART ISR for transactional APIs. */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -static lpuart_isr_t s_lpuartIsr = (lpuart_isr_t)DefaultISR; -#else -static lpuart_isr_t s_lpuartIsr; -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -/*! - * brief Get the LPUART instance from peripheral base address. - * - * param base LPUART peripheral base address. - * return LPUART instance. - */ -uint32_t LPUART_GetInstance(LPUART_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0U; instance < ARRAY_SIZE(s_lpuartBases); instance++) - { - if (s_lpuartBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_lpuartBases)); - - return instance; -} - -/*! - * brief Get the length of received data in RX ring buffer. - * - * userData handle LPUART handle pointer. - * return Length of received data in RX ring buffer. - */ -size_t LPUART_TransferGetRxRingBufferLength(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - size_t size; - size_t tmpRxRingBufferSize = handle->rxRingBufferSize; - uint16_t tmpRxRingBufferTail = handle->rxRingBufferTail; - uint16_t tmpRxRingBufferHead = handle->rxRingBufferHead; - - if (tmpRxRingBufferTail > tmpRxRingBufferHead) - { - size = ((size_t)tmpRxRingBufferHead + tmpRxRingBufferSize - (size_t)tmpRxRingBufferTail); - } - else - { - size = ((size_t)tmpRxRingBufferHead - (size_t)tmpRxRingBufferTail); - } - - return size; -} - -static bool LPUART_TransferIsRxRingBufferFull(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - bool full; - - if (LPUART_TransferGetRxRingBufferLength(base, handle) == (handle->rxRingBufferSize - 1U)) - { - full = true; - } - else - { - full = false; - } - return full; -} - -static void LPUART_WriteNonBlocking(LPUART_Type *base, const uint8_t *data, size_t length) -{ - assert(NULL != data); - - size_t i; - - /* The Non Blocking write data API assume user have ensured there is enough space in - peripheral to write. */ - for (i = 0; i < length; i++) - { - base->DATA = data[i]; - } -} - -static void LPUART_ReadNonBlocking(LPUART_Type *base, uint8_t *data, size_t length) -{ - assert(NULL != data); - - size_t i; -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) || - (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U))); -#endif - - /* The Non Blocking read data API assume user have ensured there is enough space in - peripheral to write. */ - for (i = 0; i < length; i++) - { -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (isSevenDataBits) - { - data[i] = (uint8_t)(base->DATA & 0x7FU); - } - else - { - data[i] = (uint8_t)base->DATA; - } -#else - data[i] = (uint8_t)(base->DATA); -#endif - } -} - -/*! - * brief Initializes an LPUART instance with the user configuration structure and the peripheral clock. - * - * This function configures the LPUART module with user-defined settings. Call the LPUART_GetDefaultConfig() function - * to configure the configuration structure and get the default configuration. - * The example below shows how to use this API to configure the LPUART. - * code - * lpuart_config_t lpuartConfig; - * lpuartConfig.baudRate_Bps = 115200U; - * lpuartConfig.parityMode = kLPUART_ParityDisabled; - * lpuartConfig.dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig.isMsb = false; - * lpuartConfig.stopBitCount = kLPUART_OneStopBit; - * lpuartConfig.txFifoWatermark = 0; - * lpuartConfig.rxFifoWatermark = 1; - * LPUART_Init(LPUART1, &lpuartConfig, 20000000U); - * endcode - * - * param base LPUART peripheral base address. - * param config Pointer to a user-defined configuration structure. - * param srcClock_Hz LPUART clock source frequency in HZ. - * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not support in current clock source. - * retval kStatus_Success LPUART initialize succeed - */ -#ifndef __rtems__ -status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz) -#else /* __rtems__ */ -status_t LPUART_Init(LPUART_Type *base, const lpuart_config_t *config, uint32_t srcClock_Hz, bool do_reset) -#endif /* __rtems__ */ -{ - assert(NULL != config); - assert(0U < config->baudRate_Bps); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - assert((uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->txFifoWatermark); - assert((uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) >= config->rxFifoWatermark); -#endif - - status_t status = kStatus_Success; - uint32_t temp; - uint16_t sbr, sbrTemp; - uint8_t osr, osrTemp; - uint32_t tempDiff, calculatedBaud, baudDiff; - - /* This LPUART instantiation uses a slightly different baud rate calculation - * The idea is to use the best OSR (over-sampling rate) possible - * Note, OSR is typically hard-set to 16 in other LPUART instantiations - * loop to find the best OSR value possible, one that generates minimum baudDiff - * iterate through the rest of the supported values of OSR */ - - baudDiff = config->baudRate_Bps; - osr = 0U; - sbr = 0U; - for (osrTemp = 4U; osrTemp <= 32U; osrTemp++) - { - /* calculate the temporary sbr value */ - sbrTemp = (uint16_t)((srcClock_Hz * 10U / (config->baudRate_Bps * (uint32_t)osrTemp) + 5U) / 10U); - /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ - if (sbrTemp == 0U) - { - sbrTemp = 1U; - } - /* Calculate the baud rate based on the temporary OSR and SBR values */ - calculatedBaud = (srcClock_Hz / ((uint32_t)osrTemp * (uint32_t)sbrTemp)); - tempDiff = calculatedBaud > config->baudRate_Bps ? (calculatedBaud - config->baudRate_Bps) : - (config->baudRate_Bps - calculatedBaud); - - if (tempDiff <= baudDiff) - { - baudDiff = tempDiff; - osr = osrTemp; /* update and store the best OSR value calculated */ - sbr = sbrTemp; /* update store the best SBR value calculated */ - } - } - -#ifndef __rtems__ - /* Check to see if actual baud rate is within 3% of desired baud rate - * based on the best calculate OSR value */ - if (baudDiff > ((config->baudRate_Bps / 100U) * 3U)) - { - /* Unacceptable baud rate difference of more than 3%*/ - status = kStatus_LPUART_BaudrateNotSupport; - } - else -#else /* __rtems__ */ - /* - * Better to have any baudrate then none. With this change, the function can - * not fail any more. - */ -#endif /* __rtems__ */ - { -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - - uint32_t instance = LPUART_GetInstance(base); - - /* Enable lpuart clock */ - CLOCK_EnableClock(s_lpuartClock[instance]); -#if defined(LPUART_PERIPH_CLOCKS) - CLOCK_EnableClock(s_lpuartPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_LPUART_HAS_GLOBAL) && FSL_FEATURE_LPUART_HAS_GLOBAL - /*Reset all internal logic and registers, except the Global Register */ -#ifndef __rtems__ - LPUART_SoftwareReset(base); -#else /* __rtems__ */ - if (do_reset) { - LPUART_SoftwareReset(base); - } -#endif /* __rtems__ */ -#else - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); -#endif - - temp = base->BAUD; - - /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3U) && (osr < 8U)) - { - temp |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* program the osr value (bit value is one less than actual value) */ - temp &= ~LPUART_BAUD_OSR_MASK; - temp |= LPUART_BAUD_OSR((uint32_t)osr - 1UL); - - /* write the sbr value to the BAUD registers */ - temp &= ~LPUART_BAUD_SBR_MASK; - base->BAUD = temp | LPUART_BAUD_SBR(sbr); - - /* Set bit count and parity mode. */ - base->BAUD &= ~LPUART_BAUD_M10_MASK; - - temp = base->CTRL & ~(LPUART_CTRL_PE_MASK | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK | - LPUART_CTRL_IDLECFG_MASK); - - temp |= (uint8_t)config->parityMode | LPUART_CTRL_IDLECFG(config->rxIdleConfig) | - LPUART_CTRL_ILT(config->rxIdleType); - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (kLPUART_SevenDataBits == config->dataBitsCount) - { - if (kLPUART_ParityDisabled != config->parityMode) - { - temp &= ~LPUART_CTRL_M7_MASK; /* Seven data bits and one parity bit */ - } - else - { - temp |= LPUART_CTRL_M7_MASK; - } - } - else -#endif - { - if (kLPUART_ParityDisabled != config->parityMode) - { - temp |= LPUART_CTRL_M_MASK; /* Eight data bits and one parity bit */ - } - } - - base->CTRL = temp; - -#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT - /* set stop bit per char */ - temp = base->BAUD & ~LPUART_BAUD_SBNS_MASK; - base->BAUD = temp | LPUART_BAUD_SBNS((uint8_t)config->stopBitCount); -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - /* Set tx/rx WATER watermark - Note: - Take care of the RX FIFO, RX interrupt request only assert when received bytes - equal or more than RX water mark, there is potential issue if RX water - mark larger than 1. - For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and - 5 bytes are received. the last byte will be saved in FIFO but not trigger - RX interrupt because the water mark is 2. - */ - base->WATER = (((uint32_t)(config->rxFifoWatermark) << 16U) | config->txFifoWatermark); - - /* Enable tx/rx FIFO */ - base->FIFO |= (LPUART_FIFO_TXFE_MASK | LPUART_FIFO_RXFE_MASK); - - /* Flush FIFO */ - base->FIFO |= (LPUART_FIFO_TXFLUSH_MASK | LPUART_FIFO_RXFLUSH_MASK); -#endif - - /* Clear all status flags */ - temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); - -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_LBKDIF_MASK; -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT - /* Set the CTS configuration/TX CTS source. */ - base->MODIR |= LPUART_MODIR_TXCTSC(config->txCtsConfig) | LPUART_MODIR_TXCTSSRC(config->txCtsSource); - if (true == config->enableRxRTS) - { - /* Enable the receiver RTS(request-to-send) function. */ - base->MODIR |= LPUART_MODIR_RXRTSE_MASK; - } - if (true == config->enableTxCTS) - { - /* Enable the CTS(clear-to-send) function. */ - base->MODIR |= LPUART_MODIR_TXCTSE_MASK; - } -#endif - - /* Set data bits order. */ - if (true == config->isMsb) - { - temp |= LPUART_STAT_MSBF_MASK; - } - else - { - temp &= ~LPUART_STAT_MSBF_MASK; - } - - base->STAT |= temp; - - /* Enable TX/RX base on configure structure. */ - temp = base->CTRL; - if (true == config->enableTx) - { - temp |= LPUART_CTRL_TE_MASK; - } - - if (true == config->enableRx) - { - temp |= LPUART_CTRL_RE_MASK; - } - - base->CTRL = temp; - } - - return status; -} -/*! - * brief Deinitializes a LPUART instance. - * - * This function waits for transmit to complete, disables TX and RX, and disables the LPUART clock. - * - * param base LPUART peripheral base address. - */ -void LPUART_Deinit(LPUART_Type *base) -{ - uint32_t temp; - -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - /* Wait tx FIFO send out*/ - while (0U != ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXWATER_SHIFT)) - { - } -#endif - /* Wait last char shift out */ - while (0U == (base->STAT & LPUART_STAT_TC_MASK)) - { - } - - /* Clear all status flags */ - temp = (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); - -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp |= LPUART_STAT_LBKDIF_MASK; -#endif - -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp |= (LPUART_STAT_MA1F_MASK | LPUART_STAT_MA2F_MASK); -#endif - - base->STAT |= temp; - - /* Disable the module. */ - base->CTRL = 0U; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = LPUART_GetInstance(base); - - /* Disable lpuart clock */ - CLOCK_DisableClock(s_lpuartClock[instance]); - -#if defined(LPUART_PERIPH_CLOCKS) - CLOCK_DisableClock(s_lpuartPeriphClocks[instance]); -#endif - -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets the default configuration structure. - * - * This function initializes the LPUART configuration structure to a default value. The default - * values are: - * lpuartConfig->baudRate_Bps = 115200U; - * lpuartConfig->parityMode = kLPUART_ParityDisabled; - * lpuartConfig->dataBitsCount = kLPUART_EightDataBits; - * lpuartConfig->isMsb = false; - * lpuartConfig->stopBitCount = kLPUART_OneStopBit; - * lpuartConfig->txFifoWatermark = 0; - * lpuartConfig->rxFifoWatermark = 1; - * lpuartConfig->rxIdleType = kLPUART_IdleTypeStartBit; - * lpuartConfig->rxIdleConfig = kLPUART_IdleCharacter1; - * lpuartConfig->enableTx = false; - * lpuartConfig->enableRx = false; - * - * param config Pointer to a configuration structure. - */ -void LPUART_GetDefaultConfig(lpuart_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->baudRate_Bps = 115200U; - config->parityMode = kLPUART_ParityDisabled; - config->dataBitsCount = kLPUART_EightDataBits; - config->isMsb = false; -#if defined(FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT) && FSL_FEATURE_LPUART_HAS_STOP_BIT_CONFIG_SUPPORT - config->stopBitCount = kLPUART_OneStopBit; -#endif -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - config->txFifoWatermark = 0U; - config->rxFifoWatermark = 0U; -#endif -#if defined(FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT) && FSL_FEATURE_LPUART_HAS_MODEM_SUPPORT - config->enableRxRTS = false; - config->enableTxCTS = false; - config->txCtsConfig = kLPUART_CtsSampleAtStart; - config->txCtsSource = kLPUART_CtsSourcePin; -#endif - config->rxIdleType = kLPUART_IdleTypeStartBit; - config->rxIdleConfig = kLPUART_IdleCharacter1; - config->enableTx = false; - config->enableRx = false; -} - -/*! - * brief Sets the LPUART instance baudrate. - * - * This function configures the LPUART module baudrate. This function is used to update - * the LPUART module baudrate after the LPUART module is initialized by the LPUART_Init. - * code - * LPUART_SetBaudRate(LPUART1, 115200U, 20000000U); - * endcode - * - * param base LPUART peripheral base address. - * param baudRate_Bps LPUART baudrate to be set. - * param srcClock_Hz LPUART clock source frequency in HZ. - * retval kStatus_LPUART_BaudrateNotSupport Baudrate is not supported in the current clock source. - * retval kStatus_Success Set baudrate succeeded. - */ -status_t LPUART_SetBaudRate(LPUART_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) -{ - assert(0U < baudRate_Bps); - - status_t status = kStatus_Success; - uint32_t temp, oldCtrl; - uint16_t sbr, sbrTemp; - uint8_t osr, osrTemp; - uint32_t tempDiff, calculatedBaud, baudDiff; - - /* This LPUART instantiation uses a slightly different baud rate calculation - * The idea is to use the best OSR (over-sampling rate) possible - * Note, OSR is typically hard-set to 16 in other LPUART instantiations - * loop to find the best OSR value possible, one that generates minimum baudDiff - * iterate through the rest of the supported values of OSR */ - - baudDiff = baudRate_Bps; - osr = 0U; - sbr = 0U; - for (osrTemp = 4U; osrTemp <= 32U; osrTemp++) - { - /* calculate the temporary sbr value */ - sbrTemp = (uint16_t)((srcClock_Hz * 10U / (baudRate_Bps * (uint32_t)osrTemp) + 5U) / 10U); - /*set sbrTemp to 1 if the sourceClockInHz can not satisfy the desired baud rate*/ - if (sbrTemp == 0U) - { - sbrTemp = 1U; - } - /* Calculate the baud rate based on the temporary OSR and SBR values */ - calculatedBaud = srcClock_Hz / ((uint32_t)osrTemp * (uint32_t)sbrTemp); - - tempDiff = calculatedBaud > baudRate_Bps ? (calculatedBaud - baudRate_Bps) : (baudRate_Bps - calculatedBaud); - - if (tempDiff <= baudDiff) - { - baudDiff = tempDiff; - osr = osrTemp; /* update and store the best OSR value calculated */ - sbr = sbrTemp; /* update store the best SBR value calculated */ - } - } - - /* Check to see if actual baud rate is within 3% of desired baud rate - * based on the best calculate OSR value */ - if (baudDiff < (uint32_t)((baudRate_Bps / 100U) * 3U)) - { - /* Store CTRL before disable Tx and Rx */ - oldCtrl = base->CTRL; - - /* Disable LPUART TX RX before setting. */ - base->CTRL &= ~(LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK); - - temp = base->BAUD; - - /* Acceptable baud rate, check if OSR is between 4x and 7x oversampling. - * If so, then "BOTHEDGE" sampling must be turned on */ - if ((osr > 3U) && (osr < 8U)) - { - temp |= LPUART_BAUD_BOTHEDGE_MASK; - } - - /* program the osr value (bit value is one less than actual value) */ - temp &= ~LPUART_BAUD_OSR_MASK; - temp |= LPUART_BAUD_OSR((uint32_t)osr - 1UL); - - /* write the sbr value to the BAUD registers */ - temp &= ~LPUART_BAUD_SBR_MASK; - base->BAUD = temp | LPUART_BAUD_SBR(sbr); - - /* Restore CTRL. */ - base->CTRL = oldCtrl; - } - else - { - /* Unacceptable baud rate difference of more than 3%*/ - status = kStatus_LPUART_BaudrateNotSupport; - } - - return status; -} - -/*! - * brief Enables LPUART interrupts according to a provided mask. - * - * This function enables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See the ref _lpuart_interrupt_enable. - * This examples shows how to enable TX empty interrupt and RX full interrupt: - * code - * LPUART_EnableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * endcode - * - * param base LPUART peripheral base address. - * param mask The interrupts to enable. Logical OR of ref _uart_interrupt_enable. - */ -void LPUART_EnableInterrupts(LPUART_Type *base, uint32_t mask) -{ - base->BAUD |= ((mask << 8U) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) | - ((mask << 8U) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); -#endif - mask &= 0xFFFFFF00U; - base->CTRL |= mask; -} - -/*! - * brief Disables LPUART interrupts according to a provided mask. - * - * This function disables the LPUART interrupts according to a provided mask. The mask - * is a logical OR of enumeration members. See ref _lpuart_interrupt_enable. - * This example shows how to disable the TX empty interrupt and RX full interrupt: - * code - * LPUART_DisableInterrupts(LPUART1,kLPUART_TxDataRegEmptyInterruptEnable | kLPUART_RxDataRegFullInterruptEnable); - * endcode - * - * param base LPUART peripheral base address. - * param mask The interrupts to disable. Logical OR of ref _lpuart_interrupt_enable. - */ -void LPUART_DisableInterrupts(LPUART_Type *base, uint32_t mask) -{ - base->BAUD &= ~((mask << 8U) & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)); -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - base->FIFO = (base->FIFO & ~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) & - ~((mask << 8U) & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)); -#endif - mask &= 0xFFFFFF00U; - base->CTRL &= ~mask; -} - -/*! - * brief Gets enabled LPUART interrupts. - * - * This function gets the enabled LPUART interrupts. The enabled interrupts are returned - * as the logical OR value of the enumerators ref _lpuart_interrupt_enable. To check - * a specific interrupt enable status, compare the return value with enumerators - * in ref _lpuart_interrupt_enable. - * For example, to check whether the TX empty interrupt is enabled: - * code - * uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(LPUART1); - * - * if (kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts) - * { - * ... - * } - * endcode - * - * param base LPUART peripheral base address. - * return LPUART interrupt flags which are logical OR of the enumerators in ref _lpuart_interrupt_enable. - */ -uint32_t LPUART_GetEnabledInterrupts(LPUART_Type *base) -{ - uint32_t temp; - temp = (base->BAUD & (LPUART_BAUD_LBKDIE_MASK | LPUART_BAUD_RXEDGIE_MASK)) >> 8U; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp |= (base->FIFO & (LPUART_FIFO_TXOFE_MASK | LPUART_FIFO_RXUFE_MASK)) >> 8U; -#endif - temp |= (uint32_t)(base->CTRL & 0xFF0C000u); - - return temp; -} - -/*! - * brief Gets LPUART status flags. - * - * This function gets all LPUART status flags. The flags are returned as the logical - * OR value of the enumerators ref _lpuart_flags. To check for a specific status, - * compare the return value with enumerators in the ref _lpuart_flags. - * For example, to check whether the TX is empty: - * code - * if (kLPUART_TxDataRegEmptyFlag & LPUART_GetStatusFlags(LPUART1)) - * { - * ... - * } - * endcode - * - * param base LPUART peripheral base address. - * return LPUART status flags which are ORed by the enumerators in the _lpuart_flags. - */ -uint32_t LPUART_GetStatusFlags(LPUART_Type *base) -{ - uint32_t temp; - temp = base->STAT; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp |= (base->FIFO & - (LPUART_FIFO_TXEMPT_MASK | LPUART_FIFO_RXEMPT_MASK | LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)) >> - 16U; -#endif - return temp; -} - -/*! - * brief Clears status flags with a provided mask. - * - * This function clears LPUART status flags with a provided mask. Automatically cleared flags - * can't be cleared by this function. - * Flags that can only cleared or set by hardware are: - * kLPUART_TxDataRegEmptyFlag, kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, - * kLPUART_RxActiveFlag, kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, - * kLPUART_TxFifoEmptyFlag,kLPUART_RxFifoEmptyFlag - * Note: This API should be called when the Tx/Rx is idle, otherwise it takes no effects. - * - * param base LPUART peripheral base address. - * param mask the status flags to be cleared. The user can use the enumerators in the - * _lpuart_status_flag_t to do the OR operation and get the mask. - * return 0 succeed, others failed. - * retval kStatus_LPUART_FlagCannotClearManually The flag can't be cleared by this function but - * it is cleared automatically by hardware. - * retval kStatus_Success Status in the mask are cleared. - */ -status_t LPUART_ClearStatusFlags(LPUART_Type *base, uint32_t mask) -{ - uint32_t temp; - status_t status; -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - temp = (uint32_t)base->FIFO; - temp &= (uint32_t)(~(LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK)); - temp |= (mask << 16U) & (LPUART_FIFO_TXOF_MASK | LPUART_FIFO_RXUF_MASK); - base->FIFO = temp; -#endif - temp = (uint32_t)base->STAT; -#if defined(FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT) && FSL_FEATURE_LPUART_HAS_LIN_BREAK_DETECT - temp &= (uint32_t)(~(LPUART_STAT_LBKDIF_MASK)); - temp |= mask & LPUART_STAT_LBKDIF_MASK; -#endif - temp &= (uint32_t)(~(LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK)); - temp |= mask & (LPUART_STAT_RXEDGIF_MASK | LPUART_STAT_IDLE_MASK | LPUART_STAT_OR_MASK | LPUART_STAT_NF_MASK | - LPUART_STAT_FE_MASK | LPUART_STAT_PF_MASK); -#if defined(FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING) && FSL_FEATURE_LPUART_HAS_ADDRESS_MATCHING - temp &= (uint32_t)(~(LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK)); - temp |= mask & (LPUART_STAT_MA2F_MASK | LPUART_STAT_MA1F_MASK); -#endif - base->STAT = temp; - /* If some flags still pending. */ - if (0U != (mask & LPUART_GetStatusFlags(base))) - { - /* Some flags can only clear or set by the hardware itself, these flags are: kLPUART_TxDataRegEmptyFlag, - kLPUART_TransmissionCompleteFlag, kLPUART_RxDataRegFullFlag, kLPUART_RxActiveFlag, - kLPUART_NoiseErrorInRxDataRegFlag, kLPUART_ParityErrorInRxDataRegFlag, - kLPUART_TxFifoEmptyFlag, kLPUART_RxFifoEmptyFlag. */ - status = kStatus_LPUART_FlagCannotClearManually; /* flags can not clear manually */ - } - else - { - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Writes to the transmitter register using a blocking method. - * - * This function polls the transmitter register, first waits for the register to be empty or TX FIFO to have room, - * and writes data to the transmitter buffer, then waits for the data to be sent out to bus. - * - * param base LPUART peripheral base address. - * param data Start address of the data to write. - * param length Size of the data to write. - * retval kStatus_LPUART_Timeout Transmission timed out and was aborted. - * retval kStatus_Success Successfully wrote all data. - */ -status_t LPUART_WriteBlocking(LPUART_Type *base, const uint8_t *data, size_t length) -{ - assert(NULL != data); - - const uint8_t *dataAddress = data; - size_t transferSize = length; - -#if UART_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != transferSize) - { -#if UART_RETRY_TIMES - waitTimes = UART_RETRY_TIMES; - while ((0U == (base->STAT & LPUART_STAT_TDRE_MASK)) && (0U != --waitTimes)) -#else - while (0U == (base->STAT & LPUART_STAT_TDRE_MASK)) -#endif - { - } -#if UART_RETRY_TIMES - if (0U == waitTimes) - { - return kStatus_LPUART_Timeout; - } -#endif - base->DATA = *(dataAddress); - dataAddress++; - transferSize--; - } - /* Ensure all the data in the transmit buffer are sent out to bus. */ -#if UART_RETRY_TIMES - waitTimes = UART_RETRY_TIMES; - while ((0U == (base->STAT & LPUART_STAT_TC_MASK)) && (0U != --waitTimes)) -#else - while (0U == (base->STAT & LPUART_STAT_TC_MASK)) -#endif - { - } -#if UART_RETRY_TIMES - if (0U == waitTimes) - { - return kStatus_LPUART_Timeout; - } -#endif - return kStatus_Success; -} - -/*! - * brief Reads the receiver data register using a blocking method. - * - * This function polls the receiver register, waits for the receiver register full or receiver FIFO - * has data, and reads data from the TX register. - * - * param base LPUART peripheral base address. - * param data Start address of the buffer to store the received data. - * param length Size of the buffer. - * retval kStatus_LPUART_RxHardwareOverrun Receiver overrun happened while receiving data. - * retval kStatus_LPUART_NoiseError Noise error happened while receiving data. - * retval kStatus_LPUART_FramingError Framing error happened while receiving data. - * retval kStatus_LPUART_ParityError Parity error happened while receiving data. - * retval kStatus_LPUART_Timeout Transmission timed out and was aborted. - * retval kStatus_Success Successfully received all data. - */ -status_t LPUART_ReadBlocking(LPUART_Type *base, uint8_t *data, size_t length) -{ - assert(NULL != data); - - status_t status = kStatus_Success; - uint32_t statusFlag; - uint8_t *dataAddress = data; - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) || - (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U))); -#endif - -#if UART_RETRY_TIMES - uint32_t waitTimes; -#endif - - while (0U != (length--)) - { -#if UART_RETRY_TIMES - waitTimes = UART_RETRY_TIMES; -#endif -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - while (0U == ((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)) -#else - while (0U == (base->STAT & LPUART_STAT_RDRF_MASK)) -#endif - { -#if UART_RETRY_TIMES - if (0U == --waitTimes) - { - status = kStatus_LPUART_Timeout; - break; - } -#endif - statusFlag = LPUART_GetStatusFlags(base); - - if (0U != (statusFlag & (uint32_t)kLPUART_RxOverrunFlag)) - { - status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_RxOverrunFlag)) ? - (kStatus_LPUART_RxHardwareOverrun) : - (kStatus_LPUART_FlagCannotClearManually)); - /* Other error flags(FE, NF, and PF) are prevented from setting once OR is set, no need to check other - * error flags*/ - break; - } - - if (0U != (statusFlag & (uint32_t)kLPUART_ParityErrorFlag)) - { - status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_ParityErrorFlag)) ? - (kStatus_LPUART_ParityError) : - (kStatus_LPUART_FlagCannotClearManually)); - } - - if (0U != (statusFlag & (uint32_t)kLPUART_FramingErrorFlag)) - { - status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_FramingErrorFlag)) ? - (kStatus_LPUART_FramingError) : - (kStatus_LPUART_FlagCannotClearManually)); - } - - if (0U != (statusFlag & (uint32_t)kLPUART_NoiseErrorFlag)) - { - status = ((kStatus_Success == LPUART_ClearStatusFlags(base, (uint32_t)kLPUART_NoiseErrorFlag)) ? - (kStatus_LPUART_NoiseError) : - (kStatus_LPUART_FlagCannotClearManually)); - } - if (kStatus_Success != status) - { - break; - } - } - - if (kStatus_Success == status) - { -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (isSevenDataBits) - { - *(dataAddress) = (uint8_t)(base->DATA & 0x7FU); - dataAddress++; - } - else - { - *(dataAddress) = (uint8_t)base->DATA; - dataAddress++; - } -#else - *(dataAddress) = (uint8_t)base->DATA; - dataAddress++; -#endif - } - else - { - break; - } - } - - return status; -} - -/*! - * brief Initializes the LPUART handle. - * - * This function initializes the LPUART handle, which can be used for other LPUART - * transactional APIs. Usually, for a specified LPUART instance, - * call this API once to get the initialized handle. - * - * The LPUART driver supports the "background" receiving, which means that user can set up - * an RX ring buffer optionally. Data received is stored into the ring buffer even when the - * user doesn't call the LPUART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * The ring buffer is disabled if passing NULL as p ringBuffer. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param callback Callback function. - * param userData User data. - */ -void LPUART_TransferCreateHandle(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_callback_t callback, - void *userData) -{ - assert(NULL != handle); - - uint32_t instance; - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - uint32_t ctrl = base->CTRL; - bool isSevenDataBits = (((ctrl & LPUART_CTRL_M7_MASK) != 0U) || - (((ctrl & LPUART_CTRL_M_MASK) == 0U) && ((ctrl & LPUART_CTRL_PE_MASK) != 0U))); -#endif - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(lpuart_handle_t)); - - /* Set the TX/RX state. */ - handle->rxState = (uint8_t)kLPUART_RxIdle; - handle->txState = (uint8_t)kLPUART_TxIdle; - - /* Set the callback and user data. */ - handle->callback = callback; - handle->userData = userData; - -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - /* Initial seven data bits flag */ - handle->isSevenDataBits = isSevenDataBits; -#endif - - /* Get instance from peripheral base address. */ - instance = LPUART_GetInstance(base); - - /* Save the handle in global variables to support the double weak mechanism. */ - s_lpuartHandle[instance] = handle; - - s_lpuartIsr = LPUART_TransferHandleIRQ; - -/* Enable interrupt in NVIC. */ -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ - (void)EnableIRQ(s_lpuartRxIRQ[instance]); - (void)EnableIRQ(s_lpuartTxIRQ[instance]); -#else - (void)EnableIRQ(s_lpuartIRQ[instance]); -#endif -} - -/*! - * brief Sets up the RX ring buffer. - * - * This function sets up the RX ring buffer to a specific UART handle. - * - * When the RX ring buffer is used, data received is stored into the ring buffer even when - * the user doesn't call the UART_TransferReceiveNonBlocking() API. If there is already data received - * in the ring buffer, the user can get the received data from the ring buffer directly. - * - * note When using RX ring buffer, one byte is reserved for internal use. In other - * words, if p ringBufferSize is 32, then only 31 bytes are used for saving data. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param ringBuffer Start address of ring buffer for background receiving. Pass NULL to disable the ring buffer. - * param ringBufferSize size of the ring buffer. - */ -void LPUART_TransferStartRingBuffer(LPUART_Type *base, - lpuart_handle_t *handle, - uint8_t *ringBuffer, - size_t ringBufferSize) -{ - assert(NULL != handle); - assert(NULL != ringBuffer); - - /* Setup the ring buffer address */ - handle->rxRingBuffer = ringBuffer; - handle->rxRingBufferSize = ringBufferSize; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; - - /* Enable the interrupt to accept the data when user need the ring buffer. */ - LPUART_EnableInterrupts( - base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | (uint32_t)kLPUART_RxOverrunInterruptEnable); -} - -/*! - * brief Aborts the background transfer and uninstalls the ring buffer. - * - * This function aborts the background transfer and uninstalls the ring buffer. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferStopRingBuffer(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - if (handle->rxState == (uint8_t)kLPUART_RxIdle) - { - LPUART_DisableInterrupts( - base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | (uint32_t)kLPUART_RxOverrunInterruptEnable); - } - - handle->rxRingBuffer = NULL; - handle->rxRingBufferSize = 0U; - handle->rxRingBufferHead = 0U; - handle->rxRingBufferTail = 0U; -} - -/*! - * brief Transmits a buffer of data using the interrupt method. - * - * This function send data using an interrupt method. This is a non-blocking function, which - * returns directly without waiting for all data written to the transmitter register. When - * all data is written to the TX register in the ISR, the LPUART driver calls the callback - * function and passes the ref kStatus_LPUART_TxIdle as status parameter. - * - * note The kStatus_LPUART_TxIdle is passed to the upper layer when all data are written - * to the TX register. However, there is no check to ensure that all the data sent out. Before disabling the TX, - * check the kLPUART_TransmissionCompleteFlag to ensure that the transmit is finished. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param xfer LPUART transfer structure, see #lpuart_transfer_t. - * retval kStatus_Success Successfully start the data transmission. - * retval kStatus_LPUART_TxBusy Previous transmission still not finished, data not all written to the TX register. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferSendNonBlocking(LPUART_Type *base, lpuart_handle_t *handle, lpuart_transfer_t *xfer) -{ - assert(NULL != handle); - assert(NULL != xfer); - assert(NULL != xfer->data); - assert(0U != xfer->dataSize); - - status_t status; - - /* Return error if current TX busy. */ - if ((uint8_t)kLPUART_TxBusy == handle->txState) - { - status = kStatus_LPUART_TxBusy; - } - else - { - handle->txData = xfer->data; - handle->txDataSize = xfer->dataSize; - handle->txDataSizeAll = xfer->dataSize; - handle->txState = (uint8_t)kLPUART_TxBusy; - - /* Enable transmitter interrupt. */ - LPUART_EnableInterrupts(base, (uint32_t)kLPUART_TxDataRegEmptyInterruptEnable); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the interrupt-driven data transmit. - * - * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out - * how many bytes are not sent out. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferAbortSend(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - LPUART_DisableInterrupts( - base, (uint32_t)kLPUART_TxDataRegEmptyInterruptEnable | (uint32_t)kLPUART_TransmissionCompleteInterruptEnable); - - handle->txDataSize = 0; - handle->txState = (uint8_t)kLPUART_TxIdle; -} - -/*! - * brief Gets the number of bytes that have been sent out to bus. - * - * This function gets the number of bytes that have been sent out to bus by an interrupt method. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Send bytes count. - * retval kStatus_NoTransferInProgress No send in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetSendCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) -{ - assert(NULL != handle); - assert(NULL != count); - - status_t status = kStatus_Success; - size_t tmptxDataSize = handle->txDataSize; - - if ((uint8_t)kLPUART_TxIdle == handle->txState) - { - status = kStatus_NoTransferInProgress; - } - else - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - *count = handle->txDataSizeAll - tmptxDataSize - - ((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); -#else - if ((base->STAT & (uint32_t)kLPUART_TxDataRegEmptyFlag) != 0U) - { - *count = handle->txDataSizeAll - tmptxDataSize; - } - else - { - *count = handle->txDataSizeAll - tmptxDataSize - 1U; - } -#endif - } - - return status; -} - -/*! - * brief Receives a buffer of data using the interrupt method. - * - * This function receives data using an interrupt method. This is a non-blocking function - * which returns without waiting to ensure that all data are received. - * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and - * the parameter p receivedBytes shows how many bytes are copied from the ring buffer. - * After copying, if the data in the ring buffer is not enough for read, the receive - * request is saved by the LPUART driver. When the new data arrives, the receive request - * is serviced first. When all data is received, the LPUART driver notifies the upper layer - * through a callback function and passes a status parameter ref kStatus_UART_RxIdle. - * For example, the upper layer needs 10 bytes but there are only 5 bytes in ring buffer. - * The 5 bytes are copied to xfer->data, which returns with the - * parameter p receivedBytes set to 5. For the remaining 5 bytes, the newly arrived data is - * saved from xfer->data[5]. When 5 bytes are received, the LPUART driver notifies the upper layer. - * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt - * to receive data to xfer->data. When all data is received, the upper layer is notified. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param xfer LPUART transfer structure, see #uart_transfer_t. - * param receivedBytes Bytes received from the ring buffer directly. - * retval kStatus_Success Successfully queue the transfer into the transmit queue. - * retval kStatus_LPUART_RxBusy Previous receive request is not finished. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_TransferReceiveNonBlocking(LPUART_Type *base, - lpuart_handle_t *handle, - lpuart_transfer_t *xfer, - size_t *receivedBytes) -{ - assert(NULL != handle); - assert(NULL != xfer); - assert(NULL != xfer->data); - assert(0U != xfer->dataSize); - - uint32_t i; - status_t status; - /* How many bytes to copy from ring buffer to user memory. */ - size_t bytesToCopy = 0U; - /* How many bytes to receive. */ - size_t bytesToReceive; - /* How many bytes currently have received. */ - size_t bytesCurrentReceived; - - /* How to get data: - 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize - to lpuart handle, enable interrupt to store received data to xfer->data. When - all data received, trigger callback. - 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. - If there are enough data in ring buffer, copy them to xfer->data and return. - If there are not enough data in ring buffer, copy all of them to xfer->data, - save the xfer->data remained empty space to lpuart handle, receive data - to this empty space and trigger callback when finished. */ - - if ((uint8_t)kLPUART_RxBusy == handle->rxState) - { - status = kStatus_LPUART_RxBusy; - } - else - { - bytesToReceive = xfer->dataSize; - bytesCurrentReceived = 0; - - /* If RX ring buffer is used. */ - if (NULL != handle->rxRingBuffer) - { - /* Disable LPUART RX IRQ, protect ring buffer. */ - LPUART_DisableInterrupts(base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable); - - /* How many bytes in RX ring buffer currently. */ - bytesToCopy = LPUART_TransferGetRxRingBufferLength(base, handle); - - if (0U != bytesToCopy) - { - bytesToCopy = MIN(bytesToReceive, bytesToCopy); - - bytesToReceive -= bytesToCopy; - - /* Copy data from ring buffer to user memory. */ - for (i = 0U; i < bytesToCopy; i++) - { - xfer->data[bytesCurrentReceived] = handle->rxRingBuffer[handle->rxRingBufferTail]; - bytesCurrentReceived++; - - /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ - if (((uint32_t)handle->rxRingBufferTail + 1U) == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - } - - /* If ring buffer does not have enough data, still need to read more data. */ - if (0U != bytesToReceive) - { - /* No data in ring buffer, save the request to LPUART handle. */ - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = (uint8_t)kLPUART_RxBusy; - } - /* Enable LPUART RX IRQ if previously enabled. */ - LPUART_EnableInterrupts(base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable); - - /* Call user callback since all data are received. */ - if (0U == bytesToReceive) - { - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } - /* Ring buffer not used. */ - else - { - handle->rxData = xfer->data + bytesCurrentReceived; - handle->rxDataSize = bytesToReceive; - handle->rxDataSizeAll = bytesToReceive; - handle->rxState = (uint8_t)kLPUART_RxBusy; - - /* Enable RX interrupt. */ - LPUART_EnableInterrupts(base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | - (uint32_t)kLPUART_RxOverrunInterruptEnable | - (uint32_t)kLPUART_IdleLineInterruptEnable); - } - - /* Return the how many bytes have read. */ - if (NULL != receivedBytes) - { - *receivedBytes = bytesCurrentReceived; - } - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the interrupt-driven data receiving. - * - * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out - * how many bytes not received yet. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferAbortReceive(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ - if (NULL == handle->rxRingBuffer) - { - /* Disable RX interrupt. */ - LPUART_DisableInterrupts(base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | - (uint32_t)kLPUART_RxOverrunInterruptEnable | - (uint32_t)kLPUART_IdleLineInterruptEnable); - } - - handle->rxDataSize = 0U; - handle->rxState = (uint8_t)kLPUART_RxIdle; -} - -/*! - * brief Gets the number of bytes that have been received. - * - * This function gets the number of bytes that have been received. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Receive bytes count. - * retval kStatus_NoTransferInProgress No receive in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetReceiveCount(LPUART_Type *base, lpuart_handle_t *handle, uint32_t *count) -{ - assert(NULL != handle); - assert(NULL != count); - - status_t status = kStatus_Success; - size_t tmprxDataSize = handle->rxDataSize; - - if ((uint8_t)kLPUART_RxIdle == handle->rxState) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = handle->rxDataSizeAll - tmprxDataSize; - } - - return status; -} - -/*! - * brief LPUART IRQ handle function. - * - * This function handles the LPUART transmit and receive IRQ request. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferHandleIRQ(LPUART_Type *base, lpuart_handle_t *handle) -{ - assert(NULL != handle); - - uint8_t count; - uint8_t tempCount; - uint32_t status = LPUART_GetStatusFlags(base); - uint32_t enabledInterrupts = LPUART_GetEnabledInterrupts(base); - uint16_t tpmRxRingBufferHead; - uint32_t tpmData; - - /* If RX overrun. */ - if ((uint32_t)kLPUART_RxOverrunFlag == ((uint32_t)kLPUART_RxOverrunFlag & status)) - { - /* Clear overrun flag, otherwise the RX does not work. */ - base->STAT = ((base->STAT & 0x3FE00000U) | LPUART_STAT_OR_MASK); - - /* Trigger callback. */ - if (NULL != (handle->callback)) - { - handle->callback(base, handle, kStatus_LPUART_RxHardwareOverrun, handle->userData); - } - } - - /* If IDLE flag is set and the IDLE interrupt is enabled. */ - if ((0U != ((uint32_t)kLPUART_IdleLineFlag & status)) && - (0U != ((uint32_t)kLPUART_IdleLineInterruptEnable & enabledInterrupts))) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); - - while ((0U != handle->rxDataSize) && (0U != count)) - { - tempCount = (uint8_t)MIN(handle->rxDataSize, count); - - /* Using non block API to read the data from the registers. */ - LPUART_ReadNonBlocking(base, handle->rxData, tempCount); - handle->rxData += tempCount; - handle->rxDataSize -= tempCount; - count -= tempCount; - - /* If rxDataSize is 0, disable idle line interrupt.*/ - if (0U == (handle->rxDataSize)) - { - handle->rxState = (uint8_t)kLPUART_RxIdle; - - LPUART_DisableInterrupts( - base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | (uint32_t)kLPUART_RxOverrunInterruptEnable); - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } -#endif - /* Clear IDLE flag.*/ - base->STAT |= LPUART_STAT_IDLE_MASK; - - /* If rxDataSize is 0, disable idle line interrupt.*/ - if (0U != (handle->rxDataSize)) - { - LPUART_DisableInterrupts(base, (uint32_t)kLPUART_IdleLineInterruptEnable); - } - /* If callback is not NULL and rxDataSize is not 0. */ - if ((0U != handle->rxDataSize) && (NULL != handle->callback)) - { - handle->callback(base, handle, kStatus_LPUART_IdleLineDetected, handle->userData); - } - } - /* Receive data register full */ - if ((0U != ((uint32_t)kLPUART_RxDataRegFullFlag & status)) && - (0U != ((uint32_t)kLPUART_RxDataRegFullInterruptEnable & enabledInterrupts))) - { -/* Get the size that can be stored into buffer for this interrupt. */ -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = ((uint8_t)((base->WATER & LPUART_WATER_RXCOUNT_MASK) >> LPUART_WATER_RXCOUNT_SHIFT)); -#else - count = 1; -#endif - - /* If handle->rxDataSize is not 0, first save data to handle->rxData. */ - while ((0U != handle->rxDataSize) && (0U != count)) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - tempCount = (uint8_t)MIN(handle->rxDataSize, count); -#else - tempCount = 1; -#endif - - /* Using non block API to read the data from the registers. */ - LPUART_ReadNonBlocking(base, handle->rxData, tempCount); - handle->rxData += tempCount; - handle->rxDataSize -= tempCount; - count -= tempCount; - - /* If all the data required for upper layer is ready, trigger callback. */ - if (0U == handle->rxDataSize) - { - handle->rxState = (uint8_t)kLPUART_RxIdle; - - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxIdle, handle->userData); - } - } - } - - /* If use RX ring buffer, receive data to ring buffer. */ - if (NULL != handle->rxRingBuffer) - { - while (0U != count--) - { - /* If RX ring buffer is full, trigger callback to notify over run. */ - if (LPUART_TransferIsRxRingBufferFull(base, handle)) - { - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_RxRingBufferOverrun, handle->userData); - } - } - - /* If ring buffer is still full after callback function, the oldest data is overridden. */ - if (LPUART_TransferIsRxRingBufferFull(base, handle)) - { - /* Increase handle->rxRingBufferTail to make room for new data. */ - if (((uint32_t)handle->rxRingBufferTail + 1U) == handle->rxRingBufferSize) - { - handle->rxRingBufferTail = 0U; - } - else - { - handle->rxRingBufferTail++; - } - } - - /* Read data. */ - tpmRxRingBufferHead = handle->rxRingBufferHead; - tpmData = base->DATA; -#if defined(FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT) && FSL_FEATURE_LPUART_HAS_7BIT_DATA_SUPPORT - if (handle->isSevenDataBits) - { - handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)(tpmData & 0x7FU); - } - else - { - handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)tpmData; - } -#else - handle->rxRingBuffer[tpmRxRingBufferHead] = (uint8_t)tpmData; -#endif - - /* Increase handle->rxRingBufferHead. */ - if (((uint32_t)handle->rxRingBufferHead + 1U) == handle->rxRingBufferSize) - { - handle->rxRingBufferHead = 0U; - } - else - { - handle->rxRingBufferHead++; - } - } - } - /* If no receive requst pending, stop RX interrupt. */ - else if (0U == handle->rxDataSize) - { - LPUART_DisableInterrupts( - base, (uint32_t)kLPUART_RxDataRegFullInterruptEnable | (uint32_t)kLPUART_RxOverrunInterruptEnable); - } - else - { - } - } - - /* Send data register empty and the interrupt is enabled. */ - if ((0U != ((uint32_t)kLPUART_TxDataRegEmptyFlag & status)) && - (0U != ((uint32_t)kLPUART_TxDataRegEmptyInterruptEnable & enabledInterrupts))) - { -/* Get the bytes that available at this moment. */ -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - count = (uint8_t)FSL_FEATURE_LPUART_FIFO_SIZEn(base) - - (uint8_t)((base->WATER & LPUART_WATER_TXCOUNT_MASK) >> LPUART_WATER_TXCOUNT_SHIFT); -#else - count = 1; -#endif - - while ((0U != handle->txDataSize) && (0U != count)) - { -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - tempCount = (uint8_t)MIN(handle->txDataSize, count); -#else - tempCount = 1; -#endif - - /* Using non block API to write the data to the registers. */ - LPUART_WriteNonBlocking(base, handle->txData, tempCount); - handle->txData += tempCount; - handle->txDataSize -= tempCount; - count -= tempCount; - - /* If all the data are written to data register, notify user with the callback, then TX finished. */ - if (0U == handle->txDataSize) - { - /* Disable TX register empty interrupt. */ - base->CTRL = (base->CTRL & ~LPUART_CTRL_TIE_MASK); - /* Enable transmission complete interrupt. */ - LPUART_EnableInterrupts(base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable); - } - } - } - - /* Transmission complete and the interrupt is enabled. */ - if ((0U != ((uint32_t)kLPUART_TransmissionCompleteFlag & status)) && - (0U != ((uint32_t)kLPUART_TransmissionCompleteInterruptEnable & enabledInterrupts))) - { - /* Set txState to idle only when all data has been sent out to bus. */ - handle->txState = (uint8_t)kLPUART_TxIdle; - /* Disable transmission complete interrupt. */ - LPUART_DisableInterrupts(base, (uint32_t)kLPUART_TransmissionCompleteInterruptEnable); - - /* Trigger callback. */ - if (NULL != handle->callback) - { - handle->callback(base, handle, kStatus_LPUART_TxIdle, handle->userData); - } - } -} - -/*! - * brief LPUART Error IRQ handle function. - * - * This function handles the LPUART error IRQ request. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - */ -void LPUART_TransferHandleErrorIRQ(LPUART_Type *base, lpuart_handle_t *handle) -{ - /* To be implemented by User. */ -} -#if defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1 -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART0_LPUART1_RX_DriverIRQHandler(void) -{ - uint32_t stat = 0U; - uint32_t ctrl = 0U; - - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - stat = LPUART0->STAT; - ctrl = LPUART0->CTRL; - if ((LPUART_STAT_OR_MASK & stat) || ((LPUART_STAT_RDRF_MASK & stat) && (LPUART_CTRL_RIE_MASK & ctrl))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - stat = LPUART1->STAT; - ctrl = LPUART1->CTRL; - if ((LPUART_STAT_OR_MASK & stat) || ((LPUART_STAT_RDRF_MASK & stat) && (LPUART_CTRL_RIE_MASK & ctrl))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } - SDK_ISR_EXIT_BARRIER; -} -void LPUART0_LPUART1_TX_DriverIRQHandler(void) -{ - uint32_t stat = 0U; - uint32_t ctrl = 0U; - - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - stat = LPUART0->STAT; - ctrl = LPUART0->CTRL; - if ((LPUART_STAT_OR_MASK & stat) || ((stat & LPUART_STAT_TDRE_MASK) && (ctrl & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - stat = LPUART1->STAT; - ctrl = LPUART1->CTRL; - if ((LPUART_STAT_OR_MASK & stat) || ((stat & LPUART_STAT_TDRE_MASK) && (ctrl & LPUART_CTRL_TIE_MASK))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART0_LPUART1_DriverIRQHandler(void) -{ - uint32_t stat = 0U; - uint32_t ctrl = 0U; - - if (CLOCK_isEnabledClock(s_lpuartClock[0])) - { - stat = LPUART0->STAT; - ctrl = LPUART0->CTRL; - if ((0U != (LPUART_STAT_OR_MASK & stat)) || - ((0U != (LPUART_STAT_RDRF_MASK & stat)) && (0U != (LPUART_CTRL_RIE_MASK & ctrl))) || - ((0U != (stat & LPUART_STAT_TDRE_MASK)) && (0U != (ctrl & LPUART_CTRL_TIE_MASK)))) - { - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - } - } - if (CLOCK_isEnabledClock(s_lpuartClock[1])) - { - stat = LPUART1->STAT; - ctrl = LPUART1->CTRL; - if ((0U != (LPUART_STAT_OR_MASK & stat)) || - ((0U != (LPUART_STAT_RDRF_MASK & stat)) && (0U != (LPUART_CTRL_RIE_MASK & ctrl))) || - ((0U != (stat & LPUART_STAT_TDRE_MASK)) && (0U != (ctrl & LPUART_CTRL_TIE_MASK)))) - { - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - } - } - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART0) -#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART0_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART0_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART0_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART0, s_lpuartHandle[0]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif -#endif - -#if defined(LPUART1) -#if !(defined(FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) && FSL_FEATURE_LPUART_HAS_SHARED_IRQ0_IRQ1) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART1_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART1_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART1_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART1, s_lpuartHandle[1]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif -#endif - -#if defined(LPUART2) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART2_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART2_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART2_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART2, s_lpuartHandle[2]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART3) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART3_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART3_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART3_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART3, s_lpuartHandle[3]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART4) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART4_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART4_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART4_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART4, s_lpuartHandle[4]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART5) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART5_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART5_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART5_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART5, s_lpuartHandle[5]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART6) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART6_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART6_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART6_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART6, s_lpuartHandle[6]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART7) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART7_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART7_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART7_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART7, s_lpuartHandle[7]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(LPUART8) -#if defined(FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ) && FSL_FEATURE_LPUART_HAS_SEPARATE_RX_TX_IRQ -void LPUART8_TX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); - SDK_ISR_EXIT_BARRIER; -} -void LPUART8_RX_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); - SDK_ISR_EXIT_BARRIER; -} -#else -void LPUART8_DriverIRQHandler(void) -{ - s_lpuartIsr(LPUART8, s_lpuartHandle[8]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(CM4_0__LPUART) -void M4_0_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4_0__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_0__LPUART)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CM4_1__LPUART) -void M4_1_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4_1__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4_1__LPUART)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(CM4__LPUART) -void M4_LPUART_DriverIRQHandler(void) -{ - s_lpuartIsr(CM4__LPUART, s_lpuartHandle[LPUART_GetInstance(CM4__LPUART)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__LPUART0) -void DMA_UART0_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART0)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__LPUART1) -void DMA_UART1_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART1)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__LPUART2) -void DMA_UART2_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART2)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__LPUART3) -void DMA_UART3_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART3)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(DMA__LPUART4) -void DMA_UART4_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(DMA__LPUART4, s_lpuartHandle[LPUART_GetInstance(DMA__LPUART4)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__LPUART0) -void ADMA_UART0_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART0, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART0)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__LPUART1) -void ADMA_UART1_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART1, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART1)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__LPUART2) -void ADMA_UART2_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART2, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART2)]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(ADMA__LPUART3) -void ADMA_UART3_INT_DriverIRQHandler(void) -{ - s_lpuartIsr(ADMA__LPUART3, s_lpuartHandle[LPUART_GetInstance(ADMA__LPUART3)]); - SDK_ISR_EXIT_BARRIER; -} -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart_edma.c deleted file mode 100644 index c165539ada..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_lpuart_edma.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_lpuart_edma.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.lpuart_edma" -#endif - -/*<! Structure definition for lpuart_edma_private_handle_t. The structure is private. */ -typedef struct _lpuart_edma_private_handle -{ - LPUART_Type *base; - lpuart_edma_handle_t *handle; -} lpuart_edma_private_handle_t; - -/* LPUART EDMA transfer handle. */ -enum -{ - kLPUART_TxIdle, /* TX idle. */ - kLPUART_TxBusy, /* TX busy. */ - kLPUART_RxIdle, /* RX idle. */ - kLPUART_RxBusy /* RX busy. */ -}; - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Array of LPUART handle. */ -#if (defined(LPUART8)) -#define LPUART_HANDLE_ARRAY_SIZE 9 -#else /* LPUART8 */ -#if (defined(LPUART7)) -#define LPUART_HANDLE_ARRAY_SIZE 8 -#else /* LPUART7 */ -#if (defined(LPUART6)) -#define LPUART_HANDLE_ARRAY_SIZE 7 -#else /* LPUART6 */ -#if (defined(LPUART5)) -#define LPUART_HANDLE_ARRAY_SIZE 6 -#else /* LPUART5 */ -#if (defined(LPUART4)) -#define LPUART_HANDLE_ARRAY_SIZE 5 -#else /* LPUART4 */ -#if (defined(LPUART3)) -#define LPUART_HANDLE_ARRAY_SIZE 4 -#else /* LPUART3 */ -#if (defined(LPUART2)) -#define LPUART_HANDLE_ARRAY_SIZE 3 -#else /* LPUART2 */ -#if (defined(LPUART1)) -#define LPUART_HANDLE_ARRAY_SIZE 2 -#else /* LPUART1 */ -#if (defined(LPUART0)) -#define LPUART_HANDLE_ARRAY_SIZE 1 -#else /* LPUART0 */ -#define LPUART_HANDLE_ARRAY_SIZE FSL_FEATURE_SOC_LPUART_COUNT -#endif /* LPUART 0 */ -#endif /* LPUART 1 */ -#endif /* LPUART 2 */ -#endif /* LPUART 3 */ -#endif /* LPUART 4 */ -#endif /* LPUART 5 */ -#endif /* LPUART 6 */ -#endif /* LPUART 7 */ -#endif /* LPUART 8 */ - -/*<! Private handle only used for internally. */ -static lpuart_edma_private_handle_t s_lpuartEdmaPrivateHandle[LPUART_HANDLE_ARRAY_SIZE]; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief LPUART EDMA send finished callback function. - * - * This function is called when LPUART EDMA send finished. It disables the LPUART - * TX EDMA request and sends @ref kStatus_LPUART_TxIdle to LPUART callback. - * - * @param handle The EDMA handle. - * @param param Callback function parameter. - */ -static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); - -/*! - * @brief LPUART EDMA receive finished callback function. - * - * This function is called when LPUART EDMA receive finished. It disables the LPUART - * RX EDMA request and sends @ref kStatus_LPUART_RxIdle to LPUART callback. - * - * @param handle The EDMA handle. - * @param param Callback function parameter. - */ -static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static void LPUART_SendEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) -{ - assert(NULL != param); - - lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; - - /* Avoid the warning for unused variables. */ - handle = handle; - tcds = tcds; - - if (transferDone) - { - LPUART_TransferAbortSendEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle); - - /* Ensure all the data in the transmit buffer are sent out to bus. */ - while (0U == (lpuartPrivateHandle->base->STAT & LPUART_STAT_TC_MASK)) - { - } - - if (NULL != lpuartPrivateHandle->handle->callback) - { - lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, - kStatus_LPUART_TxIdle, lpuartPrivateHandle->handle->userData); - } - } -} - -static void LPUART_ReceiveEDMACallback(edma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) -{ - assert(NULL != param); - - lpuart_edma_private_handle_t *lpuartPrivateHandle = (lpuart_edma_private_handle_t *)param; - - /* Avoid warning for unused parameters. */ - handle = handle; - tcds = tcds; - - if (transferDone) - { - /* Disable transfer. */ - LPUART_TransferAbortReceiveEDMA(lpuartPrivateHandle->base, lpuartPrivateHandle->handle); - - if (NULL != lpuartPrivateHandle->handle->callback) - { - lpuartPrivateHandle->handle->callback(lpuartPrivateHandle->base, lpuartPrivateHandle->handle, - kStatus_LPUART_RxIdle, lpuartPrivateHandle->handle->userData); - } - } -} - -/*! - * brief Initializes the LPUART handle which is used in transactional functions. - * param base LPUART peripheral base address. - * param handle Pointer to lpuart_edma_handle_t structure. - * param callback Callback function. - * param userData User data. - * param txEdmaHandle User requested DMA handle for TX DMA transfer. - * param rxEdmaHandle User requested DMA handle for RX DMA transfer. - */ -void LPUART_TransferCreateHandleEDMA(LPUART_Type *base, - lpuart_edma_handle_t *handle, - lpuart_edma_transfer_callback_t callback, - void *userData, - edma_handle_t *txEdmaHandle, - edma_handle_t *rxEdmaHandle) -{ - assert(NULL != handle); - - uint32_t instance = LPUART_GetInstance(base); - - s_lpuartEdmaPrivateHandle[instance].base = base; - s_lpuartEdmaPrivateHandle[instance].handle = handle; - - (void)memset(handle, 0, sizeof(*handle)); - - handle->rxState = (uint8_t)kLPUART_RxIdle; - handle->txState = (uint8_t)kLPUART_TxIdle; - - handle->rxEdmaHandle = rxEdmaHandle; - handle->txEdmaHandle = txEdmaHandle; - - handle->callback = callback; - handle->userData = userData; - -#if defined(FSL_FEATURE_LPUART_HAS_FIFO) && FSL_FEATURE_LPUART_HAS_FIFO - /* Note: - Take care of the RX FIFO, EDMA request only assert when received bytes - equal or more than RX water mark, there is potential issue if RX water - mark larger than 1. - For example, if RX FIFO water mark is 2, upper layer needs 5 bytes and - 5 bytes are received. the last byte will be saved in FIFO but not trigger - EDMA transfer because the water mark is 2. - */ - if (NULL != rxEdmaHandle) - { - base->WATER &= (~LPUART_WATER_RXWATER_MASK); - } -#endif - - /* Configure TX. */ - if (NULL != txEdmaHandle) - { - EDMA_SetCallback(handle->txEdmaHandle, LPUART_SendEDMACallback, &s_lpuartEdmaPrivateHandle[instance]); - } - - /* Configure RX. */ - if (NULL != rxEdmaHandle) - { - EDMA_SetCallback(handle->rxEdmaHandle, LPUART_ReceiveEDMACallback, &s_lpuartEdmaPrivateHandle[instance]); - } -} - -/*! - * brief Sends data using eDMA. - * - * This function sends data using eDMA. This is a non-blocking function, which returns - * right away. When all data is sent, the send callback function is called. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param xfer LPUART eDMA transfer structure. See #lpuart_transfer_t. - * retval kStatus_Success if succeed, others failed. - * retval kStatus_LPUART_TxBusy Previous transfer on going. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_SendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) -{ - assert(NULL != handle); - assert(NULL != handle->txEdmaHandle); - assert(NULL != xfer); - assert(NULL != xfer->data); - assert(0U != xfer->dataSize); - - edma_transfer_config_t xferConfig; - status_t status; - - /* If previous TX not finished. */ - if ((uint8_t)kLPUART_TxBusy == handle->txState) - { - status = kStatus_LPUART_TxBusy; - } - else - { - handle->txState = (uint8_t)kLPUART_TxBusy; - handle->txDataSizeAll = xfer->dataSize; - - /* Prepare transfer. */ - EDMA_PrepareTransfer(&xferConfig, xfer->data, sizeof(uint8_t), - (void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), sizeof(uint8_t), - xfer->dataSize, kEDMA_MemoryToPeripheral); - - /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ - handle->nbytes = (uint8_t)sizeof(uint8_t); - - /* Submit transfer. */ - if (kStatus_Success != - EDMA_SubmitTransfer(handle->txEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig)) - { - return kStatus_Fail; - } - EDMA_StartTransfer(handle->txEdmaHandle); - - /* Enable LPUART TX EDMA. */ - LPUART_EnableTxDMA(base, true); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Receives data using eDMA. - * - * This function receives data using eDMA. This is non-blocking function, which returns - * right away. When all data is received, the receive callback function is called. - * - * param base LPUART peripheral base address. - * param handle Pointer to lpuart_edma_handle_t structure. - * param xfer LPUART eDMA transfer structure, see #lpuart_transfer_t. - * retval kStatus_Success if succeed, others fail. - * retval kStatus_LPUART_RxBusy Previous transfer ongoing. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t LPUART_ReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, lpuart_transfer_t *xfer) -{ - assert(NULL != handle); - assert(NULL != handle->rxEdmaHandle); - assert(NULL != xfer); - assert(NULL != xfer->data); - assert(0U != xfer->dataSize); - - edma_transfer_config_t xferConfig; - status_t status; - - /* If previous RX not finished. */ - if ((uint8_t)kLPUART_RxBusy == handle->rxState) - { - status = kStatus_LPUART_RxBusy; - } - else - { - handle->rxState = (uint8_t)kLPUART_RxBusy; - handle->rxDataSizeAll = xfer->dataSize; - - /* Prepare transfer. */ - EDMA_PrepareTransfer(&xferConfig, (void *)(uint32_t *)LPUART_GetDataRegisterAddress(base), sizeof(uint8_t), - xfer->data, sizeof(uint8_t), sizeof(uint8_t), xfer->dataSize, kEDMA_PeripheralToMemory); - - /* Store the initially configured eDMA minor byte transfer count into the LPUART handle */ - handle->nbytes = (uint8_t)sizeof(uint8_t); - - /* Submit transfer. */ - if (kStatus_Success != - EDMA_SubmitTransfer(handle->rxEdmaHandle, (const edma_transfer_config_t *)(uint32_t)&xferConfig)) - { - return kStatus_Fail; - } - EDMA_StartTransfer(handle->rxEdmaHandle); - - /* Enable LPUART RX EDMA. */ - LPUART_EnableRxDMA(base, true); - - status = kStatus_Success; - } - - return status; -} - -/*! - * brief Aborts the sent data using eDMA. - * - * This function aborts the sent data using eDMA. - * - * param base LPUART peripheral base address. - * param handle Pointer to lpuart_edma_handle_t structure. - */ -void LPUART_TransferAbortSendEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) -{ - assert(NULL != handle); - assert(NULL != handle->txEdmaHandle); - - /* Disable LPUART TX EDMA. */ - LPUART_EnableTxDMA(base, false); - - /* Stop transfer. */ - EDMA_AbortTransfer(handle->txEdmaHandle); - - handle->txState = (uint8_t)kLPUART_TxIdle; -} - -/*! - * brief Aborts the received data using eDMA. - * - * This function aborts the received data using eDMA. - * - * param base LPUART peripheral base address. - * param handle Pointer to lpuart_edma_handle_t structure. - */ -void LPUART_TransferAbortReceiveEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle) -{ - assert(NULL != handle); - assert(NULL != handle->rxEdmaHandle); - - /* Disable LPUART RX EDMA. */ - LPUART_EnableRxDMA(base, false); - - /* Stop transfer. */ - EDMA_AbortTransfer(handle->rxEdmaHandle); - - handle->rxState = (uint8_t)kLPUART_RxIdle; -} - -/*! - * brief Gets the number of received bytes. - * - * This function gets the number of received bytes. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Receive bytes count. - * retval kStatus_NoTransferInProgress No receive in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetReceiveCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) -{ - assert(NULL != handle); - assert(NULL != handle->rxEdmaHandle); - assert(NULL != count); - - if ((uint8_t)kLPUART_RxIdle == handle->rxState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->rxDataSizeAll - - ((uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->rxEdmaHandle->base, handle->rxEdmaHandle->channel)); - - return kStatus_Success; -} - -/*! - * brief Gets the number of bytes written to the LPUART TX register. - * - * This function gets the number of bytes written to the LPUART TX - * register by DMA. - * - * param base LPUART peripheral base address. - * param handle LPUART handle pointer. - * param count Send bytes count. - * retval kStatus_NoTransferInProgress No send in progress. - * retval kStatus_InvalidArgument Parameter is invalid. - * retval kStatus_Success Get successfully through the parameter \p count; - */ -status_t LPUART_TransferGetSendCountEDMA(LPUART_Type *base, lpuart_edma_handle_t *handle, uint32_t *count) -{ - assert(NULL != handle); - assert(NULL != handle->txEdmaHandle); - assert(NULL != count); - - if ((uint8_t)kLPUART_TxIdle == handle->txState) - { - return kStatus_NoTransferInProgress; - } - - *count = handle->txDataSizeAll - - ((uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->txEdmaHandle->base, handle->txEdmaHandle->channel)); - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ocotp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ocotp.c deleted file mode 100644 index e37daf059c..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_ocotp.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright 2019-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_ocotp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.ocotp" -#endif - -/* Wait time should be not less than 150ns . */ -#define OCOTP_TIMING_WAIT_NS (uint64_t)150 -/* Relex time should be not less than 100ns . */ -#define OCOTP_TIMING_RELEX_NS (uint64_t)100 -/* Program time should be rang from 9000ns~11000ns. */ -#define OCOTP_TIMING_PROGRAM_NS (uint64_t)10000 -/* Read time should be less than 40ns. */ -#define OCOTP_TIMING_READ_NS (uint64_t)40 - -/* Unlock key is 0x3E77. */ -#define OCOTP_WRITE_UNLOCK_KEY (0x3E77) -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Set read timing configuration. - * - * @param base OCOTP peripheral base addess. - * @param timingConfig configuration of timing. - */ -static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig); - -/*! - * @brief Set write timing configuration. - * - * @param base OCOTP peripheral base addess. - * @param timingConfig configuration of timing. - */ -static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* Timing configuration for OCOTP controller. */ -ocotp_timing_t s_timingConfig; - -/******************************************************************************* - * Code - *******************************************************************************/ -/* Reload the shadow register. */ -void OCOTP_ReloadShadowRegister(OCOTP_Type *base) -{ - assert(NULL != base); - - /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* Clear access error status bit. */ - OCOTP_ClearErrorStatus(base); - - /* Set the read timing. */ - OCOTP_SetReadTiming(base, s_timingConfig); - - /* Wait for the OCOTP controller not busy. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* Set reload bit. */ - base->CTRL_SET = OCOTP_CTRL_RELOAD_SHADOWS(1); - - /* Wait for the OCOTP controller not busy. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - /* Wait for shadow register reload complete. this bit will be auto clear by OCOTP once operation is complete. */ - while (OCOTP_CTRL_RELOAD_SHADOWS_MASK == (base->CTRL & OCOTP_CTRL_RELOAD_SHADOWS_MASK)) - { - } -} - -static void OCOTP_SetReadTiming(OCOTP_Type *base, ocotp_timing_t timingConfig) -{ - uint32_t timingValue = base->TIMING; - - timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_READ_MASK | OCOTP_TIMING_WAIT_MASK); - timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_READ(timingConfig.strobe_read) | - OCOTP_TIMING_WAIT(timingConfig.wait); - base->TIMING = timingValue; -} - -static void OCOTP_SetWriteTiming(OCOTP_Type *base, ocotp_timing_t timingConfig) -{ - uint32_t timingValue = base->TIMING; - - timingValue &= ~(OCOTP_TIMING_RELAX_MASK | OCOTP_TIMING_STROBE_PROG_MASK | OCOTP_TIMING_WAIT_MASK); - timingValue |= OCOTP_TIMING_RELAX(timingConfig.relax) | OCOTP_TIMING_STROBE_PROG(timingConfig.strobe_prog) | - OCOTP_TIMING_WAIT(timingConfig.wait); - - base->TIMING = timingValue; -} - -/* Initializes OCOTP controller. */ -void OCOTP_Init(OCOTP_Type *base, uint32_t srcClock_Hz) -{ - assert(NULL != base); - assert(0UL != srcClock_Hz); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable OCOTP clock */ - CLOCK_EnableClock(kCLOCK_Ocotp); -#endif - - /* tWait time shoule be higher than OCOTP_TIMING_WAIT_NS. */ - s_timingConfig.wait = (OCOTP_TIMING_WAIT_NS * srcClock_Hz + 1000000000) / 1000000000 - 1; - - /* tRelax time shoule be higher than OCOTP_TIMING_RELEX_NS. */ - s_timingConfig.relax = (OCOTP_TIMING_RELEX_NS * srcClock_Hz + 1000000000) / 1000000000 - 1; - - /* tStrobe_prog time should be close to OCOTP_TIMING_PROGRAM_NS, only add half of 1000000000. */ - s_timingConfig.strobe_prog = - (OCOTP_TIMING_PROGRAM_NS * srcClock_Hz + 500000000) / 1000000000 + 2 * (s_timingConfig.relax + 1) - 1; - - /* tStrobe_read time should be higher than OCOTP_TIMING_READ_NS. */ - s_timingConfig.strobe_read = - (OCOTP_TIMING_READ_NS * srcClock_Hz + 1000000000) / 1000000000 + 2 * (s_timingConfig.relax + 1) - 1; -} - -/* De-init OCOTP controller. */ -void OCOTP_Deinit(OCOTP_Type *base) -{ - assert(NULL != base); - - s_timingConfig.wait = 0UL; - s_timingConfig.relax = 0UL; - s_timingConfig.strobe_prog = 0UL; - s_timingConfig.strobe_read = 0UL; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable OCOTP clock */ - CLOCK_DisableClock(kCLOCK_Ocotp); -#endif -} - -/* Read the fuse shadow register. */ -uint32_t OCOTP_ReadFuseShadowRegister(OCOTP_Type *base, uint32_t address) -{ - assert(NULL != base); - - /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* If ERROR bit was set, clear access error status bit. */ - if (OCOTP_CheckErrorStatus(base)) - { - OCOTP_ClearErrorStatus(base); - } - - /* Set the read timing. */ - OCOTP_SetReadTiming(base, s_timingConfig); - - /* Wait for busy bit is cleared. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* Clear access error status bit. */ - if (OCOTP_CheckErrorStatus(base)) - { - OCOTP_ClearErrorStatus(base); - } - - /* Write requested address to register. */ - base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK; - base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address); - - /* Set OCOTP auto read enable. */ - base->READ_CTRL = OCOTP_READ_CTRL_READ_FUSE_MASK; - - /* Wait for busy bit is cleared, and no error occurred on controller. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */ - if (OCOTP_CheckErrorStatus(base)) - { - /* Clear access error status bit. */ - OCOTP_ClearErrorStatus(base); - } - - /* Read the fuse data. */ - return (base->READ_FUSE_DATA); -} - -/* Write the fuse shadow register. */ -status_t OCOTP_WriteFuseShadowRegister(OCOTP_Type *base, uint32_t address, uint32_t data) -{ - assert(NULL != base); - - /* Make sure the OCOTP is ready, Overlapped accesses are not supported by the controller. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* Clear access error status bit. */ - if (OCOTP_CheckErrorStatus(base)) - { - OCOTP_ClearErrorStatus(base); - } - - /* Set write timing for OCOTP controller. */ - OCOTP_SetWriteTiming(base, s_timingConfig); - - /* Wait for busy bit is cleared. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* Clear access error status bit. */ - if (OCOTP_CheckErrorStatus(base)) - { - OCOTP_ClearErrorStatus(base); - } - - /* Write requested address and unlock key to register. */ - base->CTRL_CLR = OCOTP_CTRL_CLR_ADDR_MASK | OCOTP_CTRL_WR_UNLOCK_MASK; - base->CTRL_SET = OCOTP_CTRL_SET_ADDR(address) | OCOTP_CTRL_WR_UNLOCK(OCOTP_WRITE_UNLOCK_KEY); - - /* Write data to register. */ - base->DATA = data; - - /* Wait for busy bit is cleared, and no error occurred on controller. */ - while (OCOTP_CheckBusyStatus(base)) - { - } - - /* If ERROR bit was set, this may be mean that the accsee to the register was wrong. */ - if (OCOTP_CheckErrorStatus(base)) - { - /* Clear access error status bit. */ - OCOTP_ClearErrorStatus(base); - - return kStatus_OCOTP_AccessError; - } - - /* Reload the fuse register. */ - OCOTP_ReloadShadowRegister(base); - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pit.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pit.c deleted file mode 100644 index 659de24999..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pit.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_pit.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.pit" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Gets the instance from the base address to be used to gate or ungate the module clock - * - * @param base PIT peripheral base address - * - * @return The PIT instance - */ -static uint32_t PIT_GetInstance(PIT_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to PIT bases for each instance. */ -static PIT_Type *const s_pitBases[] = PIT_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to PIT clocks for each instance. */ -static const clock_ip_name_t s_pitClocks[] = PIT_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t PIT_GetInstance(PIT_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_pitBases); instance++) - { - if (s_pitBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_pitBases)); - - return instance; -} - -/*! - * brief Ungates the PIT clock, enables the PIT module, and configures the peripheral for basic operations. - * - * note This API should be called at the beginning of the application using the PIT driver. - * - * param base PIT peripheral base address - * param config Pointer to the user's PIT config structure - */ -void PIT_Init(PIT_Type *base, const pit_config_t *config) -{ - assert(NULL != config); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate the PIT clock*/ - CLOCK_EnableClock(s_pitClocks[PIT_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_PIT_HAS_MDIS) && FSL_FEATURE_PIT_HAS_MDIS - /* Enable PIT timers */ - base->MCR &= ~PIT_MCR_MDIS_MASK; -#endif - -#if defined(FSL_FEATURE_PIT_TIMER_COUNT) && (FSL_FEATURE_PIT_TIMER_COUNT) - /* Clear all status bits for all channels to make sure the status of all TCTRL registers is clean. */ - for (uint8_t i = 0U; i < (uint32_t)FSL_FEATURE_PIT_TIMER_COUNT; i++) - { - base->CHANNEL[i].TCTRL &= ~(PIT_TCTRL_TEN_MASK | PIT_TCTRL_TIE_MASK | PIT_TCTRL_CHN_MASK); - } -#endif /* FSL_FEATURE_PIT_TIMER_COUNT */ - - /* Config timer operation when in debug mode */ - if (true == config->enableRunInDebug) - { - base->MCR &= ~PIT_MCR_FRZ_MASK; - } - else - { - base->MCR |= PIT_MCR_FRZ_MASK; - } -} - -/*! - * brief Gates the PIT clock and disables the PIT module. - * - * param base PIT peripheral base address - */ -void PIT_Deinit(PIT_Type *base) -{ -#if defined(FSL_FEATURE_PIT_HAS_MDIS) && FSL_FEATURE_PIT_HAS_MDIS - /* Disable PIT timers */ - base->MCR |= PIT_MCR_MDIS_MASK; -#endif - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Gate the PIT clock*/ - CLOCK_DisableClock(s_pitClocks[PIT_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -#if defined(FSL_FEATURE_PIT_HAS_LIFETIME_TIMER) && FSL_FEATURE_PIT_HAS_LIFETIME_TIMER - -/*! - * brief Reads the current lifetime counter value. - * - * The lifetime timer is a 64-bit timer which chains timer 0 and timer 1 together. - * Timer 0 and 1 are chained by calling the PIT_SetTimerChainMode before using this timer. - * The period of lifetime timer is equal to the "period of timer 0 * period of timer 1". - * For the 64-bit value, the higher 32-bit has the value of timer 1, and the lower 32-bit - * has the value of timer 0. - * - * param base PIT peripheral base address - * - * return Current lifetime timer value - */ -uint64_t PIT_GetLifetimeTimerCount(PIT_Type *base) -{ - uint32_t valueH = 0U; - uint32_t valueL = 0U; - - /* LTMR64H should be read before LTMR64L */ - valueH = base->LTMR64H; - valueL = base->LTMR64L; - - return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); -} - -#endif /* FSL_FEATURE_PIT_HAS_LIFETIME_TIMER */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pmu.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pmu.c deleted file mode 100644 index 8e8b0473bf..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pmu.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include "fsl_pmu.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.pmu" -#endif - -/*! - * name Status. - * { - */ - -uint32_t PMU_GetStatusFlags(PMU_Type *base) -{ - uint32_t ret = 0U; - - /* For 1P1. */ - if (PMU_REG_1P1_OK_VDD1P1_MASK == (PMU_REG_1P1_OK_VDD1P1_MASK & base->REG_1P1)) - { - ret |= (uint32_t)kPMU_1P1RegulatorOutputOK; - } - if (PMU_REG_1P1_BO_VDD1P1_MASK == (PMU_REG_1P1_BO_VDD1P1_MASK & base->REG_1P1)) - { - ret |= (uint32_t)kPMU_1P1BrownoutOnOutput; - } - - /* For 3P0. */ - if (PMU_REG_3P0_OK_VDD3P0_MASK == (PMU_REG_3P0_OK_VDD3P0_MASK & base->REG_3P0)) - { - ret |= (uint32_t)kPMU_3P0RegulatorOutputOK; - } - if (PMU_REG_3P0_BO_VDD3P0_MASK == (PMU_REG_3P0_BO_VDD3P0_MASK & base->REG_3P0)) - { - ret |= (uint32_t)kPMU_3P0BrownoutOnOutput; - } - - /* For 2P5. */ - if (PMU_REG_2P5_OK_VDD2P5_MASK == (PMU_REG_2P5_OK_VDD2P5_MASK & base->REG_2P5)) - { - ret |= (uint32_t)kPMU_2P5RegulatorOutputOK; - } - if (PMU_REG_2P5_BO_VDD2P5_MASK == (PMU_REG_2P5_BO_VDD2P5_MASK & base->REG_2P5)) - { - ret |= (uint32_t)kPMU_2P5BrownoutOnOutput; - } - - return ret; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pwm.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pwm.c deleted file mode 100644 index d16fe3a139..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pwm.c +++ /dev/null @@ -1,935 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_pwm.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.pwm" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance from the base address - * - * @param base PWM peripheral base address - * - * @return The PWM module instance - */ -static uint32_t PWM_GetInstance(PWM_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to PWM bases for each instance. */ -static PWM_Type *const s_pwmBases[] = PWM_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to PWM clocks for each PWM submodule. */ -static const clock_ip_name_t s_pwmClocks[][FSL_FEATURE_PWM_SUBMODULE_COUNT] = PWM_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Complement the variable of type uint16_t as needed - * - * This function can complement the variable of type uint16_t as needed.For example, - * need to ask for the opposite of a positive integer. - * - * param value Parameters of type uint16_t - */ -static inline uint16_t PWM_GetComplementU16(uint16_t value) -{ - return (~value + 1U); -} - -static inline uint16_t dutyCycleToReloadValue(uint8_t dutyCyclePercent) -{ - /* Rounding calculations to improve the accuracy of reloadValue */ - return ((65535U * dutyCyclePercent) + 50U) / 100U; -} - -static uint32_t PWM_GetInstance(PWM_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_pwmBases); instance++) - { - if (s_pwmBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_pwmBases)); - - return instance; -} - -/*! - * brief Ungates the PWM submodule clock and configures the peripheral for basic operation. - * - * note This API should be called at the beginning of the application using the PWM driver. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param config Pointer to user's PWM config structure. - * - * return kStatus_Success means success; else failed. - */ -status_t PWM_Init(PWM_Type *base, pwm_submodule_t subModule, const pwm_config_t *config) -{ - assert(config); - - uint16_t reg; - - /* Source clock for submodule 0 cannot be itself */ - if ((config->clockSource == kPWM_Submodule0Clock) && (subModule == kPWM_Module_0)) - { - return kStatus_Fail; - } - - /* Reload source select clock for submodule 0 cannot be master reload */ - if ((config->reloadSelect == kPWM_MasterReload) && (subModule == kPWM_Module_0)) - { - return kStatus_Fail; - } - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Ungate the PWM submodule clock*/ - CLOCK_EnableClock(s_pwmClocks[PWM_GetInstance(base)][subModule]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Clear the fault status flags */ - base->FSTS |= PWM_FSTS_FFLAG_MASK; - - reg = base->SM[subModule].CTRL2; - - /* Setup the submodule clock-source, control source of the INIT signal, - * source of the force output signal, operation in debug & wait modes and reload source select - */ - reg &= ~(uint16_t)(PWM_CTRL2_CLK_SEL_MASK | PWM_CTRL2_FORCE_SEL_MASK | PWM_CTRL2_INIT_SEL_MASK | - PWM_CTRL2_INDEP_MASK | PWM_CTRL2_WAITEN_MASK | PWM_CTRL2_DBGEN_MASK | PWM_CTRL2_RELOAD_SEL_MASK); - reg |= (PWM_CTRL2_CLK_SEL(config->clockSource) | PWM_CTRL2_FORCE_SEL(config->forceTrigger) | - PWM_CTRL2_INIT_SEL(config->initializationControl) | PWM_CTRL2_DBGEN(config->enableDebugMode) | - PWM_CTRL2_WAITEN(config->enableWait) | PWM_CTRL2_RELOAD_SEL(config->reloadSelect)); - - /* Setup PWM A & B to be independent or a complementary-pair */ - switch (config->pairOperation) - { - case kPWM_Independent: - reg |= PWM_CTRL2_INDEP_MASK; - break; - case kPWM_ComplementaryPwmA: - base->MCTRL &= ~((uint16_t)1U << (PWM_MCTRL_IPOL_SHIFT + (uint16_t)subModule)); - break; - case kPWM_ComplementaryPwmB: - base->MCTRL |= ((uint16_t)1U << (PWM_MCTRL_IPOL_SHIFT + (uint16_t)subModule)); - break; - default: - assert(false); - break; - } - base->SM[subModule].CTRL2 = reg; - - reg = base->SM[subModule].CTRL; - - /* Setup the clock prescale, load mode and frequency */ - reg &= ~(uint16_t)(PWM_CTRL_PRSC_MASK | PWM_CTRL_LDFQ_MASK | PWM_CTRL_LDMOD_MASK); - reg |= (PWM_CTRL_PRSC(config->prescale) | PWM_CTRL_LDFQ(config->reloadFrequency)); - - /* Setup register reload logic */ - switch (config->reloadLogic) - { - case kPWM_ReloadImmediate: - reg |= PWM_CTRL_LDMOD_MASK; - break; - case kPWM_ReloadPwmHalfCycle: - reg |= PWM_CTRL_HALF_MASK; - reg &= (uint16_t)(~PWM_CTRL_FULL_MASK); - break; - case kPWM_ReloadPwmFullCycle: - reg &= (uint16_t)(~PWM_CTRL_HALF_MASK); - reg |= PWM_CTRL_FULL_MASK; - break; - case kPWM_ReloadPwmHalfAndFullCycle: - reg |= PWM_CTRL_HALF_MASK; - reg |= PWM_CTRL_FULL_MASK; - break; - default: - assert(false); - break; - } - base->SM[subModule].CTRL = reg; - - /* Issue a Force trigger event when configured to trigger locally */ - if (config->forceTrigger == kPWM_Force_Local) - { - base->SM[subModule].CTRL2 |= PWM_CTRL2_FORCE(1U); - } - - return kStatus_Success; -} - -/*! - * brief Gate the PWM submodule clock - * - * param base PWM peripheral base address - * param subModule PWM submodule to deinitialize - */ -void PWM_Deinit(PWM_Type *base, pwm_submodule_t subModule) -{ - /* Stop the submodule */ - base->MCTRL &= ~((uint16_t)1U << (PWM_MCTRL_RUN_SHIFT + (uint16_t)subModule)); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Gate the PWM submodule clock*/ - CLOCK_DisableClock(s_pwmClocks[PWM_GetInstance(base)][subModule]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Fill in the PWM config struct with the default settings - * - * The default values are: - * code - * config->enableDebugMode = false; - * config->enableWait = false; - * config->reloadSelect = kPWM_LocalReload; - * config->clockSource = kPWM_BusClock; - * config->prescale = kPWM_Prescale_Divide_1; - * config->initializationControl = kPWM_Initialize_LocalSync; - * config->forceTrigger = kPWM_Force_Local; - * config->reloadFrequency = kPWM_LoadEveryOportunity; - * config->reloadLogic = kPWM_ReloadImmediate; - * config->pairOperation = kPWM_Independent; - * endcode - * param config Pointer to user's PWM config structure. - */ -void PWM_GetDefaultConfig(pwm_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - /* PWM is paused in debug mode */ - config->enableDebugMode = false; - /* PWM is paused in wait mode */ - config->enableWait = false; - /* PWM module uses the local reload signal to reload registers */ - config->reloadSelect = kPWM_LocalReload; - /* Use the IP Bus clock as source clock for the PWM submodule */ - config->clockSource = kPWM_BusClock; - /* Clock source prescale is set to divide by 1*/ - config->prescale = kPWM_Prescale_Divide_1; - /* Local sync causes initialization */ - config->initializationControl = kPWM_Initialize_LocalSync; - /* The local force signal, CTRL2[FORCE], from the submodule is used to force updates */ - config->forceTrigger = kPWM_Force_Local; - /* PWM reload frequency, reload opportunity is PWM half cycle or full cycle. - * This field is not used in Immediate reload mode - */ - config->reloadFrequency = kPWM_LoadEveryOportunity; - /* Buffered-registers get loaded with new values as soon as LDOK bit is set */ - config->reloadLogic = kPWM_ReloadImmediate; - /* PWM A & PWM B operate as 2 independent channels */ - config->pairOperation = kPWM_Independent; -} - -/*! - * brief Sets up the PWM signals for a PWM submodule. - * - * The function initializes the submodule according to the parameters passed in by the user. The function - * also sets up the value compare registers to match the PWM signal requirements. - * If the dead time insertion logic is enabled, the pulse period is reduced by the - * dead time period specified by the user. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param chnlParams Array of PWM channel parameters to configure the channel(s) - * param numOfChnls Number of channels to configure, this should be the size of the array passed in. - * Array size should not be more than 2 as each submodule has 2 pins to output PWM - * param mode PWM operation mode, options available in enumeration ::pwm_mode_t - * param pwmFreq_Hz PWM signal frequency in Hz - * param srcClock_Hz PWM main counter clock in Hz. - * - * return Returns kStatusFail if there was error setting up the signal; kStatusSuccess otherwise - */ -status_t PWM_SetupPwm(PWM_Type *base, - pwm_submodule_t subModule, - const pwm_signal_param_t *chnlParams, - uint8_t numOfChnls, - pwm_mode_t mode, - uint32_t pwmFreq_Hz, - uint32_t srcClock_Hz) -{ - assert(chnlParams); - assert(pwmFreq_Hz); - assert(numOfChnls); - assert(srcClock_Hz); - - uint32_t pwmClock; - uint16_t pulseCnt = 0, pwmHighPulse = 0; - uint16_t modulo = 0; - uint8_t i, polarityShift = 0, outputEnableShift = 0; - - if (numOfChnls > 2U) - { - /* Each submodule has 2 signals; PWM A & PWM B */ - return kStatus_Fail; - } - - /* Divide the clock by the prescale value */ - pwmClock = (srcClock_Hz / (1UL << ((base->SM[subModule].CTRL & PWM_CTRL_PRSC_MASK) >> PWM_CTRL_PRSC_SHIFT))); - pulseCnt = (uint16_t)(pwmClock / pwmFreq_Hz); - - /* Setup each PWM channel */ - for (i = 0; i < numOfChnls; i++) - { - /* Calculate pulse width */ - pwmHighPulse = (pulseCnt * chnlParams->dutyCyclePercent) / 100U; - - /* Setup the different match registers to generate the PWM signal */ - switch (mode) - { - case kPWM_SignedCenterAligned: - /* Setup the PWM period for a signed center aligned signal */ - if (i == 0U) - { - modulo = (pulseCnt >> 1U); - /* Indicates the start of the PWM period */ - base->SM[subModule].INIT = PWM_GetComplementU16(modulo); - /* Indicates the center value */ - base->SM[subModule].VAL0 = 0; - /* Indicates the end of the PWM period */ - /* The change during the end to start of the PWM period requires a count time */ - base->SM[subModule].VAL1 = modulo - 1U; - } - - /* Setup the PWM dutycycle */ - if (chnlParams->pwmChannel == kPWM_PwmA) - { - base->SM[subModule].VAL2 = PWM_GetComplementU16(pwmHighPulse / 2U); - base->SM[subModule].VAL3 = (pwmHighPulse / 2U); - } - else - { - base->SM[subModule].VAL4 = PWM_GetComplementU16(pwmHighPulse / 2U); - base->SM[subModule].VAL5 = (pwmHighPulse / 2U); - } - break; - case kPWM_CenterAligned: - /* Setup the PWM period for an unsigned center aligned signal */ - /* Indicates the start of the PWM period */ - if (i == 0U) - { - base->SM[subModule].INIT = 0; - /* Indicates the center value */ - base->SM[subModule].VAL0 = (pulseCnt / 2U); - /* Indicates the end of the PWM period */ - /* The change during the end to start of the PWM period requires a count time */ - base->SM[subModule].VAL1 = pulseCnt - 1U; - } - - /* Setup the PWM dutycycle */ - if (chnlParams->pwmChannel == kPWM_PwmA) - { - base->SM[subModule].VAL2 = ((pulseCnt - pwmHighPulse) / 2U); - base->SM[subModule].VAL3 = ((pulseCnt + pwmHighPulse) / 2U); - } - else - { - base->SM[subModule].VAL4 = ((pulseCnt - pwmHighPulse) / 2U); - base->SM[subModule].VAL5 = ((pulseCnt + pwmHighPulse) / 2U); - } - break; - case kPWM_SignedEdgeAligned: - /* Setup the PWM period for a signed edge aligned signal */ - if (i == 0U) - { - modulo = (pulseCnt >> 1U); - /* Indicates the start of the PWM period */ - base->SM[subModule].INIT = PWM_GetComplementU16(modulo); - /* Indicates the center value */ - base->SM[subModule].VAL0 = 0; - /* Indicates the end of the PWM period */ - /* The change during the end to start of the PWM period requires a count time */ - base->SM[subModule].VAL1 = modulo - 1U; - } - - /* Setup the PWM dutycycle */ - if (chnlParams->pwmChannel == kPWM_PwmA) - { - base->SM[subModule].VAL2 = PWM_GetComplementU16(modulo); - base->SM[subModule].VAL3 = PWM_GetComplementU16(modulo) + pwmHighPulse; - } - else - { - base->SM[subModule].VAL4 = PWM_GetComplementU16(modulo); - base->SM[subModule].VAL5 = PWM_GetComplementU16(modulo) + pwmHighPulse; - } - break; - case kPWM_EdgeAligned: - /* Setup the PWM period for a unsigned edge aligned signal */ - /* Indicates the start of the PWM period */ - if (i == 0U) - { - base->SM[subModule].INIT = 0; - /* Indicates the center value */ - base->SM[subModule].VAL0 = (pulseCnt / 2U); - /* Indicates the end of the PWM period */ - /* The change during the end to start of the PWM period requires a count time */ - base->SM[subModule].VAL1 = pulseCnt - 1U; - } - - /* Setup the PWM dutycycle */ - if (chnlParams->pwmChannel == kPWM_PwmA) - { - base->SM[subModule].VAL2 = 0; - base->SM[subModule].VAL3 = pwmHighPulse; - } - else - { - base->SM[subModule].VAL4 = 0; - base->SM[subModule].VAL5 = pwmHighPulse; - } - break; - default: - assert(false); - break; - } - /* Setup register shift values based on the channel being configured. - * Also setup the deadtime value - */ - if (chnlParams->pwmChannel == kPWM_PwmA) - { - polarityShift = PWM_OCTRL_POLA_SHIFT; - outputEnableShift = PWM_OUTEN_PWMA_EN_SHIFT; - base->SM[subModule].DTCNT0 = PWM_DTCNT0_DTCNT0(chnlParams->deadtimeValue); - } - else - { - polarityShift = PWM_OCTRL_POLB_SHIFT; - outputEnableShift = PWM_OUTEN_PWMB_EN_SHIFT; - base->SM[subModule].DTCNT1 = PWM_DTCNT1_DTCNT1(chnlParams->deadtimeValue); - } - - /* Set PWM output fault status */ - switch (chnlParams->pwmChannel) - { - case kPWM_PwmA: - base->SM[subModule].OCTRL &= ~((uint16_t)PWM_OCTRL_PWMAFS_MASK); - base->SM[subModule].OCTRL |= (((uint16_t)(chnlParams->faultState) << (uint16_t)PWM_OCTRL_PWMAFS_SHIFT) & - (uint16_t)PWM_OCTRL_PWMAFS_MASK); - break; - case kPWM_PwmB: - base->SM[subModule].OCTRL &= ~((uint16_t)PWM_OCTRL_PWMBFS_MASK); - base->SM[subModule].OCTRL |= (((uint16_t)(chnlParams->faultState) << (uint16_t)PWM_OCTRL_PWMBFS_SHIFT) & - (uint16_t)PWM_OCTRL_PWMBFS_MASK); - break; - case kPWM_PwmX: - base->SM[subModule].OCTRL &= ~((uint16_t)PWM_OCTRL_PWMXFS_MASK); - base->SM[subModule].OCTRL |= (((uint16_t)(chnlParams->faultState) << (uint16_t)PWM_OCTRL_PWMXFS_SHIFT) & - (uint16_t)PWM_OCTRL_PWMXFS_MASK); - break; - default: - assert(false); - break; - } - - /* Setup signal active level */ - if ((bool)chnlParams->level == kPWM_HighTrue) - { - base->SM[subModule].OCTRL &= ~((uint16_t)1U << (uint16_t)polarityShift); - } - else - { - base->SM[subModule].OCTRL |= ((uint16_t)1U << (uint16_t)polarityShift); - } - /* Enable PWM output */ - base->OUTEN |= ((uint16_t)1U << ((uint16_t)outputEnableShift + (uint16_t)subModule)); - - /* Get the next channel parameters */ - chnlParams++; - } - - return kStatus_Success; -} - -/*! - * brief Updates the PWM signal's dutycycle. - * - * The function updates the PWM dutycyle to the new value that is passed in. - * If the dead time insertion logic is enabled then the pulse period is reduced by the - * dead time period specified by the user. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param pwmSignal Signal (PWM A or PWM B) to update - * param currPwmMode The current PWM mode set during PWM setup - * param dutyCyclePercent New PWM pulse width, value should be between 0 to 100 - * 0=inactive signal(0% duty cycle)... - * 100=active signal (100% duty cycle) - */ -void PWM_UpdatePwmDutycycle(PWM_Type *base, - pwm_submodule_t subModule, - pwm_channels_t pwmSignal, - pwm_mode_t currPwmMode, - uint8_t dutyCyclePercent) -{ - assert(dutyCyclePercent <= 100U); - assert((uint16_t)pwmSignal < 2U); - uint16_t reloadValue = dutyCycleToReloadValue(dutyCyclePercent); - - PWM_UpdatePwmDutycycleHighAccuracy(base, subModule, pwmSignal, currPwmMode, reloadValue); -} - -/*! - * brief Updates the PWM signal's dutycycle with 16-bit accuracy. - * - * The function updates the PWM dutycyle to the new value that is passed in. - * If the dead time insertion logic is enabled then the pulse period is reduced by the - * dead time period specified by the user. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param pwmSignal Signal (PWM A or PWM B) to update - * param currPwmMode The current PWM mode set during PWM setup - * param dutyCycle New PWM pulse width, value should be between 0 to 65535 - * 0=inactive signal(0% duty cycle)... - * 65535=active signal (100% duty cycle) - */ -void PWM_UpdatePwmDutycycleHighAccuracy( - PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmSignal, pwm_mode_t currPwmMode, uint16_t dutyCycle) -{ - assert((uint16_t)pwmSignal < 2U); - uint16_t pulseCnt = 0, pwmHighPulse = 0; - uint16_t modulo = 0; - - switch (currPwmMode) - { - case kPWM_SignedCenterAligned: - modulo = base->SM[subModule].VAL1 + 1U; - pulseCnt = modulo * 2U; - /* Calculate pulse width */ - pwmHighPulse = (pulseCnt * dutyCycle) / 65535U; - - /* Setup the PWM dutycycle */ - if (pwmSignal == kPWM_PwmA) - { - base->SM[subModule].VAL2 = PWM_GetComplementU16(pwmHighPulse / 2U); - base->SM[subModule].VAL3 = (pwmHighPulse / 2U); - } - else - { - base->SM[subModule].VAL4 = PWM_GetComplementU16(pwmHighPulse / 2U); - base->SM[subModule].VAL5 = (pwmHighPulse / 2U); - } - break; - case kPWM_CenterAligned: - pulseCnt = base->SM[subModule].VAL1 + 1U; - /* Calculate pulse width */ - pwmHighPulse = (pulseCnt * dutyCycle) / 65535U; - - /* Setup the PWM dutycycle */ - if (pwmSignal == kPWM_PwmA) - { - base->SM[subModule].VAL2 = ((pulseCnt - pwmHighPulse) / 2U); - base->SM[subModule].VAL3 = ((pulseCnt + pwmHighPulse) / 2U); - } - else - { - base->SM[subModule].VAL4 = ((pulseCnt - pwmHighPulse) / 2U); - base->SM[subModule].VAL5 = ((pulseCnt + pwmHighPulse) / 2U); - } - break; - case kPWM_SignedEdgeAligned: - modulo = base->SM[subModule].VAL1 + 1U; - pulseCnt = modulo * 2U; - /* Calculate pulse width */ - pwmHighPulse = (pulseCnt * dutyCycle) / 65535U; - - /* Setup the PWM dutycycle */ - if (pwmSignal == kPWM_PwmA) - { - base->SM[subModule].VAL2 = PWM_GetComplementU16(modulo); - base->SM[subModule].VAL3 = PWM_GetComplementU16(modulo) + pwmHighPulse; - } - else - { - base->SM[subModule].VAL4 = PWM_GetComplementU16(modulo); - base->SM[subModule].VAL5 = PWM_GetComplementU16(modulo) + pwmHighPulse; - } - break; - case kPWM_EdgeAligned: - pulseCnt = base->SM[subModule].VAL1 + 1U; - /* Calculate pulse width */ - pwmHighPulse = (pulseCnt * dutyCycle) / 65535U; - - /* Setup the PWM dutycycle */ - if (pwmSignal == kPWM_PwmA) - { - base->SM[subModule].VAL2 = 0; - base->SM[subModule].VAL3 = pwmHighPulse; - } - else - { - base->SM[subModule].VAL4 = 0; - base->SM[subModule].VAL5 = pwmHighPulse; - } - break; - default: - assert(false); - break; - } -} - -/*! - * brief Sets up the PWM input capture - * - * Each PWM submodule has 3 pins that can be configured for use as input capture pins. This function - * sets up the capture parameters for each pin and enables the pin for input capture operation. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param pwmChannel Channel in the submodule to setup - * param inputCaptureParams Parameters passed in to set up the input pin - */ -void PWM_SetupInputCapture(PWM_Type *base, - pwm_submodule_t subModule, - pwm_channels_t pwmChannel, - const pwm_input_capture_param_t *inputCaptureParams) -{ - uint16_t reg = 0; - switch (pwmChannel) - { - case kPWM_PwmA: - /* Setup the capture paramters for PWM A pin */ - reg = (PWM_CAPTCTRLA_INP_SELA(inputCaptureParams->captureInputSel) | - PWM_CAPTCTRLA_EDGA0(inputCaptureParams->edge0) | PWM_CAPTCTRLA_EDGA1(inputCaptureParams->edge1) | - PWM_CAPTCTRLA_ONESHOTA(inputCaptureParams->enableOneShotCapture) | - PWM_CAPTCTRLA_CFAWM(inputCaptureParams->fifoWatermark)); - /* Enable the edge counter if using the output edge counter */ - if (inputCaptureParams->captureInputSel) - { - reg |= PWM_CAPTCTRLA_EDGCNTA_EN_MASK; - } - /* Enable input capture operation */ - reg |= PWM_CAPTCTRLA_ARMA_MASK; - - base->SM[subModule].CAPTCTRLA = reg; - - /* Setup the compare value when using the edge counter as source */ - base->SM[subModule].CAPTCOMPA = PWM_CAPTCOMPA_EDGCMPA(inputCaptureParams->edgeCompareValue); - /* Setup PWM A pin for input capture */ - base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMA_EN_SHIFT + (uint16_t)subModule)); - break; - case kPWM_PwmB: - /* Setup the capture paramters for PWM B pin */ - reg = (PWM_CAPTCTRLB_INP_SELB(inputCaptureParams->captureInputSel) | - PWM_CAPTCTRLB_EDGB0(inputCaptureParams->edge0) | PWM_CAPTCTRLB_EDGB1(inputCaptureParams->edge1) | - PWM_CAPTCTRLB_ONESHOTB(inputCaptureParams->enableOneShotCapture) | - PWM_CAPTCTRLB_CFBWM(inputCaptureParams->fifoWatermark)); - /* Enable the edge counter if using the output edge counter */ - if (inputCaptureParams->captureInputSel) - { - reg |= PWM_CAPTCTRLB_EDGCNTB_EN_MASK; - } - /* Enable input capture operation */ - reg |= PWM_CAPTCTRLB_ARMB_MASK; - - base->SM[subModule].CAPTCTRLB = reg; - - /* Setup the compare value when using the edge counter as source */ - base->SM[subModule].CAPTCOMPB = PWM_CAPTCOMPB_EDGCMPB(inputCaptureParams->edgeCompareValue); - /* Setup PWM B pin for input capture */ - base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMB_EN_SHIFT + (uint16_t)subModule)); - break; - case kPWM_PwmX: - reg = (PWM_CAPTCTRLX_INP_SELX(inputCaptureParams->captureInputSel) | - PWM_CAPTCTRLX_EDGX0(inputCaptureParams->edge0) | PWM_CAPTCTRLX_EDGX1(inputCaptureParams->edge1) | - PWM_CAPTCTRLX_ONESHOTX(inputCaptureParams->enableOneShotCapture) | - PWM_CAPTCTRLX_CFXWM(inputCaptureParams->fifoWatermark)); - /* Enable the edge counter if using the output edge counter */ - if (inputCaptureParams->captureInputSel) - { - reg |= PWM_CAPTCTRLX_EDGCNTX_EN_MASK; - } - /* Enable input capture operation */ - reg |= PWM_CAPTCTRLX_ARMX_MASK; - - base->SM[subModule].CAPTCTRLX = reg; - - /* Setup the compare value when using the edge counter as source */ - base->SM[subModule].CAPTCOMPX = PWM_CAPTCOMPX_EDGCMPX(inputCaptureParams->edgeCompareValue); - /* Setup PWM X pin for input capture */ - base->OUTEN &= ~((uint16_t)1U << (PWM_OUTEN_PWMX_EN_SHIFT + (uint16_t)subModule)); - break; - default: - assert(false); - break; - } -} - -/*! - * @brief Sets up the PWM fault input filter. - * - * @param base PWM peripheral base address - * @param faultInputFilterParams Parameters passed in to set up the fault input filter. - */ -void PWM_SetupFaultInputFilter(PWM_Type *base, const pwm_fault_input_filter_param_t *faultInputFilterParams) -{ - assert(NULL != faultInputFilterParams); - - /* When changing values for fault period from a non-zero value, first write a value of 0 to clear the filter. */ - if (0U != (base->FFILT & PWM_FFILT_FILT_PER_MASK)) - { - base->FFILT &= ~(uint16_t)(PWM_FFILT_FILT_PER_MASK); - } - - base->FFILT = (uint16_t)(PWM_FFILT_FILT_PER(faultInputFilterParams->faultFilterPeriod) | - PWM_FFILT_FILT_CNT(faultInputFilterParams->faultFilterCount) | - PWM_FFILT_GSTR(faultInputFilterParams->faultGlitchStretch ? 1U : 0U)); -} - -/*! - * brief Sets up the PWM fault protection. - * - * PWM has 4 fault inputs. - * - * param base PWM peripheral base address - * param faultNum PWM fault to configure. - * param faultParams Pointer to the PWM fault config structure - */ -void PWM_SetupFaults(PWM_Type *base, pwm_fault_input_t faultNum, const pwm_fault_param_t *faultParams) -{ - assert(faultParams); - uint16_t reg; - - reg = base->FCTRL; - /* Set the faults level-settting */ - if (faultParams->faultLevel) - { - reg |= ((uint16_t)1U << (PWM_FCTRL_FLVL_SHIFT + (uint16_t)faultNum)); - } - else - { - reg &= ~((uint16_t)1U << (PWM_FCTRL_FLVL_SHIFT + (uint16_t)faultNum)); - } - /* Set the fault clearing mode */ - if ((uint16_t)faultParams->faultClearingMode != 0U) - { - /* Use manual fault clearing */ - reg &= ~((uint16_t)1U << (PWM_FCTRL_FAUTO_SHIFT + (uint16_t)faultNum)); - if (faultParams->faultClearingMode == kPWM_ManualSafety) - { - /* Use manual fault clearing with safety mode enabled */ - reg |= ((uint16_t)1U << (PWM_FCTRL_FSAFE_SHIFT + (uint16_t)faultNum)); - } - else - { - /* Use manual fault clearing with safety mode disabled */ - reg &= ~((uint16_t)1U << (PWM_FCTRL_FSAFE_SHIFT + (uint16_t)faultNum)); - } - } - else - { - /* Use automatic fault clearing */ - reg |= ((uint16_t)1U << (PWM_FCTRL_FAUTO_SHIFT + (uint16_t)faultNum)); - } - base->FCTRL = reg; - - /* Set the combinational path option */ - if (faultParams->enableCombinationalPath) - { - /* Combinational path from the fault input to the PWM output is available */ - base->FCTRL2 &= ~((uint16_t)1U << (uint16_t)faultNum); - } - else - { - /* No combinational path available, only fault filter & latch signal can disable PWM output */ - base->FCTRL2 |= ((uint16_t)1U << (uint16_t)faultNum); - } - - /* Initially clear both recovery modes */ - reg = base->FSTS; - reg &= ~(((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum)) | - ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum))); - /* Setup fault recovery */ - switch (faultParams->recoverMode) - { - case kPWM_NoRecovery: - break; - case kPWM_RecoverHalfCycle: - reg |= ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum)); - break; - case kPWM_RecoverFullCycle: - reg |= ((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum)); - break; - case kPWM_RecoverHalfAndFullCycle: - reg |= ((uint16_t)1U << (PWM_FSTS_FHALF_SHIFT + (uint16_t)faultNum)); - reg |= ((uint16_t)1U << (PWM_FSTS_FFULL_SHIFT + (uint16_t)faultNum)); - break; - default: - assert(false); - break; - } - base->FSTS = reg; -} - -/*! - * brief Fill in the PWM fault config struct with the default settings - * - * The default values are: - * code - * config->faultClearingMode = kPWM_Automatic; - * config->faultLevel = false; - * config->enableCombinationalPath = true; - * config->recoverMode = kPWM_NoRecovery; - * endcode - * param config Pointer to user's PWM fault config structure. - */ -void PWM_FaultDefaultConfig(pwm_fault_param_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - /* PWM uses automatic fault clear mode */ - config->faultClearingMode = kPWM_Automatic; - /* PWM fault level is set to logic 0 */ - config->faultLevel = false; - /* Combinational Path from fault input is enabled */ - config->enableCombinationalPath = true; - /* PWM output will stay inactive when recovering from a fault */ - config->recoverMode = kPWM_NoRecovery; -} - -/*! - * brief Selects the signal to output on a PWM pin when a FORCE_OUT signal is asserted. - * - * The user specifies which channel to configure by supplying the submodule number and whether - * to modify PWM A or PWM B within that submodule. - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param pwmChannel Channel to configure - * param mode Signal to output when a FORCE_OUT is triggered - */ -void PWM_SetupForceSignal(PWM_Type *base, pwm_submodule_t subModule, pwm_channels_t pwmChannel, pwm_force_signal_t mode) - -{ - uint16_t shift; - uint16_t reg; - - /* DTSRCSEL register has 4 bits per submodule; 2 bits for PWM A and 2 bits for PWM B */ - shift = ((uint16_t)subModule * 4U) + ((uint16_t)pwmChannel * 2U); - - /* Setup the signal to be passed upon occurrence of a FORCE_OUT signal */ - reg = base->DTSRCSEL; - reg &= ~((uint16_t)0x3U << shift); - reg |= (uint16_t)((uint16_t)mode << shift); - base->DTSRCSEL = reg; -} - -/*! - * brief Enables the selected PWM interrupts - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param mask The interrupts to enable. This is a logical OR of members of the - * enumeration ::pwm_interrupt_enable_t - */ -void PWM_EnableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask) -{ - /* Upper 16 bits are for related to the submodule */ - base->SM[subModule].INTEN |= ((uint16_t)mask & 0xFFFFU); - /* Fault related interrupts */ - base->FCTRL |= ((uint16_t)(mask >> 16U) & PWM_FCTRL_FIE_MASK); -} - -/*! - * brief Disables the selected PWM interrupts - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param mask The interrupts to enable. This is a logical OR of members of the - * enumeration ::pwm_interrupt_enable_t - */ -void PWM_DisableInterrupts(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask) -{ - base->SM[subModule].INTEN &= ~((uint16_t)mask & 0xFFFFU); - base->FCTRL &= ~((uint16_t)(mask >> 16U) & PWM_FCTRL_FIE_MASK); -} - -/*! - * brief Gets the enabled PWM interrupts - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * - * return The enabled interrupts. This is the logical OR of members of the - * enumeration ::pwm_interrupt_enable_t - */ -uint32_t PWM_GetEnabledInterrupts(PWM_Type *base, pwm_submodule_t subModule) -{ - uint32_t enabledInterrupts; - - enabledInterrupts = base->SM[subModule].INTEN; - enabledInterrupts |= (((uint32_t)base->FCTRL & PWM_FCTRL_FIE_MASK) << 16UL); - return enabledInterrupts; -} - -/*! - * brief Gets the PWM status flags - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * - * return The status flags. This is the logical OR of members of the - * enumeration ::pwm_status_flags_t - */ -uint32_t PWM_GetStatusFlags(PWM_Type *base, pwm_submodule_t subModule) -{ - uint32_t statusFlags; - - statusFlags = base->SM[subModule].STS; - statusFlags |= (((uint32_t)base->FSTS & PWM_FSTS_FFLAG_MASK) << 16UL); - - return statusFlags; -} - -/*! - * brief Clears the PWM status flags - * - * param base PWM peripheral base address - * param subModule PWM submodule to configure - * param mask The status flags to clear. This is a logical OR of members of the - * enumeration ::pwm_status_flags_t - */ -void PWM_ClearStatusFlags(PWM_Type *base, pwm_submodule_t subModule, uint32_t mask) -{ - uint16_t reg; - - base->SM[subModule].STS = ((uint16_t)mask & 0xFFFFU); - reg = base->FSTS; - /* Clear the fault flags and set only the ones we wish to clear as the fault flags are cleared - * by writing a login one - */ - reg &= ~(uint16_t)(PWM_FSTS_FFLAG_MASK); - reg |= (uint16_t)((mask >> 16U) & PWM_FSTS_FFLAG_MASK); - base->FSTS = reg; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pxp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pxp.c deleted file mode 100644 index 2d9740ff54..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_pxp.c +++ /dev/null @@ -1,1050 +0,0 @@ -/* - * Copyright 2017-2020 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_pxp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.pxp" -#endif - -/* The CSC2 coefficient is ###.####_#### */ -#define PXP_CSC2_COEF_INT_WIDTH 2 -#define PXP_CSC2_COEF_FRAC_WIDTH 8 - -/* Compatibility map macro. */ -#if defined(PXP_PS_CLRKEYLOW_0_PIXEL_MASK) && (!defined(PXP_PS_CLRKEYLOW_PIXEL_MASK)) -#define PS_CLRKEYLOW PS_CLRKEYLOW_0 -#define PS_CLRKEYHIGH PS_CLRKEYHIGH_0 -#endif -#if defined(PXP_AS_CLRKEYLOW_0_PIXEL_MASK) && (!defined(PXP_AS_CLRKEYLOW_PIXEL_MASK)) -#define AS_CLRKEYLOW AS_CLRKEYLOW_0 -#define AS_CLRKEYHIGH AS_CLRKEYHIGH_0 -#endif - -#define PXP_MAX_HEIGHT ((PXP_OUT_LRC_Y_MASK >> PXP_OUT_LRC_Y_SHIFT) + 1U) - -typedef union _u32_f32 -{ - float f32; - uint32_t u32; -} u32_f32_t; - -typedef union _pxp_pvoid_u32 -{ - void *pvoid; - uint32_t u32; -} pxp_pvoid_u32_t; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance from the base address - * - * @param base PXP peripheral base address - * - * @return The PXP module instance - */ -static uint32_t PXP_GetInstance(PXP_Type *base); - -#if !(defined(FSL_FEATURE_PXP_HAS_NO_CSC2) && FSL_FEATURE_PXP_HAS_NO_CSC2) -/*! - * @brief Convert IEEE 754 float value to the value could be written to registers. - * - * This function converts the float value to integer value to set the scaler - * and CSC parameters. - * - * This function is an alternative implemention of the following code with no - * MISRA 2004 rule 10.4 error: - * - * @code - return (uint32_t)(floatValue * (float)(1 << fracBits)); - @endcode - * - * @param floatValue The float value to convert. - * @param intBits Bits number of integer part in result. - * @param fracBits Bits number of fractional part in result. - * @return The value to set to register. - */ -static uint32_t PXP_ConvertFloat(float floatValue, uint8_t intBits, uint8_t fracBits); -#endif - -/*! - * @brief Convert the desired scale fact to DEC and PS_SCALE. - * - * @param inputDimension Input dimension. - * @param outputDimension Output dimension. - * @param dec The decimation filter contr0l value. - * @param scale The scale value set to register PS_SCALE. - */ -static void PXP_GetScalerParam(uint16_t inputDimension, uint16_t outputDimension, uint8_t *dec, uint32_t *scale); - -/*! - * @brief Reset the PXP to initialized state. - * - * @param base PXP peripheral base address. - */ -static void PXP_ResetToInit(PXP_Type *base); - -/*! - * @brief Copy rectangle. - * - * @param base PXP peripheral base address. - * @param srcAddr Start address of the soruce rectangle. - * @param srcPitchBytes Pitch of source buffer. - * @param destAddr Start address of the destination rectangle. - * @param destPitchBytes Pitch of destination buffer. - * @param width How many pixels one line to copy. - * @param height How many lines to copy. - * @param pixelFormat Pixel format. - */ -static void PXP_StartRectCopy(PXP_Type *base, - uint32_t srcAddr, - uint16_t srcPitchBytes, - uint32_t destAddr, - uint16_t destPitchBytes, - uint16_t width, - uint16_t height, - pxp_as_pixel_format_t pixelFormat); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to PXP bases for each instance. */ -static PXP_Type *const s_pxpBases[] = PXP_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to PXP clocks for each PXP submodule. */ -static const clock_ip_name_t s_pxpClocks[] = PXP_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t PXP_GetInstance(PXP_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_pxpBases); instance++) - { - if (s_pxpBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_pxpBases)); - - return instance; -} - -#if !(defined(FSL_FEATURE_PXP_HAS_NO_CSC2) && FSL_FEATURE_PXP_HAS_NO_CSC2) -static uint32_t PXP_ConvertFloat(float floatValue, uint8_t intBits, uint8_t fracBits) -{ - /* One bit reserved for sign bit. */ - assert(intBits + fracBits < 32); - - u32_f32_t u32_f32; - uint32_t ret; - - u32_f32.f32 = floatValue; - uint32_t floatBits = u32_f32.u32; - int32_t expValue = (int32_t)((floatBits & 0x7F800000U) >> 23U) - 127; - - ret = (floatBits & 0x007FFFFFU) | 0x00800000U; - expValue += fracBits; - - if (expValue < 0) - { - return 0U; - } - else if (expValue > 23) - { - /* should not exceed 31-bit when left shift. */ - assert((expValue - 23) <= 7); - ret <<= (expValue - 23); - } - else - { - ret >>= (23 - expValue); - } - - /* Set the sign bit. */ - if (floatBits & 0x80000000U) - { - ret = ((~ret) + 1U) & ~(((uint32_t)-1) << (intBits + fracBits + 1)); - } - - return ret; -} -#endif - -static void PXP_GetScalerParam(uint16_t inputDimension, uint16_t outputDimension, uint8_t *dec, uint32_t *scale) -{ - uint32_t scaleFact = ((uint32_t)inputDimension << 12U) / outputDimension; - - if (scaleFact >= (16UL << 12U)) - { - /* Desired fact is two large, use the largest support value. */ - *dec = 3U; - *scale = 0x2000U; - } - else - { - if (scaleFact > (8UL << 12U)) - { - *dec = 3U; - } - else if (scaleFact > (4UL << 12U)) - { - *dec = 2U; - } - else if (scaleFact > (2UL << 12U)) - { - *dec = 1U; - } - else - { - *dec = 0U; - } - - *scale = scaleFact >> (*dec); - - if (0U == *scale) - { - *scale = 1U; - } - } -} - -static void PXP_ResetToInit(PXP_Type *base) -{ - uint32_t ctrl = 0U; - - PXP_Reset(base); - -/* Enable the process engine in primary processing flow. */ -#if defined(PXP_CTRL_ENABLE_ROTATE0_MASK) - ctrl |= PXP_CTRL_ENABLE_ROTATE0_MASK; -#endif -#if defined(PXP_CTRL_ENABLE_ROTATE1_MASK) - ctrl |= PXP_CTRL_ENABLE_ROTATE1_MASK; -#endif -#if defined(PXP_CTRL_ENABLE_CSC2_MASK) - ctrl |= PXP_CTRL_ENABLE_CSC2_MASK; -#endif -#if defined(PXP_CTRL_ENABLE_LUT_MASK) - ctrl |= PXP_CTRL_ENABLE_LUT_MASK; -#endif -#if defined(PXP_CTRL_ENABLE_PS_AS_OUT_MASK) - ctrl |= PXP_CTRL_ENABLE_PS_AS_OUT_MASK; -#endif - - base->CTRL = ctrl; -} - -/*! - * brief Initialize the PXP. - * - * This function enables the PXP peripheral clock, and resets the PXP registers - * to default status. - * - * param base PXP peripheral base address. - */ -void PXP_Init(PXP_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = PXP_GetInstance(base); - CLOCK_EnableClock(s_pxpClocks[instance]); -#endif - - PXP_ResetToInit(base); -} - -/*! - * brief De-initialize the PXP. - * - * This function disables the PXP peripheral clock. - * - * param base PXP peripheral base address. - */ -void PXP_Deinit(PXP_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - uint32_t instance = PXP_GetInstance(base); - CLOCK_DisableClock(s_pxpClocks[instance]); -#endif -} - -/*! - * brief Reset the PXP. - * - * This function resets the PXP peripheral registers to default status. - * - * param base PXP peripheral base address. - */ -void PXP_Reset(PXP_Type *base) -{ - base->CTRL_SET = PXP_CTRL_SFTRST_MASK; - base->CTRL_CLR = (PXP_CTRL_SFTRST_MASK | PXP_CTRL_CLKGATE_MASK); -} - -/*! - * brief Set the alpha surface input buffer configuration. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetAlphaSurfaceBufferConfig(PXP_Type *base, const pxp_as_buffer_config_t *config) -{ - assert(NULL != config); - - base->AS_CTRL = (base->AS_CTRL & ~PXP_AS_CTRL_FORMAT_MASK) | PXP_AS_CTRL_FORMAT(config->pixelFormat); - - base->AS_BUF = config->bufferAddr; - base->AS_PITCH = config->pitchBytes; -} - -/*! - * brief Set the alpha surface blending configuration. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration structure. - */ -void PXP_SetAlphaSurfaceBlendConfig(PXP_Type *base, const pxp_as_blend_config_t *config) -{ - assert(NULL != config); - uint32_t reg; - - reg = base->AS_CTRL; - reg &= - ~(PXP_AS_CTRL_ALPHA0_INVERT_MASK | PXP_AS_CTRL_ROP_MASK | PXP_AS_CTRL_ALPHA_MASK | PXP_AS_CTRL_ALPHA_CTRL_MASK); - reg |= (PXP_AS_CTRL_ROP(config->ropMode) | PXP_AS_CTRL_ALPHA(config->alpha) | - PXP_AS_CTRL_ALPHA_CTRL(config->alphaMode)); - - if (config->invertAlpha) - { - reg |= PXP_AS_CTRL_ALPHA0_INVERT_MASK; - } - - base->AS_CTRL = reg; -} - -/*! - * brief Set the alpha surface position in output buffer. - * - * param base PXP peripheral base address. - * param upperLeftX X of the upper left corner. - * param upperLeftY Y of the upper left corner. - * param lowerRightX X of the lower right corner. - * param lowerRightY Y of the lower right corner. - */ -void PXP_SetAlphaSurfacePosition( - PXP_Type *base, uint16_t upperLeftX, uint16_t upperLeftY, uint16_t lowerRightX, uint16_t lowerRightY) -{ - base->OUT_AS_ULC = PXP_OUT_AS_ULC_Y(upperLeftY) | PXP_OUT_AS_ULC_X(upperLeftX); - base->OUT_AS_LRC = PXP_OUT_AS_LRC_Y(lowerRightY) | PXP_OUT_AS_LRC_X(lowerRightX); -} - -/*! - * brief Set the alpha surface overlay color key. - * - * If a pixel in the current overlay image with a color that falls in the range - * from the p colorKeyLow to p colorKeyHigh range, it will use the process surface - * pixel value for that location. If no PS image is present or if the PS image also - * matches its colorkey range, the PS background color is used. - * - * param base PXP peripheral base address. - * param colorKeyLow Color key low range. - * param colorKeyHigh Color key high range. - * - * note Colorkey operations are higher priority than alpha or ROP operations - */ -void PXP_SetAlphaSurfaceOverlayColorKey(PXP_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh) -{ - base->AS_CLRKEYLOW = colorKeyLow; - base->AS_CLRKEYHIGH = colorKeyHigh; -} - -/*! - * brief Set the process surface input buffer configuration. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetProcessSurfaceBufferConfig(PXP_Type *base, const pxp_ps_buffer_config_t *config) -{ - assert(NULL != config); - - base->PS_CTRL = ((base->PS_CTRL & ~(PXP_PS_CTRL_FORMAT_MASK | PXP_PS_CTRL_WB_SWAP_MASK)) | - PXP_PS_CTRL_FORMAT(config->pixelFormat) | PXP_PS_CTRL_WB_SWAP(config->swapByte)); - - base->PS_BUF = config->bufferAddr; - base->PS_UBUF = config->bufferAddrU; - base->PS_VBUF = config->bufferAddrV; - base->PS_PITCH = config->pitchBytes; -} - -/*! - * brief Set the process surface scaler configuration. - * - * The valid down scale fact is 1/(2^12) ~ 16. - * - * param base PXP peripheral base address. - * param inputWidth Input image width. - * param inputHeight Input image height. - * param outputWidth Output image width. - * param outputHeight Output image height. - */ -void PXP_SetProcessSurfaceScaler( - PXP_Type *base, uint16_t inputWidth, uint16_t inputHeight, uint16_t outputWidth, uint16_t outputHeight) -{ - uint8_t decX, decY; - uint32_t scaleX, scaleY; - - PXP_GetScalerParam(inputWidth, outputWidth, &decX, &scaleX); - PXP_GetScalerParam(inputHeight, outputHeight, &decY, &scaleY); - - base->PS_CTRL = (base->PS_CTRL & ~(PXP_PS_CTRL_DECX_MASK | PXP_PS_CTRL_DECY_MASK)) | PXP_PS_CTRL_DECX(decX) | - PXP_PS_CTRL_DECY(decY); - - base->PS_SCALE = PXP_PS_SCALE_XSCALE(scaleX) | PXP_PS_SCALE_YSCALE(scaleY); -} - -/*! - * brief Set the process surface position in output buffer. - * - * param base PXP peripheral base address. - * param upperLeftX X of the upper left corner. - * param upperLeftY Y of the upper left corner. - * param lowerRightX X of the lower right corner. - * param lowerRightY Y of the lower right corner. - */ -void PXP_SetProcessSurfacePosition( - PXP_Type *base, uint16_t upperLeftX, uint16_t upperLeftY, uint16_t lowerRightX, uint16_t lowerRightY) -{ - base->OUT_PS_ULC = PXP_OUT_PS_ULC_Y(upperLeftY) | PXP_OUT_PS_ULC_X(upperLeftX); - base->OUT_PS_LRC = PXP_OUT_PS_LRC_Y(lowerRightY) | PXP_OUT_PS_LRC_X(lowerRightX); -} - -/*! - * brief Set the process surface color key. - * - * If the PS image matches colorkey range, the PS background color is output. Set - * p colorKeyLow to 0xFFFFFFFF and p colorKeyHigh to 0 will disable the colorkeying. - * - * param base PXP peripheral base address. - * param colorKeyLow Color key low range. - * param colorKeyHigh Color key high range. - */ -void PXP_SetProcessSurfaceColorKey(PXP_Type *base, uint32_t colorKeyLow, uint32_t colorKeyHigh) -{ - base->PS_CLRKEYLOW = colorKeyLow; - base->PS_CLRKEYHIGH = colorKeyHigh; -} - -/*! - * brief Set the PXP outpt buffer configuration. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetOutputBufferConfig(PXP_Type *base, const pxp_output_buffer_config_t *config) -{ - assert(NULL != config); - - base->OUT_CTRL = (base->OUT_CTRL & ~(PXP_OUT_CTRL_FORMAT_MASK | PXP_OUT_CTRL_INTERLACED_OUTPUT_MASK)) | - PXP_OUT_CTRL_FORMAT(config->pixelFormat) | PXP_OUT_CTRL_INTERLACED_OUTPUT(config->interlacedMode); - - base->OUT_BUF = config->buffer0Addr; - base->OUT_BUF2 = config->buffer1Addr; - - base->OUT_PITCH = config->pitchBytes; - base->OUT_LRC = PXP_OUT_LRC_Y((uint32_t)config->height - 1U) | PXP_OUT_LRC_X((uint32_t)config->width - 1U); - -/* - * The dither store size must be set to the same with the output buffer size, - * otherwise the dither engine could not work. - */ -#if defined(PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH_MASK) - base->DITHER_STORE_SIZE_CH0 = PXP_DITHER_STORE_SIZE_CH0_OUT_WIDTH(config->width - 1U) | - PXP_DITHER_STORE_SIZE_CH0_OUT_HEIGHT(config->height - 1U); -#endif -} - -/*! - * brief Set the next command. - * - * The PXP supports a primitive ability to queue up one operation while the current - * operation is running. Workflow: - * - * 1. Prepare the PXP register values except STAT, CSCCOEFn, NEXT in the memory - * in the order they appear in the register map. - * 2. Call this function sets the new operation to PXP. - * 3. There are two methods to check whether the PXP has loaded the new operation. - * The first method is using ref PXP_IsNextCommandPending. If there is new operation - * not loaded by the PXP, this function returns true. The second method is checking - * the flag ref kPXP_CommandLoadFlag, if command loaded, this flag asserts. User - * could enable interrupt ref kPXP_CommandLoadInterruptEnable to get the loaded - * signal in interrupt way. - * 4. When command loaded by PXP, a new command could be set using this function. - * - * param base PXP peripheral base address. - * param commandAddr Address of the new command. - */ -void PXP_SetNextCommand(PXP_Type *base, void *commandAddr) -{ - pxp_pvoid_u32_t addr; - - /* Make sure commands have been saved to memory. */ - __DSB(); - - addr.pvoid = commandAddr; - - base->NEXT = addr.u32 & PXP_NEXT_POINTER_MASK; -} - -#if !(defined(FSL_FEATURE_PXP_HAS_NO_CSC2) && FSL_FEATURE_PXP_HAS_NO_CSC2) -/*! - * brief Set the CSC2 configuration. - * - * The CSC2 module receives pixels in any color space and can convert the pixels - * into any of RGB, YUV, or YCbCr color spaces. The output pixels are passed - * onto the LUT and rotation engine for further processing - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetCsc2Config(PXP_Type *base, const pxp_csc2_config_t *config) -{ - assert(NULL != config); - - base->CSC2_CTRL = (base->CSC2_CTRL & ~PXP_CSC2_CTRL_CSC_MODE_MASK) | PXP_CSC2_CTRL_CSC_MODE(config->mode); - - base->CSC2_COEF0 = - (PXP_ConvertFloat(config->A1, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF0_A1_SHIFT) | - (PXP_ConvertFloat(config->A2, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF0_A2_SHIFT); - - base->CSC2_COEF1 = - (PXP_ConvertFloat(config->A3, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF1_A3_SHIFT) | - (PXP_ConvertFloat(config->B1, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF1_B1_SHIFT); - - base->CSC2_COEF2 = - (PXP_ConvertFloat(config->B2, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF2_B2_SHIFT) | - (PXP_ConvertFloat(config->B3, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF2_B3_SHIFT); - - base->CSC2_COEF3 = - (PXP_ConvertFloat(config->C1, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF3_C1_SHIFT) | - (PXP_ConvertFloat(config->C2, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF3_C2_SHIFT); - - base->CSC2_COEF4 = - (PXP_ConvertFloat(config->C3, PXP_CSC2_COEF_INT_WIDTH, PXP_CSC2_COEF_FRAC_WIDTH) << PXP_CSC2_COEF4_C3_SHIFT) | - PXP_CSC2_COEF4_D1(config->D1); - - base->CSC2_COEF5 = PXP_CSC2_COEF5_D2(config->D2) | PXP_CSC2_COEF5_D3(config->D3); -} -#endif - -/*! - * brief Set the CSC1 mode. - * - * The CSC1 module receives scaled YUV/YCbCr444 pixels from the scale engine and - * converts the pixels to the RGB888 color space. It could only be used by process - * surface. - * - * param base PXP peripheral base address. - * param mode The conversion mode. - */ -void PXP_SetCsc1Mode(PXP_Type *base, pxp_csc1_mode_t mode) -{ - /* - * The equations used for Colorspace conversion are: - * - * R = C0*(Y+Y_OFFSET) + C1(V+UV_OFFSET) - * G = C0*(Y+Y_OFFSET) + C3(U+UV_OFFSET) + C2(V+UV_OFFSET) - * B = C0*(Y+Y_OFFSET) + C4(U+UV_OFFSET) - */ - - if (kPXP_Csc1YUV2RGB == mode) - { - base->CSC1_COEF0 = (base->CSC1_COEF0 & ~(PXP_CSC1_COEF0_C0_MASK | PXP_CSC1_COEF0_Y_OFFSET_MASK | - PXP_CSC1_COEF0_UV_OFFSET_MASK | PXP_CSC1_COEF0_YCBCR_MODE_MASK)) | - PXP_CSC1_COEF0_C0(0x100U) /* 1.00. */ - | PXP_CSC1_COEF0_Y_OFFSET(0x0U) /* 0. */ - | PXP_CSC1_COEF0_UV_OFFSET(0x0U); /* 0. */ - base->CSC1_COEF1 = PXP_CSC1_COEF1_C1(0x0123U) /* 1.140. */ - | PXP_CSC1_COEF1_C4(0x0208U); /* 2.032. */ - base->CSC1_COEF2 = PXP_CSC1_COEF2_C2(0x076BU) /* -0.851. */ - | PXP_CSC1_COEF2_C3(0x079BU); /* -0.394. */ - } - else - { - base->CSC1_COEF0 = (base->CSC1_COEF0 & - ~(PXP_CSC1_COEF0_C0_MASK | PXP_CSC1_COEF0_Y_OFFSET_MASK | PXP_CSC1_COEF0_UV_OFFSET_MASK)) | - PXP_CSC1_COEF0_YCBCR_MODE_MASK | PXP_CSC1_COEF0_C0(0x12AU) /* 1.164. */ - | PXP_CSC1_COEF0_Y_OFFSET(0x1F0U) /* -16. */ - | PXP_CSC1_COEF0_UV_OFFSET(0x180U); /* -128. */ - base->CSC1_COEF1 = PXP_CSC1_COEF1_C1(0x0198U) /* 1.596. */ - | PXP_CSC1_COEF1_C4(0x0204U); /* 2.017. */ - base->CSC1_COEF2 = PXP_CSC1_COEF2_C2(0x0730U) /* -0.813. */ - | PXP_CSC1_COEF2_C3(0x079CU); /* -0.392. */ - } -} - -#if !(defined(FSL_FEATURE_PXP_HAS_NO_LUT) && FSL_FEATURE_PXP_HAS_NO_LUT) -/*! - * brief Set the LUT configuration. - * - * The lookup table (LUT) is used to modify pixels in a manner that is not linear - * and that cannot be achieved by the color space conversion modules. To setup - * the LUT, the complete workflow is: - * 1. Use ref PXP_SetLutConfig to set the configuration, such as the lookup mode. - * 2. Use ref PXP_LoadLutTable to load the lookup table to PXP. - * 3. Use ref PXP_EnableLut to enable the function. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetLutConfig(PXP_Type *base, const pxp_lut_config_t *config) -{ - base->LUT_CTRL = (base->LUT_CTRL & ~(PXP_LUT_CTRL_OUT_MODE_MASK | PXP_LUT_CTRL_LOOKUP_MODE_MASK)) | - PXP_LUT_CTRL_LRU_UPD_MASK | /* Use Least Recently Used Policy Update Control. */ - PXP_LUT_CTRL_OUT_MODE(config->outMode) | PXP_LUT_CTRL_LOOKUP_MODE(config->lookupMode); - - if (kPXP_LutOutRGBW4444CFA == config->outMode) - { - base->CFA = config->cfaValue; - } -} - -/*! - * brief Set the look up table to PXP. - * - * If lookup mode is DIRECT mode, this function loads p bytesNum of values - * from the address p memAddr into PXP LUT address p lutStartAddr. So this - * function allows only update part of the PXP LUT. - * - * If lookup mode is CACHE mode, this function sets the new address to p memAddr - * and invalid the PXP LUT cache. - * - * param base PXP peripheral base address. - * param lookupMode Which lookup mode is used. Note that this parameter is only - * used to distinguish DIRECT mode and CACHE mode, it does not change the register - * value PXP_LUT_CTRL[LOOKUP_MODE]. To change that value, use function ref PXP_SetLutConfig. - * param bytesNum How many bytes to set. This value must be divisable by 8. - * param memAddr Address of look up table to set. - * param lutStartAddr The LUT value will be loaded to LUT from index lutAddr. It should - * be 8 bytes aligned. - * - * retval kStatus_Success Load successfully. - * retval kStatus_InvalidArgument Failed because of invalid argument. - */ -status_t PXP_LoadLutTable( - PXP_Type *base, pxp_lut_lookup_mode_t lookupMode, uint32_t bytesNum, uint32_t memAddr, uint16_t lutStartAddr) -{ - if (kPXP_LutCacheRGB565 == lookupMode) - { - /* Make sure the previous memory write is finished, especially the LUT data memory. */ - __DSB(); - - base->LUT_EXTMEM = memAddr; - /* Invalid cache. */ - base->LUT_CTRL |= PXP_LUT_CTRL_INVALID_MASK; - } - else - { - /* Number of bytes must be divisable by 8. */ - if ((bytesNum & 0x07U) || (bytesNum < 8U) || (lutStartAddr & 0x07U) || - (bytesNum + lutStartAddr > PXP_LUT_TABLE_BYTE)) - { - return kStatus_InvalidArgument; - } - - base->LUT_EXTMEM = memAddr; - base->LUT_ADDR = PXP_LUT_ADDR_ADDR(lutStartAddr) | PXP_LUT_ADDR_NUM_BYTES(bytesNum); - - base->STAT_CLR = PXP_STAT_LUT_DMA_LOAD_DONE_IRQ_MASK; - - /* Start DMA transfer. */ - base->LUT_CTRL |= PXP_LUT_CTRL_DMA_START_MASK; - - __DSB(); - - /* Wait for transfer completed. */ - while (!(base->STAT & PXP_STAT_LUT_DMA_LOAD_DONE_IRQ_MASK)) - { - } - } - - return kStatus_Success; -} -#endif /* FSL_FEATURE_PXP_HAS_NO_LUT */ - -#if (defined(FSL_FEATURE_PXP_HAS_DITHER) && FSL_FEATURE_PXP_HAS_DITHER) -/*! - * brief Write data to the PXP internal memory. - * - * param base PXP peripheral base address. - * param ram Which internal memory to write. - * param bytesNum How many bytes to write. - * param data Pointer to the data to write. - * param memStartAddr The start address in the internal memory to write the data. - */ -void PXP_SetInternalRamData(PXP_Type *base, pxp_ram_t ram, uint32_t bytesNum, uint8_t *data, uint16_t memStartAddr) -{ - assert((memStartAddr + bytesNum) <= PXP_INTERNAL_RAM_LUT_BYTE); - - base->INIT_MEM_CTRL = - PXP_INIT_MEM_CTRL_ADDR(memStartAddr) | PXP_INIT_MEM_CTRL_SELECT(ram) | PXP_INIT_MEM_CTRL_START_MASK; - - while (bytesNum--) - { - base->INIT_MEM_DATA = (uint32_t)(*data); - data++; - } - - base->INIT_MEM_CTRL = 0U; -} - -/*! - * brief Set the dither final LUT data. - * - * The dither final LUT is only applicble to dither engine 0. It takes the bits[7:4] - * of the output pixel and looks up and 8 bit value from the 16 value LUT to generate - * the final output pixel to the next process module. - * - * param base PXP peripheral base address. - * param data Pointer to the LUT data to set. - */ -void PXP_SetDitherFinalLutData(PXP_Type *base, const pxp_dither_final_lut_data_t *data) -{ - base->DITHER_FINAL_LUT_DATA0 = data->data_3_0; - base->DITHER_FINAL_LUT_DATA1 = data->data_7_4; - base->DITHER_FINAL_LUT_DATA2 = data->data_11_8; - base->DITHER_FINAL_LUT_DATA3 = data->data_15_12; -} - -/*! - * brief Enable or disable dither engine in the PXP process path. - * - * After the initialize function ref PXP_Init, the dither engine is disabled and not - * use in the PXP processing path. This function enables the dither engine and - * routes the dither engine output to the output buffer. When the dither engine - * is enabled using this function, ref PXP_SetDitherConfig must be called to - * configure dither engine correctly, otherwise there is not output to the output - * buffer. - * - * param base PXP peripheral base address. - * param enable Pass in true to enable, false to disable. - */ -void PXP_EnableDither(PXP_Type *base, bool enable) -{ - if (enable) - { - base->CTRL_SET = PXP_CTRL_ENABLE_DITHER_MASK; - /* Route dither output to output buffer. */ - base->DATA_PATH_CTRL0 &= ~PXP_DATA_PATH_CTRL0_MUX14_SEL_MASK; - } - else - { - base->CTRL_CLR = PXP_CTRL_ENABLE_DITHER_MASK; - /* Route MUX 12 output to output buffer. */ - base->DATA_PATH_CTRL0 |= PXP_DATA_PATH_CTRL0_MUX14_SEL(1U); - } -} -#endif /* FSL_FEATURE_PXP_HAS_DITHER */ - -/*! - * brief Set the Porter Duff configuration. - * - * param base PXP peripheral base address. - * param config Pointer to the configuration. - */ -void PXP_SetPorterDuffConfig(PXP_Type *base, const pxp_porter_duff_config_t *config) -{ - assert(NULL != config); - - union - { - pxp_porter_duff_config_t pdConfigStruct; - uint32_t u32; - } pdConfig; - - pdConfig.pdConfigStruct = *config; - - base->PORTER_DUFF_CTRL = pdConfig.u32; -} - -/*! - * brief Get the Porter Duff configuration by blend mode. - * - * param mode The blend mode. - * param config Pointer to the configuration. - * retval kStatus_Success Successfully get the configuratoin. - * retval kStatus_InvalidArgument The blend mode not supported. - */ -status_t PXP_GetPorterDuffConfig(pxp_porter_duff_blend_mode_t mode, pxp_porter_duff_config_t *config) -{ - status_t status; - - union - { - pxp_porter_duff_config_t pdConfigStruct; - uint32_t u32; - } pdConfig; - - static const uint32_t pdCtrl[] = { - /* kPXP_PorterDuffSrc */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorOne) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorZero), - - /* kPXP_PorterDuffAtop */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorStraight) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorInversed), - - /* kPXP_PorterDuffOver */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorOne) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorInversed), - - /* kPXP_PorterDuffIn */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorStraight) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorZero), - - /* kPXP_PorterDuffOut */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorInversed) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorZero), - - /* kPXP_PorterDuffDst */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorZero) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorOne), - - /* kPXP_PorterDuffDstAtop */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorInversed) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorStraight), - - /* kPXP_PorterDuffDstOver */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorInversed) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorOne), - - /* kPXP_PorterDuffDstIn */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorZero) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorStraight), - - /* kPXP_PorterDuffDstOut */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorZero) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorInversed), - - /* kPXP_PorterDuffXor */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorInversed) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorInversed), - - /* kPXP_PorterDuffClear */ - PXP_PORTER_DUFF_CTRL_POTER_DUFF_ENABLE_MASK | - PXP_PORTER_DUFF_CTRL_S0_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S1_GLOBAL_ALPHA_MODE(kPXP_PorterDuffLocalAlpha) | - PXP_PORTER_DUFF_CTRL_S0_S1_FACTOR_MODE(kPXP_PorterDuffFactorZero) | - PXP_PORTER_DUFF_CTRL_S1_S0_FACTOR_MODE(kPXP_PorterDuffFactorZero), - }; - - if (mode >= kPXP_PorterDuffMax) - { - status = kStatus_InvalidArgument; - } - else - { - pdConfig.u32 = pdCtrl[(uint32_t)mode]; - - *config = pdConfig.pdConfigStruct; - - status = kStatus_Success; - } - - return status; -} - -static void PXP_StartRectCopy(PXP_Type *base, - uint32_t srcAddr, - uint16_t srcPitchBytes, - uint32_t destAddr, - uint16_t destPitchBytes, - uint16_t width, - uint16_t height, - pxp_as_pixel_format_t pixelFormat) -{ - pxp_output_buffer_config_t outputBufferConfig; - pxp_as_buffer_config_t asBufferConfig; - uint32_t intMask; - -#if !(defined(FSL_FEATURE_PXP_HAS_NO_LUT) && FSL_FEATURE_PXP_HAS_NO_LUT) - intMask = - base->CTRL & (PXP_CTRL_NEXT_IRQ_ENABLE_MASK | PXP_CTRL_IRQ_ENABLE_MASK | PXP_CTRL_LUT_DMA_IRQ_ENABLE_MASK); -#else - intMask = base->CTRL & (PXP_CTRL_NEXT_IRQ_ENABLE_MASK | PXP_CTRL_IRQ_ENABLE_MASK); -#endif - - PXP_ResetToInit(base); - - /* Restore previous interrupt configuration. */ - PXP_EnableInterrupts(base, intMask); - - /* Disable PS */ - PXP_SetProcessSurfacePosition(base, 0xFFFFU, 0xFFFFU, 0U, 0U); - - /* Input buffer. */ - asBufferConfig.pixelFormat = pixelFormat; - asBufferConfig.bufferAddr = srcAddr; - asBufferConfig.pitchBytes = srcPitchBytes; - - PXP_SetAlphaSurfaceBufferConfig(base, &asBufferConfig); - PXP_SetAlphaSurfacePosition(base, 0U, 0U, width - 1U, height - 1U); - - /* Alpha mode set to ROP, AS OR PS*/ - const pxp_as_blend_config_t asBlendConfig = { - .alpha = 0U, .invertAlpha = false, .alphaMode = kPXP_AlphaRop, .ropMode = kPXP_RopMergeAs}; - - PXP_SetAlphaSurfaceBlendConfig(base, &asBlendConfig); - - /* Output buffer. */ - outputBufferConfig.pixelFormat = (pxp_output_pixel_format_t)pixelFormat; - outputBufferConfig.interlacedMode = kPXP_OutputProgressive; - outputBufferConfig.buffer0Addr = destAddr; - outputBufferConfig.buffer1Addr = 0U; - outputBufferConfig.pitchBytes = destPitchBytes; - outputBufferConfig.width = width; - outputBufferConfig.height = height; - - PXP_SetOutputBufferConfig(base, &outputBufferConfig); - - PXP_ClearStatusFlags(base, (uint32_t)kPXP_CompleteFlag); - - PXP_Start(base); -} - -/*! - * brief Copy picture from one buffer to another buffer. - * - * This function copies a rectangle from one buffer to another buffer. - * - * param base PXP peripheral base address. - * retval kStatus_Success Successfully started the copy process. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t PXP_StartPictureCopy(PXP_Type *base, const pxp_pic_copy_config_t *config) -{ - uint8_t bytePerPixel; - uint32_t copyFromAddr; - uint32_t copyToAddr; - - if ((0U == config->height) || (0U == config->width)) - { - return kStatus_InvalidArgument; - } - - if ((config->pixelFormat == kPXP_AsPixelFormatARGB8888) || (config->pixelFormat == kPXP_AsPixelFormatRGB888)) - { - bytePerPixel = 4U; - } - else - { - bytePerPixel = 2U; - } - - copyFromAddr = config->srcPicBaseAddr + ((uint32_t)config->srcOffsetY * (uint32_t)config->srcPitchBytes) + - bytePerPixel * config->srcOffsetX; - copyToAddr = config->destPicBaseAddr + ((uint32_t)config->destOffsetY * (uint32_t)config->destPitchBytes) + - bytePerPixel * config->destOffsetX; - - PXP_StartRectCopy(base, copyFromAddr, config->srcPitchBytes, copyToAddr, config->destPitchBytes, config->width, - config->height, config->pixelFormat); - - return kStatus_Success; -} - -/*! - * brief Copy continous memory. - * - * The copy size should be 512 byte aligned. - * - * param base PXP peripheral base address. - * retval kStatus_Success Successfully started the copy process. - * retval kStatus_InvalidArgument Invalid argument. - */ -status_t PXP_StartMemCopy(PXP_Type *base, uint32_t srcAddr, uint32_t destAddr, uint32_t size) -{ - uint16_t pitchBytes; - uint32_t height; - - if ((0U == size) || ((size % 512U) != 0U)) - { - return kStatus_InvalidArgument; - } - - /* - * By default, PXP process block is 8x8. For better performance, choose - * width and height dividable by block size. - */ - if (size < 8U * 512U) - { - height = 8U; - pitchBytes = (uint16_t)(size / height); - } - else - { - pitchBytes = 512U; - height = size / pitchBytes; - } - - if (height > PXP_MAX_HEIGHT) - { - return kStatus_InvalidArgument; - } - - PXP_StartRectCopy(base, srcAddr, pitchBytes, destAddr, pitchBytes, pitchBytes / 4U, (uint16_t)height, - kPXP_AsPixelFormatARGB8888); - - return kStatus_Success; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_qtmr.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_qtmr.c deleted file mode 100644 index f96e5504be..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_qtmr.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright 2017-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_qtmr.h" -#ifdef __rtems__ -#include <bsp.h> -#include <bsp/irq.h> -#include <libfdt.h> -#endif /* __rtems__ */ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.qtmr" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Gets the instance from the base address to be used to gate or ungate the module clock - * - * @param base Quad Timer peripheral base address - * - * @return The Quad Timer instance - */ -static uint32_t QTMR_GetInstance(TMR_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to Quad Timer bases for each instance. */ -static TMR_Type *const s_qtmrBases[] = TMR_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to Quad Timer clocks for each instance. */ -static const clock_ip_name_t s_qtmrClocks[] = TMR_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t QTMR_GetInstance(TMR_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_qtmrBases); instance++) - { - if (s_qtmrBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_qtmrBases)); - - return instance; -} - -#ifdef __rtems__ -TMR_Type *QTMR_get_regs_from_fdt(const void *fdt, int node) -{ - int rv; - TMR_Type *regs; - - rv = fdt_node_check_compatible(fdt, node, "nxp,imxrt-qtimer"); - if (rv != 0) { - return NULL; - } - regs = imx_get_reg_of_node(fdt, node); - return regs; -} - -rtems_vector_number QTMR_get_IRQ_from_fdt(const void *fdt, int node) -{ - int rv; - rtems_vector_number irq; - - rv = fdt_node_check_compatible(fdt, node, "nxp,imxrt-qtimer"); - if (rv != 0) { - return BSP_INTERRUPT_VECTOR_INVALID; - } - irq = imx_get_irq_of_node(fdt, node, 0); - return irq; -} - -uint32_t QTMR_get_src_clk(TMR_Type *base) -{ - (void) base; - - return CLOCK_GetFreq(kCLOCK_IpgClk); -} - -#endif /* __rtems__ */ -/*! - * brief Ungates the Quad Timer clock and configures the peripheral for basic operation. - * - * note This API should be called at the beginning of the application using the Quad Timer driver. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param config Pointer to user's Quad Timer config structure - */ -void QTMR_Init(TMR_Type *base, qtmr_channel_selection_t channel, const qtmr_config_t *config) -{ - assert(NULL != config); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the module clock */ - CLOCK_EnableClock(s_qtmrClocks[QTMR_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Setup the counter sources */ - base->CHANNEL[channel].CTRL = (TMR_CTRL_PCS(config->primarySource) | TMR_CTRL_SCS(config->secondarySource)); - - /* Setup the master mode operation */ - base->CHANNEL[channel].SCTRL = - (TMR_SCTRL_EEOF(config->enableExternalForce) | TMR_SCTRL_MSTR(config->enableMasterMode)); - - /* Setup debug mode */ - base->CHANNEL[channel].CSCTRL = TMR_CSCTRL_DBG_EN(config->debugMode); - - base->CHANNEL[channel].FILT &= (uint16_t)(~(TMR_FILT_FILT_CNT_MASK | TMR_FILT_FILT_PER_MASK)); - /* Setup input filter */ - base->CHANNEL[channel].FILT = - (TMR_FILT_FILT_CNT(config->faultFilterCount) | TMR_FILT_FILT_PER(config->faultFilterPeriod)); -} - -/*! - * brief Stops the counter and gates the Quad Timer clock - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - */ -void QTMR_Deinit(TMR_Type *base, qtmr_channel_selection_t channel) -{ - /* Stop the counter */ - base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK); - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the module clock */ - CLOCK_DisableClock(s_qtmrClocks[QTMR_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Fill in the Quad Timer config struct with the default settings - * - * The default values are: - * code - * config->debugMode = kQTMR_RunNormalInDebug; - * config->enableExternalForce = false; - * config->enableMasterMode = false; - * config->faultFilterCount = 0; - * config->faultFilterPeriod = 0; - * config->primarySource = kQTMR_ClockDivide_2; - * config->secondarySource = kQTMR_Counter0InputPin; - * endcode - * param config Pointer to user's Quad Timer config structure. - */ -void QTMR_GetDefaultConfig(qtmr_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - /* Halt counter during debug mode */ - config->debugMode = kQTMR_RunNormalInDebug; - /* Another counter cannot force state of OFLAG signal */ - config->enableExternalForce = false; - /* Compare function's output from this counter is not broadcast to other counters */ - config->enableMasterMode = false; - /* Fault filter count is set to 0 */ - config->faultFilterCount = 0; - /* Fault filter period is set to 0 which disables the fault filter */ - config->faultFilterPeriod = 0; - /* Primary count source is IP bus clock divide by 2 */ - config->primarySource = kQTMR_ClockDivide_2; - /* Secondary count source is counter 0 input pin */ - config->secondarySource = kQTMR_Counter0InputPin; -} - -/*! - * brief Sets up Quad timer module for PWM signal output. - * - * The function initializes the timer module according to the parameters passed in by the user. The - * function also sets up the value compare registers to match the PWM signal requirements. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param pwmFreqHz PWM signal frequency in Hz - * param dutyCyclePercent PWM pulse width, value should be between 0 to 100 - * 0=inactive signal(0% duty cycle)... - * 100=active signal (100% duty cycle) - * param outputPolarity true: invert polarity of the output signal, false: no inversion - * param srcClock_Hz Main counter clock in Hz. - * - * return Returns an error if there was error setting up the signal. - */ -status_t QTMR_SetupPwm(TMR_Type *base, - qtmr_channel_selection_t channel, - uint32_t pwmFreqHz, - uint8_t dutyCyclePercent, - bool outputPolarity, - uint32_t srcClock_Hz) -{ - uint32_t periodCount, highCount, lowCount; - uint16_t reg; - status_t status; - - if (dutyCyclePercent <= 100U) - { - /* Set OFLAG pin for output mode and force out a low on the pin */ - base->CHANNEL[channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK); - - /* Counter values to generate a PWM signal */ - periodCount = srcClock_Hz / pwmFreqHz; - highCount = periodCount * dutyCyclePercent / 100U; - lowCount = periodCount - highCount; - - if (highCount > 0U) - { - highCount -= 1U; - } - if (lowCount > 0U) - { - lowCount -= 1U; - } - - /* This should not be a 16-bit overflow value. If it is, change to a larger divider for clock source. */ - assert(highCount <= 0xFFFFU); - assert(lowCount <= 0xFFFFU); - - /* Setup the compare registers for PWM output */ - base->CHANNEL[channel].COMP1 = (uint16_t)lowCount; - base->CHANNEL[channel].COMP2 = (uint16_t)highCount; - - /* Setup the pre-load registers for PWM output */ - base->CHANNEL[channel].CMPLD1 = (uint16_t)lowCount; - base->CHANNEL[channel].CMPLD2 = (uint16_t)highCount; - - reg = base->CHANNEL[channel].CSCTRL; - /* Setup the compare load control for COMP1 and COMP2. - * Load COMP1 when CSCTRL[TCF2] is asserted, load COMP2 when CSCTRL[TCF1] is asserted - */ - reg &= (uint16_t)(~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK)); - reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1)); - base->CHANNEL[channel].CSCTRL = reg; - - if (outputPolarity) - { - /* Invert the polarity */ - base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OPS_MASK; - } - else - { - /* True polarity, no inversion */ - base->CHANNEL[channel].SCTRL &= ~(uint16_t)TMR_SCTRL_OPS_MASK; - } - - reg = base->CHANNEL[channel].CTRL; - reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK; - /* Count until compare value is reached and re-initialize the counter, toggle OFLAG output - * using alternating compare register - */ - reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg)); - base->CHANNEL[channel].CTRL = reg; - - status = kStatus_Success; - } - else - { - /* Invalid dutycycle */ - status = kStatus_Fail; - } - - return status; -} - -/*! - * brief Allows the user to count the source clock cycles until a capture event arrives. - * - * The count is stored in the capture register. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param capturePin Pin through which we receive the input signal to trigger the capture - * param inputPolarity true: invert polarity of the input signal, false: no inversion - * param reloadOnCapture true: reload the counter when an input capture occurs, false: no reload - * param captureMode Specifies which edge of the input signal triggers a capture - */ -void QTMR_SetupInputCapture(TMR_Type *base, - qtmr_channel_selection_t channel, - qtmr_input_source_t capturePin, - bool inputPolarity, - bool reloadOnCapture, - qtmr_input_capture_edge_t captureMode) -{ - uint16_t reg; - - /* Clear the prior value for the input source for capture */ - reg = base->CHANNEL[channel].CTRL & (uint16_t)(~TMR_CTRL_SCS_MASK); - - /* Set the new input source */ - reg |= TMR_CTRL_SCS(capturePin); - base->CHANNEL[channel].CTRL = reg; - - /* Clear the prior values for input polarity, capture mode. Set the external pin as input */ - reg = base->CHANNEL[channel].SCTRL & - (uint16_t)(~(TMR_SCTRL_IPS_MASK | TMR_SCTRL_CAPTURE_MODE_MASK | TMR_SCTRL_OEN_MASK)); - /* Set the new values */ - reg |= (TMR_SCTRL_IPS(inputPolarity) | TMR_SCTRL_CAPTURE_MODE(captureMode)); - base->CHANNEL[channel].SCTRL = reg; - - /* Setup if counter should reload when a capture occurs */ - if (reloadOnCapture) - { - base->CHANNEL[channel].CSCTRL |= TMR_CSCTRL_ROC_MASK; - } - else - { - base->CHANNEL[channel].CSCTRL &= (uint16_t)(~TMR_CSCTRL_ROC_MASK); - } -} - -/*! - * brief Enables the selected Quad Timer interrupts - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param mask The interrupts to enable. This is a logical OR of members of the - * enumeration ::qtmr_interrupt_enable_t - */ -void QTMR_EnableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) -{ - uint16_t reg; - - reg = base->CHANNEL[channel].SCTRL; - /* Compare interrupt */ - if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL) - { - reg |= TMR_SCTRL_TCFIE_MASK; - } - /* Overflow interrupt */ - if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL) - { - reg |= TMR_SCTRL_TOFIE_MASK; - } - /* Input edge interrupt */ - if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL) - { - /* Restriction: Do not set both SCTRL[IEFIE] and DMA[IEFDE] */ - base->CHANNEL[channel].DMA &= ~(uint16_t)TMR_DMA_IEFDE_MASK; - reg |= TMR_SCTRL_IEFIE_MASK; - } - base->CHANNEL[channel].SCTRL = reg; - - reg = base->CHANNEL[channel].CSCTRL; - /* Compare 1 interrupt */ - if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL) - { - reg |= TMR_CSCTRL_TCF1EN_MASK; - } - /* Compare 2 interrupt */ - if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL) - { - reg |= TMR_CSCTRL_TCF2EN_MASK; - } - base->CHANNEL[channel].CSCTRL = reg; -} - -/*! - * brief Disables the selected Quad Timer interrupts - * - * param base Quad Timer peripheral base addres - * param channel Quad Timer channel number - * param mask The interrupts to enable. This is a logical OR of members of the - * enumeration ::qtmr_interrupt_enable_t - */ -void QTMR_DisableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) -{ - uint16_t reg; - - reg = base->CHANNEL[channel].SCTRL; - /* Compare interrupt */ - if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL) - { - reg &= (uint16_t)(~TMR_SCTRL_TCFIE_MASK); - } - /* Overflow interrupt */ - if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL) - { - reg &= (uint16_t)(~TMR_SCTRL_TOFIE_MASK); - } - /* Input edge interrupt */ - if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL) - { - reg &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK); - } - base->CHANNEL[channel].SCTRL = reg; - - reg = base->CHANNEL[channel].CSCTRL; - /* Compare 1 interrupt */ - if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL) - { - reg &= ~(uint16_t)TMR_CSCTRL_TCF1EN_MASK; - } - /* Compare 2 interrupt */ - if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL) - { - reg &= ~(uint16_t)TMR_CSCTRL_TCF2EN_MASK; - } - base->CHANNEL[channel].CSCTRL = reg; -} - -/*! - * brief Gets the enabled Quad Timer interrupts - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * - * return The enabled interrupts. This is the logical OR of members of the - * enumeration ::qtmr_interrupt_enable_t - */ -uint32_t QTMR_GetEnabledInterrupts(TMR_Type *base, qtmr_channel_selection_t channel) -{ - uint32_t enabledInterrupts = 0; - uint16_t reg; - - reg = base->CHANNEL[channel].SCTRL; - /* Compare interrupt */ - if ((reg & TMR_SCTRL_TCFIE_MASK) != 0U) - { - enabledInterrupts |= (uint32_t)kQTMR_CompareFlag; - } - /* Overflow interrupt */ - if ((reg & TMR_SCTRL_TOFIE_MASK) != 0U) - { - enabledInterrupts |= (uint32_t)kQTMR_OverflowInterruptEnable; - } - /* Input edge interrupt */ - if ((reg & TMR_SCTRL_IEFIE_MASK) != 0U) - { - enabledInterrupts |= (uint32_t)kQTMR_EdgeInterruptEnable; - } - - reg = base->CHANNEL[channel].CSCTRL; - /* Compare 1 interrupt */ - if ((reg & TMR_CSCTRL_TCF1EN_MASK) != 0U) - { - enabledInterrupts |= (uint32_t)kQTMR_Compare1InterruptEnable; - } - /* Compare 2 interrupt */ - if ((reg & TMR_CSCTRL_TCF2EN_MASK) != 0U) - { - enabledInterrupts |= (uint32_t)kQTMR_Compare2InterruptEnable; - } - - return enabledInterrupts; -} - -/*! - * brief Gets the Quad Timer status flags - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * - * return The status flags. This is the logical OR of members of the - * enumeration ::qtmr_status_flags_t - */ -uint32_t QTMR_GetStatus(TMR_Type *base, qtmr_channel_selection_t channel) -{ - uint32_t statusFlags = 0; - uint16_t reg; - - reg = base->CHANNEL[channel].SCTRL; - /* Timer compare flag */ - if ((reg & TMR_SCTRL_TCF_MASK) != 0U) - { - statusFlags |= (uint32_t)kQTMR_CompareFlag; - } - /* Timer overflow flag */ - if ((reg & TMR_SCTRL_TOF_MASK) != 0U) - { - statusFlags |= (uint32_t)kQTMR_OverflowFlag; - } - /* Input edge flag */ - if ((reg & TMR_SCTRL_IEF_MASK) != 0U) - { - statusFlags |= (uint32_t)kQTMR_EdgeFlag; - } - - reg = base->CHANNEL[channel].CSCTRL; - /* Compare 1 flag */ - if ((reg & TMR_CSCTRL_TCF1_MASK) != 0U) - { - statusFlags |= (uint32_t)kQTMR_Compare1Flag; - } - /* Compare 2 flag */ - if ((reg & TMR_CSCTRL_TCF2_MASK) != 0U) - { - statusFlags |= (uint32_t)kQTMR_Compare2Flag; - } - - return statusFlags; -} - -/*! - * brief Clears the Quad Timer status flags. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param mask The status flags to clear. This is a logical OR of members of the - * enumeration ::qtmr_status_flags_t - */ -void QTMR_ClearStatusFlags(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) -{ - uint16_t reg; - - reg = base->CHANNEL[channel].SCTRL; - /* Timer compare flag */ - if ((mask & (uint32_t)kQTMR_CompareFlag) != 0U) - { - reg &= (uint16_t)(~TMR_SCTRL_TCF_MASK); - } - /* Timer overflow flag */ - if ((mask & (uint32_t)kQTMR_OverflowFlag) != 0U) - { - reg &= (uint16_t)(~TMR_SCTRL_TOF_MASK); - } - /* Input edge flag */ - if ((mask & (uint32_t)kQTMR_EdgeFlag) != 0U) - { - reg &= (uint16_t)(~TMR_SCTRL_IEF_MASK); - } - base->CHANNEL[channel].SCTRL = reg; - - reg = base->CHANNEL[channel].CSCTRL; - /* Compare 1 flag */ - if ((mask & (uint32_t)kQTMR_Compare1Flag) != 0U) - { - reg &= ~(uint16_t)TMR_CSCTRL_TCF1_MASK; - } - /* Compare 2 flag */ - if ((mask & (uint32_t)kQTMR_Compare2Flag) != 0U) - { - reg &= ~(uint16_t)TMR_CSCTRL_TCF2_MASK; - } - base->CHANNEL[channel].CSCTRL = reg; -} - -/*! - * brief Sets the timer period in ticks. - * - * Timers counts from initial value till it equals the count value set here. The counter - * will then reinitialize to the value specified in the Load register. - * - * note - * 1. This function will write the time period in ticks to COMP1 or COMP2 register - * depending on the count direction - * 2. User can call the utility macros provided in fsl_common.h to convert to ticks - * 3. This function supports cases, providing only primary source clock without secondary source clock. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param ticks Timer period in units of ticks - */ -void QTMR_SetTimerPeriod(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks) -{ - /* Set the length bit to reinitialize the counters on a match */ - base->CHANNEL[channel].CTRL |= TMR_CTRL_LENGTH_MASK; - - if ((base->CHANNEL[channel].CTRL & TMR_CTRL_DIR_MASK) != 0U) - { - /* Counting down */ - base->CHANNEL[channel].COMP2 = ticks; - } - else - { - /* Counting up */ - base->CHANNEL[channel].COMP1 = ticks; - } -} - -/*! - * brief Enable the Quad Timer DMA. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param mask The DMA to enable. This is a logical OR of members of the - * enumeration ::qtmr_dma_enable_t - */ -void QTMR_EnableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) -{ - uint16_t reg; - - reg = base->CHANNEL[channel].DMA; - /* Input Edge Flag DMA Enable */ - if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U) - { - /* Restriction: Do not set both DMA[IEFDE] and SCTRL[IEFIE] */ - base->CHANNEL[channel].SCTRL &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK); - reg |= TMR_DMA_IEFDE_MASK; - } - /* Comparator Preload Register 1 DMA Enable */ - if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U) - { - reg |= TMR_DMA_CMPLD1DE_MASK; - } - /* Comparator Preload Register 2 DMA Enable */ - if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U) - { - reg |= TMR_DMA_CMPLD2DE_MASK; - } - base->CHANNEL[channel].DMA = reg; -} - -/*! - * brief Disable the Quad Timer DMA. - * - * param base Quad Timer peripheral base address - * param channel Quad Timer channel number - * param mask The DMA to enable. This is a logical OR of members of the - * enumeration ::qtmr_dma_enable_t - */ -void QTMR_DisableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask) -{ - uint16_t reg; - - reg = base->CHANNEL[channel].DMA; - /* Input Edge Flag DMA Enable */ - if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U) - { - reg &= ~(uint16_t)TMR_DMA_IEFDE_MASK; - } - /* Comparator Preload Register 1 DMA Enable */ - if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U) - { - reg &= ~(uint16_t)TMR_DMA_CMPLD1DE_MASK; - } - /* Comparator Preload Register 2 DMA Enable */ - if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U) - { - reg &= ~(uint16_t)TMR_DMA_CMPLD2DE_MASK; - } - base->CHANNEL[channel].DMA = reg; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_rtwdog.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_rtwdog.c deleted file mode 100644 index 4b49280bf8..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_rtwdog.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_rtwdog.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.rtwdog" -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Clears the RTWDOG flag. - * - * This function clears the RTWDOG status flag. - * - * Example to clear an interrupt flag: - * code - * RTWDOG_ClearStatusFlags(wdog_base,kRTWDOG_InterruptFlag); - * endcode - * param base RTWDOG peripheral base address. - * param mask The status flags to clear. - * The parameter can be any combination of the following values: - * arg kRTWDOG_InterruptFlag - */ -void RTWDOG_ClearStatusFlags(RTWDOG_Type *base, uint32_t mask) -{ - if ((mask & (uint32_t)kRTWDOG_InterruptFlag) != 0U) - { - base->CS |= RTWDOG_CS_FLG_MASK; - } -} - -/*! - * brief Initializes the RTWDOG configuration structure. - * - * This function initializes the RTWDOG configuration structure to default values. The default - * values are: - * code - * rtwdogConfig->enableRtwdog = true; - * rtwdogConfig->clockSource = kRTWDOG_ClockSource1; - * rtwdogConfig->prescaler = kRTWDOG_ClockPrescalerDivide1; - * rtwdogConfig->workMode.enableWait = true; - * rtwdogConfig->workMode.enableStop = false; - * rtwdogConfig->workMode.enableDebug = false; - * rtwdogConfig->testMode = kRTWDOG_TestModeDisabled; - * rtwdogConfig->enableUpdate = true; - * rtwdogConfig->enableInterrupt = false; - * rtwdogConfig->enableWindowMode = false; - * rtwdogConfig->windowValue = 0U; - * rtwdogConfig->timeoutValue = 0xFFFFU; - * endcode - * - * param config Pointer to the RTWDOG configuration structure. - * see rtwdog_config_t - */ -void RTWDOG_GetDefaultConfig(rtwdog_config_t *config) -{ - assert(config != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableRtwdog = true; - config->clockSource = kRTWDOG_ClockSource1; - config->prescaler = kRTWDOG_ClockPrescalerDivide1; - config->workMode.enableWait = true; - config->workMode.enableStop = false; - config->workMode.enableDebug = false; - config->testMode = kRTWDOG_TestModeDisabled; - config->enableUpdate = true; - config->enableInterrupt = false; - config->enableWindowMode = false; - config->windowValue = 0U; - config->timeoutValue = 0xFFFFU; -} - -/*! - * brief Initializes the RTWDOG module. - * - * This function initializes the RTWDOG. - * To reconfigure the RTWDOG without forcing a reset first, enableUpdate must be set to true - * in the configuration. - * - * Example: - * code - * rtwdog_config_t config; - * RTWDOG_GetDefaultConfig(&config); - * config.timeoutValue = 0x7ffU; - * config.enableUpdate = true; - * RTWDOG_Init(wdog_base,&config); - * endcode - * - * param base RTWDOG peripheral base address. - * param config The configuration of the RTWDOG. - */ -void RTWDOG_Init(RTWDOG_Type *base, const rtwdog_config_t *config) -{ - assert(NULL != config); - - uint32_t value = 0U; - uint32_t primaskValue = 0U; - - value = RTWDOG_CS_EN(config->enableRtwdog) | RTWDOG_CS_CLK(config->clockSource) | - RTWDOG_CS_INT(config->enableInterrupt) | RTWDOG_CS_WIN(config->enableWindowMode) | - RTWDOG_CS_UPDATE(config->enableUpdate) | RTWDOG_CS_DBG(config->workMode.enableDebug) | - RTWDOG_CS_STOP(config->workMode.enableStop) | RTWDOG_CS_WAIT(config->workMode.enableWait) | - RTWDOG_CS_PRES(config->prescaler) | RTWDOG_CS_CMD32EN(1U) | RTWDOG_CS_TST(config->testMode); - - /* Disable the global interrupts. Otherwise, an interrupt could effectively invalidate the unlock sequence - * and the WCT may expire. After the configuration finishes, re-enable the global interrupts. */ - primaskValue = DisableGlobalIRQ(); - RTWDOG_Unlock(base); - base->WIN = config->windowValue; - base->TOVAL = config->timeoutValue; - base->CS = value; - while ((base->CS & RTWDOG_CS_RCS_MASK) == 0U) - { - } - EnableGlobalIRQ(primaskValue); -} - -/*! - * brief De-initializes the RTWDOG module. - * - * This function shuts down the RTWDOG. - * Ensure that the WDOG_CS.UPDATE is 1, which means that the register update is enabled. - * - * param base RTWDOG peripheral base address. - */ -void RTWDOG_Deinit(RTWDOG_Type *base) -{ - uint32_t primaskValue = 0U; - - /* Disable the global interrupts */ - primaskValue = DisableGlobalIRQ(); - RTWDOG_Unlock(base); - RTWDOG_Disable(base); - EnableGlobalIRQ(primaskValue); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai.c deleted file mode 100644 index af69595996..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai.c +++ /dev/null @@ -1,3764 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_sai.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.sai" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ -/*! @brief _sai_transfer_state sai transfer state.*/ -enum -{ - kSAI_Busy = 0x0U, /*!< SAI is busy */ - kSAI_Idle, /*!< Transfer is done. */ - kSAI_Error /*!< Transfer error occurred. */ -}; - -/*! @brief Typedef for sai tx interrupt handler. */ -typedef void (*sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle); - -/*! @brief Typedef for sai rx interrupt handler. */ -typedef void (*sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle); - -/*! @brief check flag avalibility */ -#define IS_SAI_FLAG_SET(reg, flag) (((reg) & ((uint32_t)flag)) != 0UL) -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief sai get rx enabled interrupt status. - * - * - * @param base SAI base pointer. - * @param enableFlag enable flag to check. - * @param statusFlag status flag to check. - */ -static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag); - -/*! - * @brief sai get tx enabled interrupt status. - * - * - * @param base SAI base pointer. - * @param enableFlag enable flag to check. - * @param statusFlag status flag to check. - */ -static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag); - -/*! - * @brief Set the master clock divider. - * - * This API will compute the master clock divider according to master clock frequency and master - * clock source clock source frequency. - * - * @param base SAI base pointer. - * @param mclk_Hz Mater clock frequency in Hz. - * @param mclkSrcClock_Hz Master clock source frequency in Hz. - */ -static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag); - -#if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \ - (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV))) - -/*! - * @brief Set the master clock divider. - * - * This API will compute the master clock divider according to master clock frequency and master - * clock source clock source frequency. - * - * @param base SAI base pointer. - * @param mclk_Hz Mater clock frequency in Hz. - * @param mclkSrcClock_Hz Master clock source frequency in Hz. - */ -static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz); -#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ - -/*! - * @brief Get the instance number for SAI. - * - * @param base SAI base pointer. - */ -static uint32_t SAI_GetInstance(I2S_Type *base); - -/*! - * @brief sends a piece of data in non-blocking way. - * - * @param base SAI base pointer - * @param channel start channel number. - * @param channelMask enabled channels mask. - * @param endChannel end channel numbers. - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * @param buffer Pointer to the data to be written. - * @param size Bytes to be written. - */ -static void SAI_WriteNonBlocking(I2S_Type *base, - uint32_t channel, - uint32_t channelMask, - uint32_t endChannel, - uint8_t bitWidth, - uint8_t *buffer, - uint32_t size); - -/*! - * @brief Receive a piece of data in non-blocking way. - * - * @param base SAI base pointer - * @param channel start channel number. - * @param channelMask enabled channels mask. - * @param endChannel end channel numbers. - * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits. - * @param buffer Pointer to the data to be read. - * @param size Bytes to be read. - */ -static void SAI_ReadNonBlocking(I2S_Type *base, - uint32_t channel, - uint32_t channelMask, - uint32_t endChannel, - uint8_t bitWidth, - uint8_t *buffer, - uint32_t size); - -/*! - * @brief Get classic I2S mode configurations. - * - * @param config transceiver configurations - * @param bitWidth audio data bitWidth. - * @param mode audio data channel - * @param saiChannelMask channel mask value to enable - */ -static void SAI_GetCommonConfig(sai_transceiver_t *config, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask); -/******************************************************************************* - * Variables - ******************************************************************************/ -/* Base pointer array */ -static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS; -/*!@brief SAI handle pointer */ -static sai_handle_t *s_saiHandle[ARRAY_SIZE(s_saiBases)][2]; -/* IRQ number array */ -static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS; -static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Clock name array */ -static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -/*! @brief Pointer to tx IRQ handler for each instance. */ -static sai_tx_isr_t s_saiTxIsr; -/*! @brief Pointer to tx IRQ handler for each instance. */ -static sai_rx_isr_t s_saiRxIsr; - -/******************************************************************************* - * Code - ******************************************************************************/ -static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag) -{ - uint32_t rcsr = base->RCSR; - - return IS_SAI_FLAG_SET(rcsr, enableFlag) && IS_SAI_FLAG_SET(rcsr, statusFlag); -} - -static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag) -{ - uint32_t tcsr = base->TCSR; - - return IS_SAI_FLAG_SET(tcsr, enableFlag) && IS_SAI_FLAG_SET(tcsr, statusFlag); -} - -#if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \ - (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV))) -static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz) -{ - assert(mclk_Hz <= mclkSrcClock_Hz); - - uint32_t sourceFreq = mclkSrcClock_Hz / 100U; /*In order to prevent overflow */ - uint32_t targetFreq = mclk_Hz / 100U; /*In order to prevent overflow */ - -#if FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV - uint32_t postDivider = sourceFreq / targetFreq; - - /* if source equal to target, then disable divider */ - if (postDivider == 1U) - { - base->MCR &= ~I2S_MCR_DIVEN_MASK; - } - else - { - base->MCR = (base->MCR & (~I2S_MCR_DIV_MASK)) | I2S_MCR_DIV(postDivider / 2U - 1U) | I2S_MCR_DIVEN_MASK; - } -#endif -#if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER - uint16_t fract, divide; - uint32_t remaind = 0; - uint32_t current_remainder = 0xFFFFFFFFU; - uint16_t current_fract = 0; - uint16_t current_divide = 0; - uint32_t mul_freq = 0; - uint32_t max_fract = 256; - - /* Compute the max fract number */ - max_fract = targetFreq * 4096U / sourceFreq + 1U; - if (max_fract > 256U) - { - max_fract = 256U; - } - - /* Looking for the closet frequency */ - for (fract = 1; fract < max_fract; fract++) - { - mul_freq = sourceFreq * fract; - remaind = mul_freq % targetFreq; - divide = (uint16_t)(mul_freq / targetFreq); - - /* Find the exactly frequency */ - if (remaind == 0U) - { - current_fract = fract; - current_divide = (uint16_t)(mul_freq / targetFreq); - break; - } - - /* Closer to next one, set the closest to next data */ - if (remaind > mclk_Hz / 2U) - { - remaind = targetFreq - remaind; - divide += 1U; - } - - /* Update the closest div and fract */ - if (remaind < current_remainder) - { - current_fract = fract; - current_divide = divide; - current_remainder = remaind; - } - } - - /* Fill the computed fract and divider to registers */ - base->MDR = I2S_MDR_DIVIDE(current_divide - 1UL) | I2S_MDR_FRACT(current_fract - 1UL); - - /* Waiting for the divider updated */ - while ((base->MCR & I2S_MCR_DUF_MASK) != 0UL) - { - } -#endif -} -#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ - -static uint32_t SAI_GetInstance(I2S_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++) - { - if (s_saiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_saiBases)); - - return instance; -} - -static void SAI_WriteNonBlocking(I2S_Type *base, - uint32_t channel, - uint32_t channelMask, - uint32_t endChannel, - uint8_t bitWidth, - uint8_t *buffer, - uint32_t size) -{ - uint32_t i = 0, j = 0U; - uint8_t m = 0; - uint8_t bytesPerWord = bitWidth / 8U; - uint32_t data = 0; - uint32_t temp = 0; - - for (i = 0; i < size / bytesPerWord; i++) - { - for (j = channel; j <= endChannel; j++) - { - if (IS_SAI_FLAG_SET((1UL << j), channelMask)) - { - for (m = 0; m < bytesPerWord; m++) - { - temp = (uint32_t)(*buffer); - data |= (temp << (8U * m)); - buffer++; - } - base->TDR[j] = data; - data = 0; - } - } - } -} - -static void SAI_ReadNonBlocking(I2S_Type *base, - uint32_t channel, - uint32_t channelMask, - uint32_t endChannel, - uint8_t bitWidth, - uint8_t *buffer, - uint32_t size) -{ - uint32_t i = 0, j = 0; - uint8_t m = 0; - uint8_t bytesPerWord = bitWidth / 8U; - uint32_t data = 0; - - for (i = 0; i < size / bytesPerWord; i++) - { - for (j = channel; j <= endChannel; j++) - { - if (IS_SAI_FLAG_SET((1UL << j), channelMask)) - { - data = base->RDR[j]; - for (m = 0; m < bytesPerWord; m++) - { - *buffer = (uint8_t)(data >> (8U * m)) & 0xFFU; - buffer++; - } - } - } - } -} - -static void SAI_GetCommonConfig(sai_transceiver_t *config, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask) -{ - assert(NULL != config); - assert(saiChannelMask != 0U); - - (void)memset(config, 0, sizeof(sai_transceiver_t)); - - config->channelMask = (uint8_t)saiChannelMask; - /* sync mode default configurations */ - config->syncMode = kSAI_ModeAsync; - - /* master mode default */ - config->masterSlave = kSAI_Master; - - /* bit default configurations */ - config->bitClock.bclkSrcSwap = false; - config->bitClock.bclkInputDelay = false; - config->bitClock.bclkPolarity = kSAI_SampleOnRisingEdge; - config->bitClock.bclkSource = kSAI_BclkSourceMclkDiv; - - /* frame sync default configurations */ - config->frameSync.frameSyncWidth = (uint8_t)bitWidth; - config->frameSync.frameSyncEarly = true; -#if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND - config->frameSync.frameSyncGenerateOnDemand = false; -#endif - config->frameSync.frameSyncPolarity = kSAI_PolarityActiveLow; - - /* serial data default configurations */ -#if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE - config->serialData.dataMode = kSAI_DataPinStateOutputZero; -#endif - config->serialData.dataOrder = kSAI_DataMSB; - config->serialData.dataWord0Length = (uint8_t)bitWidth; - config->serialData.dataWordLength = (uint8_t)bitWidth; - config->serialData.dataWordNLength = (uint8_t)bitWidth; - config->serialData.dataFirstBitShifted = (uint8_t)bitWidth; - config->serialData.dataWordNum = 2U; - config->serialData.dataMaskedWord = (uint32_t)mode; - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* fifo configurations */ - config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT / 2U); -#endif - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - config->fifo.fifoContinueOneError = true; -#endif -} - -/*! - * brief Initializes the SAI Tx peripheral. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_Init - * - * Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure. - * The configuration structure can be custom filled or set with default values by - * SAI_TxGetDefaultConfig(). - * - * note This API should be called at the beginning of the application to use - * the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault - * because the clock is not enabled. - * - * param base SAI base pointer - * param config SAI configuration structure. - */ -void SAI_TxInit(I2S_Type *base, const sai_config_t *config) -{ - uint32_t val = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the SAI clock */ - (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) -#if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS)) - /* Master clock source setting */ - val = (base->MCR & ~I2S_MCR_MICS_MASK); - base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); -#endif - - /* Configure Master clock output enable */ - val = (base->MCR & ~I2S_MCR_MOE_MASK); - base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable)); -#endif /* FSL_FEATURE_SAI_HAS_MCR */ - - SAI_TxReset(base); - - /* Configure audio protocol */ - if (config->protocol == kSAI_BusLeftJustified) - { - base->TCR2 |= I2S_TCR2_BCP_MASK; - base->TCR3 &= ~I2S_TCR3_WDFL_MASK; - base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusRightJustified) - { - base->TCR2 |= I2S_TCR2_BCP_MASK; - base->TCR3 &= ~I2S_TCR3_WDFL_MASK; - base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusI2S) - { - base->TCR2 |= I2S_TCR2_BCP_MASK; - base->TCR3 &= ~I2S_TCR3_WDFL_MASK; - base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusPCMA) - { - base->TCR2 &= ~I2S_TCR2_BCP_MASK; - base->TCR3 &= ~I2S_TCR3_WDFL_MASK; - base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); - } - else - { - base->TCR2 &= ~I2S_TCR2_BCP_MASK; - base->TCR3 &= ~I2S_TCR3_WDFL_MASK; - base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U); - } - - /* Set master or slave */ - if (config->masterSlave == kSAI_Master) - { - base->TCR2 |= I2S_TCR2_BCD_MASK; - base->TCR4 |= I2S_TCR4_FSD_MASK; - - /* Bit clock source setting */ - val = base->TCR2 & (~I2S_TCR2_MSEL_MASK); - base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource)); - } - else - { - base->TCR2 &= ~I2S_TCR2_BCD_MASK; - base->TCR4 &= ~I2S_TCR4_FSD_MASK; - } - - /* Set Sync mode */ - if (config->syncMode == kSAI_ModeAsync) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(0U)); - } - if (config->syncMode == kSAI_ModeSync) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(1U)); - /* If sync with Rx, should set Rx to async mode */ - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(0U)); - } -#if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) - if (config->syncMode == kSAI_ModeSyncWithOtherTx) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(2U)); - } - if (config->syncMode == kSAI_ModeSyncWithOtherRx) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(3U)); - } -#endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */ - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - SAI_TxSetFIFOErrorContinue(base, true); -#endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */ -} - -/*! - * brief Initializes the SAI Rx peripheral. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_Init - * - * Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure. - * The configuration structure can be custom filled or set with default values by - * SAI_RxGetDefaultConfig(). - * - * note This API should be called at the beginning of the application to use - * the SAI driver. Otherwise, accessing the SAI module can cause a hard fault - * because the clock is not enabled. - * - * param base SAI base pointer - * param config SAI configuration structure. - */ -void SAI_RxInit(I2S_Type *base, const sai_config_t *config) -{ - uint32_t val = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable SAI clock first. */ - (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) -#if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS)) - /* Master clock source setting */ - val = (base->MCR & ~I2S_MCR_MICS_MASK); - base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); -#endif - - /* Configure Master clock output enable */ - val = (base->MCR & ~I2S_MCR_MOE_MASK); - base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable)); -#endif /* FSL_FEATURE_SAI_HAS_MCR */ - - SAI_RxReset(base); - - /* Configure audio protocol */ - if (config->protocol == kSAI_BusLeftJustified) - { - base->RCR2 |= I2S_RCR2_BCP_MASK; - base->RCR3 &= ~I2S_RCR3_WDFL_MASK; - base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusRightJustified) - { - base->RCR2 |= I2S_RCR2_BCP_MASK; - base->RCR3 &= ~I2S_RCR3_WDFL_MASK; - base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusI2S) - { - base->RCR2 |= I2S_RCR2_BCP_MASK; - base->RCR3 &= ~I2S_RCR3_WDFL_MASK; - base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U); - } - else if (config->protocol == kSAI_BusPCMA) - { - base->RCR2 &= ~I2S_RCR2_BCP_MASK; - base->RCR3 &= ~I2S_RCR3_WDFL_MASK; - base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); - } - else - { - base->RCR2 &= ~I2S_RCR2_BCP_MASK; - base->RCR3 &= ~I2S_RCR3_WDFL_MASK; - base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U); - } - - /* Set master or slave */ - if (config->masterSlave == kSAI_Master) - { - base->RCR2 |= I2S_RCR2_BCD_MASK; - base->RCR4 |= I2S_RCR4_FSD_MASK; - - /* Bit clock source setting */ - val = base->RCR2 & (~I2S_RCR2_MSEL_MASK); - base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource)); - } - else - { - base->RCR2 &= ~I2S_RCR2_BCD_MASK; - base->RCR4 &= ~I2S_RCR4_FSD_MASK; - } - - /* Set Sync mode */ - if (config->syncMode == kSAI_ModeAsync) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(0U)); - } - if (config->syncMode == kSAI_ModeSync) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(1U)); - /* If sync with Tx, should set Tx to async mode */ - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(0U)); - } -#if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) - if (config->syncMode == kSAI_ModeSyncWithOtherTx) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(2U)); - } - if (config->syncMode == kSAI_ModeSyncWithOtherRx) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(3U)); - } -#endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */ - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - SAI_RxSetFIFOErrorContinue(base, true); -#endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */ -} - -/*! - * brief Initializes the SAI peripheral. - * - * This API gates the SAI clock. The SAI module can't operate unless SAI_Init is called to enable the clock. - * - * param base SAI base pointer - */ -void SAI_Init(I2S_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the SAI clock */ - (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* disable interrupt and DMA request*/ - base->TCSR &= - ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FRDE_MASK | I2S_TCSR_FWDE_MASK); - base->RCSR &= - ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FRDE_MASK | I2S_RCSR_FWDE_MASK); -#else - /* disable interrupt and DMA request*/ - base->TCSR &= ~(I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FWDE_MASK); - base->RCSR &= ~(I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FWDE_MASK); -#endif -} - -/*! - * brief De-initializes the SAI peripheral. - * - * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit - * or SAI_RxInit is called to enable the clock. - * - * param base SAI base pointer - */ -void SAI_Deinit(I2S_Type *base) -{ - SAI_TxEnable(base, false); - SAI_RxEnable(base, false); -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - (void)CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Sets the SAI Tx configuration structure to default values. - * - * deprecated Do not use this function. It has been superceded by @ref - * SAI_GetClassicI2SConfig, SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig, SAI_GetDSPConfig,SAI_GetTDMConfig - * - * This API initializes the configuration structure for use in SAI_TxConfig(). - * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified - * before calling SAI_TxConfig(). - * This is an example. - code - sai_config_t config; - SAI_TxGetDefaultConfig(&config); - endcode - * - * param config pointer to master configuration structure - */ -void SAI_TxGetDefaultConfig(sai_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->bclkSource = kSAI_BclkSourceMclkDiv; - config->masterSlave = kSAI_Master; -#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) - config->mclkOutputEnable = true; -#if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS)) - config->mclkSource = kSAI_MclkSourceSysclk; -#endif -#endif /* FSL_FEATURE_SAI_HAS_MCR */ - config->protocol = kSAI_BusI2S; - config->syncMode = kSAI_ModeAsync; -} - -/*! - * brief Sets the SAI Rx configuration structure to default values. - * - * deprecated Do not use this function. It has been superceded by @ref - * SAI_GetClassicI2SConfig,SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig,SAI_GetDSPConfig,SAI_GetTDMConfig - * - * This API initializes the configuration structure for use in SAI_RxConfig(). - * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified - * before calling SAI_RxConfig(). - * This is an example. - code - sai_config_t config; - SAI_RxGetDefaultConfig(&config); - endcode - * - * param config pointer to master configuration structure - */ -void SAI_RxGetDefaultConfig(sai_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->bclkSource = kSAI_BclkSourceMclkDiv; - config->masterSlave = kSAI_Master; -#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) - config->mclkOutputEnable = true; -#if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS)) - config->mclkSource = kSAI_MclkSourceSysclk; -#endif -#endif /* FSL_FEATURE_SAI_HAS_MCR */ - config->protocol = kSAI_BusI2S; - config->syncMode = kSAI_ModeSync; -} - -/*! - * brief Resets the SAI Tx. - * - * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit. - * - * param base SAI base pointer - */ -void SAI_TxReset(I2S_Type *base) -{ - /* Set the software reset and FIFO reset to clear internal state */ - base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK; - - /* Clear software reset bit, this should be done by software */ - base->TCSR &= ~I2S_TCSR_SR_MASK; - - /* Reset all Tx register values */ - base->TCR2 = 0; - base->TCR3 = 0; - base->TCR4 = 0; - base->TCR5 = 0; - base->TMR = 0; -} - -/*! - * brief Resets the SAI Rx. - * - * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit. - * - * param base SAI base pointer - */ -void SAI_RxReset(I2S_Type *base) -{ - /* Set the software reset and FIFO reset to clear internal state */ - base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK; - - /* Clear software reset bit, this should be done by software */ - base->RCSR &= ~I2S_RCSR_SR_MASK; - - /* Reset all Rx register values */ - base->RCR2 = 0; - base->RCR3 = 0; - base->RCR4 = 0; - base->RCR5 = 0; - base->RMR = 0; -} - -/*! - * brief Enables/disables the SAI Tx. - * - * param base SAI base pointer - * param enable True means enable SAI Tx, false means disable. - */ -void SAI_TxEnable(I2S_Type *base, bool enable) -{ - if (enable) - { - /* If clock is sync with Rx, should enable RE bit. */ - if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U) - { - base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); - } - base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); - /* Also need to clear the FIFO error flag before start */ - SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag); - } - else - { - /* If Rx not in sync with Tx, then disable Tx, otherwise, shall not disable Tx */ - if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) != 0x1U) - { - /* Disable TE bit */ - base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK)); - } - } -} - -/*! - * brief Enables/disables the SAI Rx. - * - * param base SAI base pointer - * param enable True means enable SAI Rx, false means disable. - */ -void SAI_RxEnable(I2S_Type *base, bool enable) -{ - if (enable) - { - /* If clock is sync with Tx, should enable TE bit. */ - if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U) - { - base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK); - } - base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK); - /* Also need to clear the FIFO error flag before start */ - SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag); - } - else - { - /* If Tx not in sync with Rx, then disable Rx, otherwise, shall not disable Rx */ - if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) != 0x1U) - { - /* Disable RE bit */ - base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK)); - } - } -} - -/*! - * brief Do software reset or FIFO reset . - * - * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0. - * Software reset means clear the Tx internal logic, including the bit clock, frame count etc. But software - * reset will not clear any configuration registers like TCR1~TCR5. - * This function will also clear all the error flags such as FIFO error, sync error etc. - * - * param base SAI base pointer - * param type Reset type, FIFO reset or software reset - */ -void SAI_TxSoftwareReset(I2S_Type *base, sai_reset_type_t type) -{ - base->TCSR |= (uint32_t)type; - - /* Clear the software reset */ - base->TCSR &= ~I2S_TCSR_SR_MASK; -} - -/*! - * brief Do software reset or FIFO reset . - * - * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0. - * Software reset means clear the Rx internal logic, including the bit clock, frame count etc. But software - * reset will not clear any configuration registers like RCR1~RCR5. - * This function will also clear all the error flags such as FIFO error, sync error etc. - * - * param base SAI base pointer - * param type Reset type, FIFO reset or software reset - */ -void SAI_RxSoftwareReset(I2S_Type *base, sai_reset_type_t type) -{ - base->RCSR |= (uint32_t)type; - - /* Clear the software reset */ - base->RCSR &= ~I2S_RCSR_SR_MASK; -} - -/*! - * brief Set the Tx channel FIFO enable mask. - * - * param base SAI base pointer - * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled, - * 3 means both channel 0 and channel 1 enabled. - */ -void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask) -{ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; - base->TCR3 |= I2S_TCR3_TCE(mask); -} - -/*! - * brief Set the Rx channel FIFO enable mask. - * - * param base SAI base pointer - * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled, - * 3 means both channel 0 and channel 1 enabled. - */ -void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask) -{ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; - base->RCR3 |= I2S_RCR3_RCE(mask); -} - -/*! - * brief Set the Tx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_TxSetDataOrder(I2S_Type *base, sai_data_order_t order) -{ - uint32_t val = (base->TCR4) & (~I2S_TCR4_MF_MASK); - - val |= I2S_TCR4_MF(order); - base->TCR4 = val; -} - -/*! - * brief Set the Rx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_RxSetDataOrder(I2S_Type *base, sai_data_order_t order) -{ - uint32_t val = (base->RCR4) & (~I2S_RCR4_MF_MASK); - - val |= I2S_RCR4_MF(order); - base->RCR4 = val; -} - -/*! - * brief Set the Tx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_TxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity) -{ - uint32_t val = (base->TCR2) & (~I2S_TCR2_BCP_MASK); - - val |= I2S_TCR2_BCP(polarity); - base->TCR2 = val; -} - -/*! - * brief Set the Rx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_RxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity) -{ - uint32_t val = (base->RCR2) & (~I2S_RCR2_BCP_MASK); - - val |= I2S_RCR2_BCP(polarity); - base->RCR2 = val; -} - -/*! - * brief Set the Tx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_TxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity) -{ - uint32_t val = (base->TCR4) & (~I2S_TCR4_FSP_MASK); - - val |= I2S_TCR4_FSP(polarity); - base->TCR4 = val; -} - -/*! - * brief Set the Rx data order. - * - * param base SAI base pointer - * param order Data order MSB or LSB - */ -void SAI_RxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity) -{ - uint32_t val = (base->RCR4) & (~I2S_RCR4_FSP_MASK); - - val |= I2S_RCR4_FSP(polarity); - base->RCR4 = val; -} - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING -/*! - * brief Set Tx FIFO packing feature. - * - * param base SAI base pointer. - * param pack FIFO pack type. It is element of sai_fifo_packing_t. - */ -void SAI_TxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack) -{ - uint32_t val = base->TCR4; - - val &= ~I2S_TCR4_FPACK_MASK; - val |= I2S_TCR4_FPACK(pack); - base->TCR4 = val; -} - -/*! - * brief Set Rx FIFO packing feature. - * - * param base SAI base pointer. - * param pack FIFO pack type. It is element of sai_fifo_packing_t. - */ -void SAI_RxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack) -{ - uint32_t val = base->RCR4; - - val &= ~I2S_RCR4_FPACK_MASK; - val |= I2S_RCR4_FPACK(pack); - base->RCR4 = val; -} -#endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */ - -/*! - * brief Transmitter bit clock rate configurations. - * - * param base SAI base pointer. - * param sourceClockHz, bit clock source frequency. - * param sampleRate audio data sample rate. - * param bitWidth, audio data bitWidth. - * param channelNumbers, audio channel numbers. - */ -void SAI_TxSetBitClockRate( - I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers) -{ - uint32_t tcr2 = base->TCR2; - uint32_t bitClockDiv = 0; - uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers; - - assert(sourceClockHz >= bitClockFreq); - - tcr2 &= ~I2S_TCR2_DIV_MASK; - /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */ - bitClockDiv = sourceClockHz / bitClockFreq; - /* for the condition where the source clock is smaller than target bclk */ - if (bitClockDiv == 0U) - { - bitClockDiv++; - } - /* recheck the divider if properly or not, to make sure output blck not bigger than target*/ - if ((sourceClockHz / bitClockDiv) > bitClockFreq) - { - bitClockDiv++; - } - -#if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS) - /* if bclk same with MCLK, bypass the divider */ - if (bitClockDiv == 1U) - { - tcr2 |= I2S_TCR2_BYP_MASK; - } - else -#endif - { - tcr2 |= I2S_TCR2_DIV(bitClockDiv / 2U - 1UL); - } - - base->TCR2 = tcr2; -} - -/*! - * brief Receiver bit clock rate configurations. - * - * param base SAI base pointer. - * param sourceClockHz, bit clock source frequency. - * param sampleRate audio data sample rate. - * param bitWidth, audio data bitWidth. - * param channelNumbers, audio channel numbers. - */ -void SAI_RxSetBitClockRate( - I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers) -{ - uint32_t rcr2 = base->RCR2; - uint32_t bitClockDiv = 0; - uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers; - - assert(sourceClockHz >= bitClockFreq); - - rcr2 &= ~I2S_RCR2_DIV_MASK; - /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */ - bitClockDiv = sourceClockHz / bitClockFreq; - /* for the condition where the source clock is smaller than target bclk */ - if (bitClockDiv == 0U) - { - bitClockDiv++; - } - /* recheck the divider if properly or not, to make sure output blck not bigger than target*/ - if ((sourceClockHz / bitClockDiv) > bitClockFreq) - { - bitClockDiv++; - } - -#if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS) - /* if bclk same with MCLK, bypass the divider */ - if (bitClockDiv == 1U) - { - rcr2 |= I2S_RCR2_BYP_MASK; - } - else -#endif - { - rcr2 |= I2S_RCR2_DIV(bitClockDiv / 2U - 1UL); - } - - base->RCR2 = rcr2; -} - -/*! - * brief Transmitter Bit clock configurations. - * - * param base SAI base pointer. - * param masterSlave master or slave. - * param config bit clock other configurations, can be NULL in slave mode. - */ -void SAI_TxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config) -{ - uint32_t tcr2 = base->TCR2; - - if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave)) - { - assert(config != NULL); - - tcr2 &= ~(I2S_TCR2_BCD_MASK | I2S_TCR2_BCP_MASK | I2S_TCR2_BCI_MASK | I2S_TCR2_BCS_MASK | I2S_TCR2_MSEL_MASK); - tcr2 |= I2S_TCR2_BCD(1U) | I2S_TCR2_BCP(config->bclkPolarity) | I2S_TCR2_BCI(config->bclkInputDelay) | - I2S_TCR2_BCS(config->bclkSrcSwap) | I2S_TCR2_MSEL(config->bclkSource); - } - else - { - tcr2 &= ~(I2S_TCR2_BCD_MASK); - } - - base->TCR2 = tcr2; -} - -/*! - * brief Receiver Bit clock configurations. - * - * param base SAI base pointer. - * param masterSlave master or slave. - * param config bit clock other configurations, can be NULL in slave mode. - */ -void SAI_RxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config) -{ - uint32_t rcr2 = base->RCR2; - - if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave)) - { - assert(config != NULL); - - rcr2 &= ~(I2S_RCR2_BCD_MASK | I2S_RCR2_BCP_MASK | I2S_RCR2_BCI_MASK | I2S_RCR2_BCS_MASK | I2S_RCR2_MSEL_MASK); - rcr2 |= I2S_RCR2_BCD(1U) | I2S_RCR2_BCP(config->bclkPolarity) | I2S_RCR2_BCI(config->bclkInputDelay) | - I2S_RCR2_BCS(config->bclkSrcSwap) | I2S_RCR2_MSEL(config->bclkSource); - } - else - { - rcr2 &= ~(I2S_RCR2_BCD_MASK); - } - - base->RCR2 = rcr2; -} - -#if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \ - (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) -/*! - * brief Master clock configurations. - * - * param base SAI base pointer. - * param config master clock configurations. - */ -void SAI_SetMasterClockConfig(I2S_Type *base, sai_master_clock_t *config) -{ - assert(config != NULL); - -#if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR) - uint32_t val = 0; -#if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS)) - /* Master clock source setting */ - val = (base->MCR & ~I2S_MCR_MICS_MASK); - base->MCR = (val | I2S_MCR_MICS(config->mclkSource)); -#endif - - /* Configure Master clock output enable */ - val = (base->MCR & ~I2S_MCR_MOE_MASK); - base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable)); -#endif /* FSL_FEATURE_SAI_HAS_MCR */ - -#if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \ - (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV))) - /* Check if master clock divider enabled, then set master clock divider */ - if (config->mclkOutputEnable) - { - SAI_SetMasterClockDivider(base, config->mclkHz, config->mclkSourceClkHz); - } -#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ -} -#endif - -#if FSL_SAI_HAS_FIFO_EXTEND_FEATURE -/*! - * brief SAI transmitter fifo configurations. - * - * param base SAI base pointer. - * param config fifo configurations. - */ -void SAI_TxSetFifoConfig(I2S_Type *base, sai_fifo_t *config) -{ - assert(config != NULL); -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - assert(config->fifoWatermark <= (I2S_TCR1_TFW_MASK >> I2S_TCR1_TFW_SHIFT)); -#endif - - uint32_t tcr4 = base->TCR4; - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE - tcr4 &= ~I2S_TCR4_FCOMB_MASK; - tcr4 |= I2S_TCR4_FCOMB(config->fifoCombine); -#endif - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - tcr4 &= ~I2S_TCR4_FCONT_MASK; - /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX - * not work */ - if (base->TMR == 0U) - { - tcr4 |= I2S_TCR4_FCONT(config->fifoContinueOneError); - } -#endif - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING - tcr4 &= ~I2S_TCR4_FPACK_MASK; - tcr4 |= I2S_TCR4_FPACK(config->fifoPacking); -#endif - - base->TCR4 = tcr4; - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - base->TCR1 = (base->TCR1 & (~I2S_TCR1_TFW_MASK)) | I2S_TCR1_TFW(config->fifoWatermark); -#endif -} - -/*! - * brief SAI receiver fifo configurations. - * - * param base SAI base pointer. - * param config fifo configurations. - */ -void SAI_RxSetFifoConfig(I2S_Type *base, sai_fifo_t *config) -{ - assert(config != NULL); -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - assert(config->fifoWatermark <= (I2S_TCR1_TFW_MASK >> I2S_TCR1_TFW_SHIFT)); -#endif - uint32_t rcr4 = base->RCR4; - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE - rcr4 &= ~I2S_RCR4_FCOMB_MASK; - rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine); -#endif - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - rcr4 &= ~I2S_RCR4_FCONT_MASK; - rcr4 |= I2S_RCR4_FCONT(config->fifoContinueOneError); -#endif - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING - rcr4 &= ~I2S_RCR4_FPACK_MASK; - rcr4 |= I2S_RCR4_FPACK(config->fifoPacking); -#endif - - base->RCR4 = rcr4; - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - base->RCR1 = (base->RCR1 & (~I2S_RCR1_RFW_MASK)) | I2S_RCR1_RFW(config->fifoWatermark); -#endif -} -#endif - -/*! - * brief SAI transmitter Frame sync configurations. - * - * param base SAI base pointer. - * param masterSlave master or slave. - * param config frame sync configurations, can be NULL in slave mode. - */ -void SAI_TxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config) -{ - uint32_t tcr4 = base->TCR4; - - if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) - { - assert(config != NULL); - assert((config->frameSyncWidth - 1UL) <= (I2S_TCR4_SYWD_MASK >> I2S_TCR4_SYWD_SHIFT)); - - tcr4 &= ~(I2S_TCR4_FSE_MASK | I2S_TCR4_FSP_MASK | I2S_TCR4_FSD_MASK | I2S_TCR4_SYWD_MASK); - -#if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND - tcr4 &= ~I2S_TCR4_ONDEM_MASK; - tcr4 |= I2S_TCR4_ONDEM(config->frameSyncGenerateOnDemand); -#endif - - tcr4 |= I2S_TCR4_FSE(config->frameSyncEarly) | I2S_TCR4_FSP(config->frameSyncPolarity) | I2S_TCR4_FSD(1UL) | - I2S_TCR4_SYWD(config->frameSyncWidth - 1UL); - } - else - { - tcr4 &= ~I2S_TCR4_FSD_MASK; - } - - base->TCR4 = tcr4; -} - -/*! - * brief SAI receiver Frame sync configurations. - * - * param base SAI base pointer. - * param masterSlave master or slave. - * param config frame sync configurations, can be NULL in slave mode. - */ -void SAI_RxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config) -{ - uint32_t rcr4 = base->RCR4; - - if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) - { - assert(config != NULL); - assert((config->frameSyncWidth - 1UL) <= (I2S_RCR4_SYWD_MASK >> I2S_RCR4_SYWD_SHIFT)); - - rcr4 &= ~(I2S_RCR4_FSE_MASK | I2S_RCR4_FSP_MASK | I2S_RCR4_FSD_MASK | I2S_RCR4_SYWD_MASK); - -#if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND - rcr4 &= ~I2S_RCR4_ONDEM_MASK; - rcr4 |= I2S_RCR4_ONDEM(config->frameSyncGenerateOnDemand); -#endif - - rcr4 |= I2S_RCR4_FSE(config->frameSyncEarly) | I2S_RCR4_FSP(config->frameSyncPolarity) | I2S_RCR4_FSD(1UL) | - I2S_RCR4_SYWD(config->frameSyncWidth - 1UL); - } - else - { - rcr4 &= ~I2S_RCR4_FSD_MASK; - } - - base->RCR4 = rcr4; -} - -/*! - * brief SAI transmitter Serial data configurations. - * - * param base SAI base pointer. - * param config serial data configurations. - */ -void SAI_TxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config) -{ - assert(config != NULL); - - uint32_t tcr4 = base->TCR4; - - base->TCR5 = I2S_TCR5_WNW(config->dataWordNLength - 1UL) | I2S_TCR5_W0W(config->dataWord0Length - 1UL) | - I2S_TCR5_FBT(config->dataFirstBitShifted - 1UL); - base->TMR = config->dataMaskedWord; -#if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR - /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX - * not work */ - if (config->dataMaskedWord > 0U) - { - tcr4 &= ~I2S_TCR4_FCONT_MASK; - } -#endif - tcr4 &= ~(I2S_TCR4_FRSZ_MASK | I2S_TCR4_MF_MASK); - tcr4 |= I2S_TCR4_FRSZ(config->dataWordNum - 1UL) | I2S_TCR4_MF(config->dataOrder); - -#if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE - tcr4 &= ~I2S_TCR4_CHMOD_MASK; - tcr4 |= I2S_TCR4_CHMOD(config->dataMode); -#endif - - base->TCR4 = tcr4; -} - -/*! - * @brief SAI receiver Serial data configurations. - * - * @param base SAI base pointer. - * @param config serial data configurations. - */ -void SAI_RxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config) -{ - assert(config != NULL); - - uint32_t rcr4 = base->RCR4; - - base->RCR5 = I2S_RCR5_WNW(config->dataWordNLength - 1UL) | I2S_RCR5_W0W(config->dataWord0Length - 1UL) | - I2S_RCR5_FBT(config->dataFirstBitShifted - 1UL); - base->RMR = config->dataMaskedWord; - - rcr4 &= ~(I2S_RCR4_FRSZ_MASK | I2S_RCR4_MF_MASK); - rcr4 |= I2S_RCR4_FRSZ(config->dataWordNum - 1uL) | I2S_RCR4_MF(config->dataOrder); - - base->RCR4 = rcr4; -} - -/*! - * brief SAI transmitter configurations. - * - * param base SAI base pointer. - * param config transmitter configurations. - */ -void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config) -{ - assert(config != NULL); - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint8_t i = 0U; - uint32_t val = 0U; - uint8_t channelNums = 0U; - - /* reset transmitter */ - SAI_TxReset(base); - - /* if channel mask is not set, then format->channel must be set, - use it to get channel mask value */ - if (config->channelMask == 0U) - { - config->channelMask = 1U << config->startChannel; - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET(1UL << i, config->channelMask)) - { - channelNums++; - config->endChannel = i; - } - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), config->channelMask)) - { - config->startChannel = i; - break; - } - } - - config->channelNums = channelNums; -#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) - /* make sure combine mode disabled while multipe channel is used */ - if (config->channelNums > 1U) - { - base->TCR4 &= ~I2S_TCR4_FCOMB_MASK; - } -#endif - - /* Set data channel */ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; - base->TCR3 |= I2S_TCR3_TCE(config->channelMask); - - if (config->syncMode == kSAI_ModeAsync) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(0U)); - } - if (config->syncMode == kSAI_ModeSync) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(1U)); - /* If sync with Rx, should set Rx to async mode */ - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(0U)); - } -#if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) - if (config->syncMode == kSAI_ModeSyncWithOtherTx) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(2U)); - } - if (config->syncMode == kSAI_ModeSyncWithOtherRx) - { - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(3U)); - } -#endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */ - - /* bit clock configurations */ - SAI_TxSetBitclockConfig(base, config->masterSlave, &config->bitClock); - /* serial data configurations */ - SAI_TxSetSerialDataConfig(base, &config->serialData); - /* frame sync configurations */ - SAI_TxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync); -#if FSL_SAI_HAS_FIFO_EXTEND_FEATURE - /* fifo configurations */ - SAI_TxSetFifoConfig(base, &config->fifo); -#endif -} - -/*! - * brief SAI transmitter transfer configurations. - * - * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations. - * - * param base SAI base pointer. - * param handle SAI handle pointer. - * param config tranmitter configurations. - */ -void SAI_TransferTxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config) -{ - assert(handle != NULL); - assert(config != NULL); - assert(config->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); - - handle->bitWidth = config->frameSync.frameSyncWidth; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->watermark = config->fifo.fifoWatermark; -#endif - - /* transmitter configurations */ - SAI_TxSetConfig(base, config); - - handle->channel = config->startChannel; - /* used for multi channel */ - handle->channelMask = config->channelMask; - handle->channelNums = config->channelNums; - handle->endChannel = config->endChannel; -} - -/*! - * brief SAI receiver configurations. - * - * param base SAI base pointer. - * param config transmitter configurations. - */ -void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config) -{ - assert(config != NULL); - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint8_t i = 0U; - uint32_t val = 0U; - uint8_t channelNums = 0U; - - /* reset receiver */ - SAI_RxReset(base); - - /* if channel mask is not set, then format->channel must be set, - use it to get channel mask value */ - if (config->channelMask == 0U) - { - config->channelMask = 1U << config->startChannel; - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), config->channelMask)) - { - channelNums++; - config->endChannel = i; - } - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), config->channelMask)) - { - config->startChannel = i; - break; - } - } - - config->channelNums = channelNums; -#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) - /* make sure combine mode disabled while multipe channel is used */ - if (config->channelNums > 1U) - { - base->RCR4 &= ~I2S_RCR4_FCOMB_MASK; - } -#endif - - /* Set data channel */ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; - base->RCR3 |= I2S_RCR3_RCE(config->channelMask); - - /* Set Sync mode */ - if (config->syncMode == kSAI_ModeAsync) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(0U)); - } - if (config->syncMode == kSAI_ModeSync) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(1U)); - /* If sync with Tx, should set Tx to async mode */ - val = base->TCR2; - val &= ~I2S_TCR2_SYNC_MASK; - base->TCR2 = (val | I2S_TCR2_SYNC(0U)); - } -#if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) - if (config->syncMode == kSAI_ModeSyncWithOtherTx) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(2U)); - } - if (config->syncMode == kSAI_ModeSyncWithOtherRx) - { - val = base->RCR2; - val &= ~I2S_RCR2_SYNC_MASK; - base->RCR2 = (val | I2S_RCR2_SYNC(3U)); - } -#endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */ - - /* bit clock configurations */ - SAI_RxSetBitclockConfig(base, config->masterSlave, &config->bitClock); - /* serial data configurations */ - SAI_RxSetSerialDataConfig(base, &config->serialData); - /* frame sync configurations */ - SAI_RxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync); -#if FSL_SAI_HAS_FIFO_EXTEND_FEATURE - /* fifo configurations */ - SAI_RxSetFifoConfig(base, &config->fifo); -#endif -} - -/*! - * brief SAI receiver transfer configurations. - * - * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations. - * - * param base SAI base pointer. - * param handle SAI handle pointer. - * param config tranmitter configurations. - */ -void SAI_TransferRxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config) -{ - assert(handle != NULL); - assert(config != NULL); - - handle->bitWidth = config->frameSync.frameSyncWidth; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->watermark = config->fifo.fifoWatermark; -#endif - - /* receiver configurations */ - SAI_RxSetConfig(base, config); - - handle->channel = config->startChannel; - /* used for multi channel */ - handle->channelMask = config->channelMask; - handle->channelNums = config->channelNums; - handle->endChannel = config->endChannel; -} - -/*! - * brief Get classic I2S mode configurations. - * - * param config transceiver configurations. - * param bitWidth audio data bitWidth. - * param mode audio data channel. - * param saiChannelMask channel mask value to enable. - */ -void SAI_GetClassicI2SConfig(sai_transceiver_t *config, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask) -{ - SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask); -} - -/*! - * brief Get left justified mode configurations. - * - * param config transceiver configurations. - * param bitWidth audio data bitWidth. - * param mode audio data channel. - * param saiChannelMask channel mask value to enable. - */ -void SAI_GetLeftJustifiedConfig(sai_transceiver_t *config, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask) -{ - assert(NULL != config); - assert(saiChannelMask != 0U); - - SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask); - - config->frameSync.frameSyncEarly = false; - config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh; -} - -/*! - * brief Get right justified mode configurations. - * - * param config transceiver configurations. - * param bitWidth audio data bitWidth. - * param mode audio data channel. - * param saiChannelMask channel mask value to enable. - */ -void SAI_GetRightJustifiedConfig(sai_transceiver_t *config, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask) -{ - assert(NULL != config); - assert(saiChannelMask != 0U); - - SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask); - - config->frameSync.frameSyncEarly = false; - config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh; -} - -/*! - * brief Get DSP mode configurations. - * - * param config transceiver configurations. - * param bitWidth audio data bitWidth. - * param mode audio data channel. - * param saiChannelMask channel mask value to enable. - */ -void SAI_GetDSPConfig(sai_transceiver_t *config, - sai_frame_sync_len_t frameSyncWidth, - sai_word_width_t bitWidth, - sai_mono_stereo_t mode, - uint32_t saiChannelMask) -{ - assert(NULL != config); - assert(saiChannelMask != 0U); - - SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask); - - /* frame sync default configurations */ - switch (frameSyncWidth) - { - case kSAI_FrameSyncLenOneBitClk: - config->frameSync.frameSyncWidth = 1U; - break; - default: - assert(false); - break; - } - config->frameSync.frameSyncEarly = false; - config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh; -} - -/*! - * brief Get TDM mode configurations. - * - * param config transceiver configurations. - * param bitWidth audio data bitWidth. - * param mode audio data channel. - * param saiChannelMask channel mask value to enable. - */ -void SAI_GetTDMConfig(sai_transceiver_t *config, - sai_frame_sync_len_t frameSyncWidth, - sai_word_width_t bitWidth, - uint32_t dataWordNum, - uint32_t saiChannelMask) -{ - assert(NULL != config); - assert(saiChannelMask != 0U); - assert(dataWordNum <= 32U); - - SAI_GetCommonConfig(config, bitWidth, kSAI_Stereo, saiChannelMask); - - /* frame sync default configurations */ - switch (frameSyncWidth) - { - case kSAI_FrameSyncLenOneBitClk: - config->frameSync.frameSyncWidth = 1U; - break; - case kSAI_FrameSyncLenPerWordWidth: - break; - default: - assert(false); - break; - } - config->frameSync.frameSyncEarly = false; - config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh; - config->serialData.dataWordNum = (uint8_t)dataWordNum; -} - -/*! - * brief Configures the SAI Tx audio format. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_TxSetConfig - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. - * - * param base SAI base pointer. - * param format Pointer to the SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master - * clock, this value should equal the masterClockHz. - */ -void SAI_TxSetFormat(I2S_Type *base, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint32_t bclk = 0; - uint32_t val = 0; - uint8_t i = 0U, channelNums = 0U; - uint32_t divider = 0U; - - if (format->isFrameSyncCompact) - { - bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U); - val = (base->TCR4 & (~I2S_TCR4_SYWD_MASK)); - val |= I2S_TCR4_SYWD(format->bitWidth - 1U); - base->TCR4 = val; - } - else - { - bclk = format->sampleRate_Hz * 32U * 2U; - } - -/* Compute the mclk */ -#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) - /* Check if master clock divider enabled, then set master clock divider */ - if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK)) - { - SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); - } -#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ - - /* Set bclk if needed */ - if (IS_SAI_FLAG_SET(base->TCR2, I2S_TCR2_BCD_MASK)) - { - base->TCR2 &= ~I2S_TCR2_DIV_MASK; - /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */ - divider = bclkSourceClockHz / bclk; - /* for the condition where the source clock is smaller than target bclk */ - if (divider == 0U) - { - divider++; - } - /* recheck the divider if properly or not, to make sure output blck not bigger than target*/ - if ((bclkSourceClockHz / divider) > bclk) - { - divider++; - } - -#if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS) - /* if bclk same with MCLK, bypass the divider */ - if (divider == 1U) - { - base->TCR2 |= I2S_TCR2_BYP_MASK; - } - else -#endif - { - base->TCR2 |= I2S_TCR2_DIV(divider / 2U - 1U); - } - } - - /* Set bitWidth */ - val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U; - if (format->protocol == kSAI_BusRightJustified) - { - base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(val); - } - else - { - if (IS_SAI_FLAG_SET(base->TCR4, I2S_TCR4_MF_MASK)) - { - base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(format->bitWidth - 1UL); - } - else - { - base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(0); - } - } - - /* Set mono or stereo */ - base->TMR = (uint32_t)format->stereo; - - /* if channel mask is not set, then format->channel must be set, - use it to get channel mask value */ - if (format->channelMask == 0U) - { - format->channelMask = 1U << format->channel; - } - - /* if channel nums is not set, calculate it here according to channelMask*/ - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), format->channelMask)) - { - channelNums++; - format->endChannel = i; - } - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), format->channelMask)) - { - format->channel = i; - break; - } - } - - format->channelNums = channelNums; -#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) - /* make sure combine mode disabled while multipe channel is used */ - if (format->channelNums > 1U) - { - base->TCR4 &= ~I2S_TCR4_FCOMB_MASK; - } -#endif - - /* Set data channel */ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; - base->TCR3 |= I2S_TCR3_TCE(format->channelMask); - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Set watermark */ - base->TCR1 = format->watermark; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * brief Configures the SAI Rx audio format. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_RxSetConfig - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. - * - * param base SAI base pointer. - * param format Pointer to the SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master - * clock, this value should equal the masterClockHz. - */ -void SAI_RxSetFormat(I2S_Type *base, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint32_t bclk = 0; - uint32_t val = 0; - uint8_t i = 0U, channelNums = 0U; - uint32_t divider = 0U; - - if (format->isFrameSyncCompact) - { - bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U); - val = (base->RCR4 & (~I2S_RCR4_SYWD_MASK)); - val |= I2S_RCR4_SYWD(format->bitWidth - 1U); - base->RCR4 = val; - } - else - { - bclk = format->sampleRate_Hz * 32U * 2U; - } - -/* Compute the mclk */ -#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) - /* Check if master clock divider enabled */ - if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK)) - { - SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz); - } -#endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */ - - /* Set bclk if needed */ - if (IS_SAI_FLAG_SET(base->RCR2, I2S_RCR2_BCD_MASK)) - { - base->RCR2 &= ~I2S_RCR2_DIV_MASK; - /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */ - divider = bclkSourceClockHz / bclk; - /* for the condition where the source clock is smaller than target bclk */ - if (divider == 0U) - { - divider++; - } - /* recheck the divider if properly or not, to make sure output blck not bigger than target*/ - if ((bclkSourceClockHz / divider) > bclk) - { - divider++; - } -#if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS) - /* if bclk same with MCLK, bypass the divider */ - if (divider == 1U) - { - base->RCR2 |= I2S_RCR2_BYP_MASK; - } - else -#endif - { - base->RCR2 |= I2S_RCR2_DIV(divider / 2U - 1U); - } - } - - /* Set bitWidth */ - val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U; - if (format->protocol == kSAI_BusRightJustified) - { - base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(val); - } - else - { - if (IS_SAI_FLAG_SET(base->RCR4, I2S_RCR4_MF_MASK)) - { - base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(format->bitWidth - 1UL); - } - else - { - base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(0UL); - } - } - - /* Set mono or stereo */ - base->RMR = (uint32_t)format->stereo; - - /* if channel mask is not set, then format->channel must be set, - use it to get channel mask value */ - if (format->channelMask == 0U) - { - format->channelMask = 1U << format->channel; - } - - /* if channel nums is not set, calculate it here according to channelMask*/ - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), format->channelMask)) - { - channelNums++; - format->endChannel = i; - } - } - - for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), format->channelMask)) - { - format->channel = i; - break; - } - } - - format->channelNums = channelNums; - -#if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) - /* make sure combine mode disabled while multipe channel is used */ - if (format->channelNums > 1U) - { - base->RCR4 &= ~I2S_RCR4_FCOMB_MASK; - } -#endif - - /* Set data channel */ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; - /* enable all the channel */ - base->RCR3 |= I2S_RCR3_RCE(format->channelMask); - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Set watermark */ - base->RCR1 = format->watermark; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * brief Sends data using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SAI base pointer. - * param channel Data channel used. - * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. - * param buffer Pointer to the data to be written. - * param size Bytes to be written. - */ -void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) -{ - uint32_t i = 0; - uint32_t bytesPerWord = bitWidth / 8U; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord); -#endif - - while (i < size) - { - /* Wait until it can write data */ - while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))) - { - } - - SAI_WriteNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord); - buffer += bytesPerWord; - i += bytesPerWord; - } - - /* Wait until the last data is sent */ - while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))) - { - } -} - -/*! - * brief Sends data to multi channel using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SAI base pointer. - * param channel Data channel used. - * param channelMask channel mask. - * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. - * param buffer Pointer to the data to be written. - * param size Bytes to be written. - */ -void SAI_WriteMultiChannelBlocking( - I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size) -{ - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint32_t i = 0, j = 0; - uint32_t bytesPerWord = bitWidth / 8U; - uint32_t channelNums = 0U, endChannel = 0U; - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord); -#endif - - for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), channelMask)) - { - channelNums++; - endChannel = i; - } - } - - bytesPerWord *= channelNums; - - while (j < size) - { - /* Wait until it can write data */ - while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))) - { - } - - SAI_WriteNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer, bytesPerWord); - buffer += bytesPerWord; - j += bytesPerWord; - } - - /* Wait until the last data is sent */ - while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))) - { - } -} - -/*! - * brief Receives multi channel data using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SAI base pointer. - * param channel Data channel used. - * param channelMask channel mask. - * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. - * param buffer Pointer to the data to be read. - * param size Bytes to be read. - */ -void SAI_ReadMultiChannelBlocking( - I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size) -{ - assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1); - - uint32_t i = 0, j = 0; - uint32_t bytesPerWord = bitWidth / 8U; - uint32_t channelNums = 0U, endChannel = 0U; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - bytesPerWord = base->RCR1 * bytesPerWord; -#endif - for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++) - { - if (IS_SAI_FLAG_SET((1UL << i), channelMask)) - { - channelNums++; - endChannel = i; - } - } - - bytesPerWord *= channelNums; - - while (j < size) - { - /* Wait until data is received */ - while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK))) - { - } - - SAI_ReadNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer, bytesPerWord); - buffer += bytesPerWord; - j += bytesPerWord; - } -} - -/*! - * brief Receives data using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SAI base pointer. - * param channel Data channel used. - * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits. - * param buffer Pointer to the data to be read. - * param size Bytes to be read. - */ -void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size) -{ - uint32_t i = 0; - uint32_t bytesPerWord = bitWidth / 8U; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - bytesPerWord = base->RCR1 * bytesPerWord; -#endif - - while (i < size) - { - /* Wait until data is received */ - while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK))) - { - } - - SAI_ReadNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord); - buffer += bytesPerWord; - i += bytesPerWord; - } -} - -/*! - * brief Initializes the SAI Tx handle. - * - * This function initializes the Tx handle for the SAI Tx transactional APIs. Call - * this function once to get the handle initialized. - * - * param base SAI base pointer - * param handle SAI handle pointer. - * param callback Pointer to the user callback function. - * param userData User parameter passed to the callback function - */ -void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) -{ - assert(handle != NULL); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - s_saiHandle[SAI_GetInstance(base)][0] = handle; - - handle->callback = callback; - handle->userData = userData; - handle->base = base; - - /* Set the isr pointer */ - s_saiTxIsr = SAI_TransferTxHandleIRQ; - - /* Enable Tx irq */ - (void)EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]); -} - -/*! - * brief Initializes the SAI Rx handle. - * - * This function initializes the Rx handle for the SAI Rx transactional APIs. Call - * this function once to get the handle initialized. - * - * param base SAI base pointer. - * param handle SAI handle pointer. - * param callback Pointer to the user callback function. - * param userData User parameter passed to the callback function. - */ -void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData) -{ - assert(handle != NULL); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - s_saiHandle[SAI_GetInstance(base)][1] = handle; - - handle->callback = callback; - handle->userData = userData; - handle->base = base; - - /* Set the isr pointer */ - s_saiRxIsr = SAI_TransferRxHandleIRQ; - - /* Enable Rx irq */ - (void)EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]); -} - -/*! - * brief Configures the SAI Tx audio format. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_TransferTxSetConfig - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. - * - * param base SAI base pointer. - * param handle SAI handle pointer. - * param format Pointer to the SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master - * clock, this value should equal the masterClockHz in format. - * return Status of this function. Return value is the status_t. - */ -status_t SAI_TransferTxSetFormat(I2S_Type *base, - sai_handle_t *handle, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert(handle != NULL); - - if ((bclkSourceClockHz < format->sampleRate_Hz) -#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) - || (mclkSourceClockHz < format->sampleRate_Hz) -#endif - ) - { - return kStatus_InvalidArgument; - } - - /* Copy format to handle */ - handle->bitWidth = (uint8_t)format->bitWidth; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->watermark = format->watermark; -#endif - - SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); - - handle->channel = format->channel; - /* used for multi channel */ - handle->channelMask = format->channelMask; - handle->channelNums = format->channelNums; - handle->endChannel = format->endChannel; - - return kStatus_Success; -} - -/*! - * brief Configures the SAI Rx audio format. - * - * deprecated Do not use this function. It has been superceded by @ref SAI_TransferRxSetConfig - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. - * - * param base SAI base pointer. - * param handle SAI handle pointer. - * param format Pointer to the SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master - * clock, this value should equal the masterClockHz in format. - * return Status of this function. Return value is one of status_t. - */ -status_t SAI_TransferRxSetFormat(I2S_Type *base, - sai_handle_t *handle, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert(handle != NULL); - - if ((bclkSourceClockHz < format->sampleRate_Hz) -#if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) - || (mclkSourceClockHz < format->sampleRate_Hz) -#endif - ) - { - return kStatus_InvalidArgument; - } - - /* Copy format to handle */ - handle->bitWidth = (uint8_t)format->bitWidth; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->watermark = format->watermark; -#endif - - SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); - - handle->channel = format->channel; - /* used for multi channel */ - handle->channelMask = format->channelMask; - handle->channelNums = format->channelNums; - handle->endChannel = format->endChannel; - - return kStatus_Success; -} - -/*! - * brief Performs an interrupt non-blocking send transfer on SAI. - * - * note This API returns immediately after the transfer initiates. - * Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether - * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer - * is finished. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - * param xfer Pointer to the sai_transfer_t structure. - * retval kStatus_Success Successfully started the data receive. - * retval kStatus_SAI_TxBusy Previous receive still not finished. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) -{ - assert(handle != NULL); - assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); - - /* Check if the queue is full */ - if (handle->saiQueue[handle->queueUser].data != NULL) - { - return kStatus_SAI_QueueFull; - } - - /* Add into queue */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->saiQueue[handle->queueUser].data = xfer->data; - handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Set the state to busy */ - handle->state = (uint32_t)kSAI_Busy; - - /* Enable interrupt */ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Use FIFO request interrupt and fifo error*/ - SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK); -#else - SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK); -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - /* Enable Tx transfer */ - SAI_TxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Performs an interrupt non-blocking receive transfer on SAI. - * - * note This API returns immediately after the transfer initiates. - * Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether - * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer - * is finished. - * - * param base SAI base pointer - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - * param xfer Pointer to the sai_transfer_t structure. - * retval kStatus_Success Successfully started the data receive. - * retval kStatus_SAI_RxBusy Previous receive still not finished. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer) -{ - assert(handle != NULL); - assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); - - /* Check if the queue is full */ - if (handle->saiQueue[handle->queueUser].data != NULL) - { - return kStatus_SAI_QueueFull; - } - - /* Add into queue */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->saiQueue[handle->queueUser].data = xfer->data; - handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Set state to busy */ - handle->state = (uint32_t)kSAI_Busy; - -/* Enable interrupt */ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Use FIFO request interrupt and fifo error*/ - SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK); -#else - SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK); -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - /* Enable Rx transfer */ - SAI_RxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Gets a set byte count. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - * param count Bytes count sent. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint32_t queueDriverIndex = handle->queueDriver; - - if (handle->state != (uint32_t)kSAI_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize); - } - - return status; -} - -/*! - * brief Gets a received byte count. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - * param count Bytes count received. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint32_t queueDriverIndex = handle->queueDriver; - - if (handle->state != (uint32_t)kSAI_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize); - } - - return status; -} - -/*! - * brief Aborts the current send. - * - * note This API can be called any time when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - */ -void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - /* Stop Tx transfer and disable interrupt */ - SAI_TxEnable(base, false); -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Use FIFO request interrupt and fifo error */ - SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK); -#else - SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK); -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - handle->state = (uint32_t)kSAI_Idle; - - /* Clear the queue */ - (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Aborts the current IRQ receive. - * - * note This API can be called when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base SAI base pointer - * param handle Pointer to the sai_handle_t structure which stores the transfer state. - */ -void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - /* Stop Tx transfer and disable interrupt */ - SAI_RxEnable(base, false); -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - /* Use FIFO request interrupt and fifo error */ - SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK); -#else - SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK); -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - handle->state = (uint32_t)kSAI_Idle; - - /* Clear the queue */ - (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Terminate all SAI send. - * - * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the - * current transfer slot, please call SAI_TransferAbortSend. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferTerminateSend(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - /* Abort the current transfer */ - SAI_TransferAbortSend(base, handle); - - /* Clear all the internal information */ - (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - - handle->queueUser = 0U; - handle->queueDriver = 0U; -} - -/*! - * brief Terminate all SAI receive. - * - * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the - * current transfer slot, please call SAI_TransferAbortReceive. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferTerminateReceive(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - /* Abort the current transfer */ - SAI_TransferAbortReceive(base, handle); - - /* Clear all the internal information */ - (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - - handle->queueUser = 0U; - handle->queueDriver = 0U; -} - -/*! - * brief Tx interrupt handler. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure. - */ -void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; - uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums; - - /* Handle Error */ - if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FEF_MASK)) - { - /* Clear FIFO error flag to continue transfer */ - SAI_TxClearStatusFlags(base, I2S_TCSR_FEF_MASK); - - /* Reset FIFO for safety */ - SAI_TxSoftwareReset(base, kSAI_ResetTypeFIFO); - - /* Call the callback */ - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData); - } - } - -/* Handle transfer */ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FRF_MASK)) - { - /* Judge if the data need to transmit is less than space */ - size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), - (size_t)(((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - handle->watermark) * dataSize)); - - /* Copy the data from sai buffer to FIFO */ - SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer, - size); - - /* Update the internal counter */ - handle->saiQueue[handle->queueDriver].dataSize -= size; - handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size); - } -#else - if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)) - { - size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); - - SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer, - size); - - /* Update internal counter */ - handle->saiQueue[handle->queueDriver].dataSize -= size; - handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size); - } -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - /* If finished a block, call the callback function */ - if (handle->saiQueue[handle->queueDriver].dataSize == 0U) - { - (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->saiQueue[handle->queueDriver].data == NULL) - { - SAI_TransferAbortSend(base, handle); - } -} - -/*! - * brief Tx interrupt handler. - * - * param base SAI base pointer. - * param handle Pointer to the sai_handle_t structure. - */ -void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle) -{ - assert(handle != NULL); - - uint8_t *buffer = handle->saiQueue[handle->queueDriver].data; - uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums; - - /* Handle Error */ - if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FEF_MASK)) - { - /* Clear FIFO error flag to continue transfer */ - SAI_RxClearStatusFlags(base, I2S_TCSR_FEF_MASK); - - /* Reset FIFO for safety */ - SAI_RxSoftwareReset(base, kSAI_ResetTypeFIFO); - - /* Call the callback */ - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData); - } - } - -/* Handle transfer */ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FRF_MASK)) - { - /* Judge if the data need to transmit is less than space */ - size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), handle->watermark * dataSize); - - /* Copy the data from sai buffer to FIFO */ - SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer, - size); - - /* Update the internal counter */ - handle->saiQueue[handle->queueDriver].dataSize -= size; - handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size); - } -#else - if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)) - { - size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize); - - SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer, - size); - - /* Update internal state */ - handle->saiQueue[handle->queueDriver].dataSize -= size; - handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size); - } -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ - - /* If finished a block, call the callback function */ - if (handle->saiQueue[handle->queueDriver].dataSize == 0U) - { - (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->saiQueue[handle->queueDriver].data == NULL) - { - SAI_TransferAbortReceive(base, handle); - } -} - -#if defined(I2S0) -void I2S0_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S0, s_saiHandle[0][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S0, s_saiHandle[0][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S0_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[0][0] != NULL); - s_saiTxIsr(I2S0, s_saiHandle[0][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S0_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[0][1] != NULL); - s_saiRxIsr(I2S0, s_saiHandle[0][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* I2S0*/ - -#if defined(I2S1) -void I2S1_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S1, s_saiHandle[1][1]); - } - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S1, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S1_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[1][0] != NULL); - s_saiTxIsr(I2S1, s_saiHandle[1][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S1_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[1][1] != NULL); - s_saiRxIsr(I2S1, s_saiHandle[1][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* I2S1*/ - -#if defined(I2S2) -void I2S2_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S2, s_saiHandle[2][1]); - } - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S2, s_saiHandle[2][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S2_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[2][0] != NULL); - s_saiTxIsr(I2S2, s_saiHandle[2][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S2_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[2][1] != NULL); - s_saiRxIsr(I2S2, s_saiHandle[2][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* I2S2*/ - -#if defined(I2S3) -void I2S3_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S3, s_saiHandle[3][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S3, s_saiHandle[3][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S3_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[3][0] != NULL); - s_saiTxIsr(I2S3, s_saiHandle[3][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S3_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[3][1] != NULL); - s_saiRxIsr(I2S3, s_saiHandle[3][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* I2S3*/ - -#if defined(I2S4) -void I2S4_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S4, s_saiHandle[4][1]); - } - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S4, s_saiHandle[4][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S4_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[4][0] != NULL); - s_saiTxIsr(I2S4, s_saiHandle[4][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S4_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[4][1] != NULL); - s_saiRxIsr(I2S4, s_saiHandle[4][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && (FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && defined(I2S5) && \ - defined(I2S6) -void I2S56_DriverIRQHandler(void) -{ - /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */ - I2S_Type *base = s_saiHandle[5][1]->base; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(base, s_saiHandle[5][1]); - } - - base = s_saiHandle[5][0]->base; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(base, s_saiHandle[5][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S56_Tx_DriverIRQHandler(void) -{ - /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */ - assert(s_saiHandle[5][0] != NULL); - s_saiTxIsr(s_saiHandle[5][0]->base, s_saiHandle[5][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S56_Rx_DriverIRQHandler(void) -{ - /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */ - assert(s_saiHandle[5][1] != NULL); - s_saiRxIsr(s_saiHandle[5][1]->base, s_saiHandle[5][1]); - SDK_ISR_EXIT_BARRIER; -} - -#else - -#if defined(I2S5) -void I2S5_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S5, s_saiHandle[5][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S5, s_saiHandle[5][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S5_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[5][0] != NULL); - s_saiTxIsr(I2S5, s_saiHandle[5][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S5_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[5][1] != NULL); - s_saiRxIsr(I2S5, s_saiHandle[5][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(I2S6) -void I2S6_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(I2S6, s_saiHandle[6][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(I2S6, s_saiHandle[6][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void I2S6_Tx_DriverIRQHandler(void) -{ - assert(s_saiHandle[6][0] != NULL); - s_saiTxIsr(I2S6, s_saiHandle[6][0]); - SDK_ISR_EXIT_BARRIER; -} - -void I2S6_Rx_DriverIRQHandler(void) -{ - assert(s_saiHandle[6][1] != NULL); - s_saiRxIsr(I2S6, s_saiHandle[6][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif - -#if defined(AUDIO__SAI0) -void AUDIO_SAI0_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI0, s_saiHandle[0][1]); - } - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI0, s_saiHandle[0][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* AUDIO__SAI0 */ - -#if defined(AUDIO__SAI1) -void AUDIO_SAI1_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI1, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI1, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* AUDIO__SAI1 */ - -#if defined(AUDIO__SAI2) -void AUDIO_SAI2_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI2, s_saiHandle[2][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI2, s_saiHandle[2][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* AUDIO__SAI2 */ - -#if defined(AUDIO__SAI3) -void AUDIO_SAI3_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI3, s_saiHandle[3][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI3, s_saiHandle[3][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif - -#if defined(AUDIO__SAI6) -void AUDIO_SAI6_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI6, s_saiHandle[6][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI6, s_saiHandle[6][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* AUDIO__SAI6 */ - -#if defined(AUDIO__SAI7) -void AUDIO_SAI7_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[7][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[7][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(AUDIO__SAI7, s_saiHandle[7][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[7][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[7][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(AUDIO__SAI7, s_saiHandle[7][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* AUDIO__SAI7 */ - -#if defined(ADMA__SAI0) -void ADMA_SAI0_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI0, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI0, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI0 */ - -#if defined(ADMA__SAI1) -void ADMA_SAI1_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI1, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI1, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI1 */ - -#if defined(ADMA__SAI2) -void ADMA_SAI2_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI2, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI2, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI2 */ - -#if defined(ADMA__SAI3) -void ADMA_SAI3_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI3, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI3, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI3 */ - -#if defined(ADMA__SAI4) -void ADMA_SAI4_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI4, s_saiHandle[1][1]); - } - -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI4, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI4 */ - -#if defined(ADMA__SAI5) -void ADMA_SAI5_INT_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && - SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(ADMA__SAI5, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && - SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(ADMA__SAI5, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* ADMA__SAI5 */ - -#if defined(SAI0) -void SAI0_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI0, s_saiHandle[0][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI0, s_saiHandle[0][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI0 */ - -#if defined(SAI1) -void SAI1_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI1, s_saiHandle[1][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI1, s_saiHandle[1][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI1 */ - -#if defined(SAI2) -void SAI2_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI2, s_saiHandle[2][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI2, s_saiHandle[2][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI2 */ - -#if defined(SAI3) -void SAI3_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI3, s_saiHandle[3][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI3, s_saiHandle[3][0]); - } - SDK_ISR_EXIT_BARRIER; -} - -void SAI3_TX_DriverIRQHandler(void) -{ - assert(s_saiHandle[3][0] != NULL); - s_saiTxIsr(SAI3, s_saiHandle[3][0]); - SDK_ISR_EXIT_BARRIER; -} - -void SAI3_RX_DriverIRQHandler(void) -{ - assert(s_saiHandle[3][1] != NULL); - s_saiRxIsr(SAI3, s_saiHandle[3][1]); - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI3 */ - -#if defined(SAI4) -void SAI4_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI4, s_saiHandle[4][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI4, s_saiHandle[4][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI4 */ - -#if defined(SAI5) -void SAI5_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI5, s_saiHandle[5][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI5, s_saiHandle[5][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI5 */ - -#if defined(SAI6) -void SAI6_DriverIRQHandler(void) -{ -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiRxIsr(SAI6, s_saiHandle[6][1]); - } -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK))) -#else - if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK), - (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK))) -#endif - { - s_saiTxIsr(SAI6, s_saiHandle[6][0]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif /* SAI6 */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai_edma.c deleted file mode 100644 index edaff64ef0..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_sai_edma.c +++ /dev/null @@ -1,707 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_sai_edma.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.sai_edma" -#endif - -/******************************************************************************* - * Definitions - ******************************************************************************/ -/* Used for 32byte aligned */ -#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)(address) + 32UL) & ~0x1FU) - -static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS; - -/*<! Structure definition for uart_edma_private_handle_t. The structure is private. */ -typedef struct sai_edma_private_handle -{ - I2S_Type *base; - sai_edma_handle_t *handle; -} sai_edma_private_handle_t; - -/*! @brief sai_edma_transfer_state, sai edma transfer state.*/ -enum -{ - kSAI_Busy = 0x0U, /*!< SAI is busy */ - kSAI_Idle, /*!< Transfer is done. */ -}; - -/*<! Private handle only used for internally. */ -static sai_edma_private_handle_t s_edmaPrivateHandle[ARRAY_SIZE(s_saiBases)][2]; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance number for SAI. - * - * @param base SAI base pointer. - */ -static uint32_t SAI_GetInstance(I2S_Type *base); - -/*! - * @brief SAI EDMA callback for send. - * - * @param handle pointer to sai_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/*! - * @brief SAI EDMA callback for receive. - * - * @param handle pointer to sai_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t SAI_GetInstance(I2S_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++) - { - if (s_saiBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_saiBases)); - - return instance; -} - -static void SAI_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData; - sai_edma_handle_t *saiHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); - saiHandle->queueDriver = (saiHandle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - if (saiHandle->callback != NULL) - { - (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_TxIdle, saiHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) - { - /* Disable DMA enable bit */ - SAI_TxEnableDMA(privHandle->base, kSAI_FIFORequestDMAEnable, false); - EDMA_AbortTransfer(handle); - } -} - -static void SAI_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - sai_edma_private_handle_t *privHandle = (sai_edma_private_handle_t *)userData; - sai_edma_handle_t *saiHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&saiHandle->saiQueue[saiHandle->queueDriver], 0, sizeof(sai_transfer_t)); - saiHandle->queueDriver = (saiHandle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - if (saiHandle->callback != NULL) - { - (saiHandle->callback)(privHandle->base, saiHandle, kStatus_SAI_RxIdle, saiHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (saiHandle->saiQueue[saiHandle->queueDriver].data == NULL) - { - /* Disable DMA enable bit */ - SAI_RxEnableDMA(privHandle->base, kSAI_FIFORequestDMAEnable, false); - EDMA_AbortTransfer(handle); - } -} - -/*! - * brief Initializes the SAI eDMA handle. - * - * This function initializes the SAI master DMA handle, which can be used for other SAI master transactional APIs. - * Usually, for a specified SAI instance, call this API once to get the initialized handle. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param base SAI peripheral base address. - * param callback Pointer to user callback function. - * param userData User parameter passed to the callback function. - * param dmaHandle eDMA handle pointer, this handle shall be static allocated by users. - */ -void SAI_TransferTxCreateHandleEDMA( - I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *txDmaHandle) -{ - assert((handle != NULL) && (txDmaHandle != NULL)); - - uint32_t instance = SAI_GetInstance(base); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set sai base to handle */ - handle->dmaHandle = txDmaHandle; - handle->callback = callback; - handle->userData = userData; - - /* Set SAI state to idle */ - handle->state = (uint32_t)kSAI_Idle; - - s_edmaPrivateHandle[instance][0].base = base; - s_edmaPrivateHandle[instance][0].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(txDmaHandle, (edma_tcd_t *)(STCD_ADDR(handle->tcd)), SAI_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel */ - EDMA_SetCallback(txDmaHandle, SAI_TxEDMACallback, &s_edmaPrivateHandle[instance][0]); -} - -/*! - * brief Initializes the SAI Rx eDMA handle. - * - * This function initializes the SAI slave DMA handle, which can be used for other SAI master transactional APIs. - * Usually, for a specified SAI instance, call this API once to get the initialized handle. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param base SAI peripheral base address. - * param callback Pointer to user callback function. - * param userData User parameter passed to the callback function. - * param dmaHandle eDMA handle pointer, this handle shall be static allocated by users. - */ -void SAI_TransferRxCreateHandleEDMA( - I2S_Type *base, sai_edma_handle_t *handle, sai_edma_callback_t callback, void *userData, edma_handle_t *rxDmaHandle) -{ - assert((handle != NULL) && (rxDmaHandle != NULL)); - - uint32_t instance = SAI_GetInstance(base); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set sai base to handle */ - handle->dmaHandle = rxDmaHandle; - handle->callback = callback; - handle->userData = userData; - - /* Set SAI state to idle */ - handle->state = (uint32_t)kSAI_Idle; - - s_edmaPrivateHandle[instance][1].base = base; - s_edmaPrivateHandle[instance][1].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(rxDmaHandle, STCD_ADDR(handle->tcd), SAI_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel */ - EDMA_SetCallback(rxDmaHandle, SAI_RxEDMACallback, &s_edmaPrivateHandle[instance][1]); -} - -/*! - * brief Configures the SAI Tx audio format. - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. This function also sets the eDMA parameter according to formatting requirements. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param format Pointer to SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If bit clock source is master - * clock, this value should equals to masterClockHz in format. - * retval kStatus_Success Audio format set successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - */ -void SAI_TransferTxSetFormatEDMA(I2S_Type *base, - sai_edma_handle_t *handle, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert((handle != NULL) && (format != NULL)); - - /* Configure the audio format to SAI registers */ - SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); - - /* Get the transfer size from format, this should be used in EDMA configuration */ - if (format->bitWidth == 24U) - { - handle->bytesPerFrame = 4U; - } - else - { - handle->bytesPerFrame = (uint8_t)(format->bitWidth / 8U); - } - - /* Update the data channel SAI used */ - handle->channel = format->channel; - - /* Clear the channel enable bits until do a send/receive */ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->count = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - format->watermark); -#else - handle->count = 1U; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * @brief Configures the SAI Tx. - * - * - * @param base SAI base pointer. - * @param handle SAI eDMA handle pointer. - * @param saiConfig sai configurations. - */ -void SAI_TransferTxSetConfigEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transceiver_t *saiConfig) -{ - assert((handle != NULL) && (saiConfig != NULL)); - - /* Configure the audio format to SAI registers */ - SAI_TxSetConfig(base, saiConfig); - - /* Get the transfer size from format, this should be used in EDMA configuration */ - if (saiConfig->serialData.dataWordLength == 24U) - { - handle->bytesPerFrame = 4U; - } - else - { - handle->bytesPerFrame = saiConfig->serialData.dataWordLength / 8U; - } - /* Update the data channel SAI used */ - handle->channel = saiConfig->startChannel; - - /* Clear the channel enable bits until do a send/receive */ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->count = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - saiConfig->fifo.fifoWatermark); -#else - handle->count = 1U; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * brief Configures the SAI Rx audio format. - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. This function also sets the eDMA parameter according to formatting requirements. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param format Pointer to SAI audio data format structure. - * param mclkSourceClockHz SAI master clock source frequency in Hz. - * param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is the master - * clock, this value should equal to masterClockHz in format. - * retval kStatus_Success Audio format set successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - */ -void SAI_TransferRxSetFormatEDMA(I2S_Type *base, - sai_edma_handle_t *handle, - sai_transfer_format_t *format, - uint32_t mclkSourceClockHz, - uint32_t bclkSourceClockHz) -{ - assert((handle != NULL) && (format != NULL)); - - /* Configure the audio format to SAI registers */ - SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz); - - /* Get the transfer size from format, this should be used in EDMA configuration */ - if (format->bitWidth == 24U) - { - handle->bytesPerFrame = 4U; - } - else - { - handle->bytesPerFrame = (uint8_t)(format->bitWidth / 8U); - } - - /* Update the data channel SAI used */ - handle->channel = format->channel; - - /* Clear the channel enable bits until do a send/receive */ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->count = format->watermark; -#else - handle->count = 1U; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * @brief Configures the SAI Rx. - * - * - * @param base SAI base pointer. - * @param handle SAI eDMA handle pointer. - * @param saiConfig sai configurations. - */ -void SAI_TransferRxSetConfigEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transceiver_t *saiConfig) -{ - assert((handle != NULL) && (saiConfig != NULL)); - - /* Configure the audio format to SAI registers */ - SAI_RxSetConfig(base, saiConfig); - - /* Get the transfer size from format, this should be used in EDMA configuration */ - if (saiConfig->serialData.dataWordLength == 24U) - { - handle->bytesPerFrame = 4U; - } - else - { - handle->bytesPerFrame = saiConfig->serialData.dataWordLength / 8U; - } - - /* Update the data channel SAI used */ - handle->channel = saiConfig->startChannel; - - /* Clear the channel enable bits until do a send/receive */ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; -#if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1) - handle->count = saiConfig->fifo.fifoWatermark; -#else - handle->count = 1U; -#endif /* FSL_FEATURE_SAI_FIFO_COUNT */ -} - -/*! - * brief Performs a non-blocking SAI transfer using DMA. - * - * note This interface returns immediately after the transfer initiates. Call - * SAI_GetTransferStatus to poll the transfer status and check whether the SAI transfer is finished. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param xfer Pointer to the DMA transfer structure. - * retval kStatus_Success Start a SAI eDMA send successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - * retval kStatus_TxBusy SAI is busy sending data. - */ -status_t SAI_TransferSendEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer) -{ - assert((handle != NULL) && (xfer != NULL)); - - edma_transfer_config_t config = {0}; - uint32_t destAddr = SAI_TxGetDataRegisterAddress(base, handle->channel); - - /* Check if input parameter invalid */ - if ((xfer->data == NULL) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - if (handle->saiQueue[handle->queueUser].data != NULL) - { - return kStatus_SAI_QueueFull; - } - - /* Change the state of handle */ - handle->state = (uint32_t)kSAI_Busy; - - /* Update the queue state */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->saiQueue[handle->queueUser].data = xfer->data; - handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, xfer->data, handle->bytesPerFrame, (uint32_t *)destAddr, handle->bytesPerFrame, - (uint32_t)handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_MemoryToPeripheral); - - /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ - handle->nbytes = handle->count * handle->bytesPerFrame; - - if (EDMA_SubmitTransfer(handle->dmaHandle, &config) != kStatus_Success) - { - return kStatus_SAI_QueueFull; - } - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaHandle); - - /* Enable DMA enable bit */ - SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); - - /* Enable SAI Tx clock */ - SAI_TxEnable(base, true); - - /* Enable the channel FIFO */ - base->TCR3 |= I2S_TCR3_TCE(1UL << handle->channel); - - return kStatus_Success; -} - -/*! - * brief Performs a non-blocking SAI receive using eDMA. - * - * note This interface returns immediately after the transfer initiates. Call - * the SAI_GetReceiveRemainingBytes to poll the transfer status and check whether the SAI transfer is finished. - * - * param base SAI base pointer - * param handle SAI eDMA handle pointer. - * param xfer Pointer to DMA transfer structure. - * retval kStatus_Success Start a SAI eDMA receive successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - * retval kStatus_RxBusy SAI is busy receiving data. - */ -status_t SAI_TransferReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle, sai_transfer_t *xfer) -{ - assert((handle != NULL) && (xfer != NULL)); - - edma_transfer_config_t config = {0}; - uint32_t srcAddr = SAI_RxGetDataRegisterAddress(base, handle->channel); - - /* Check if input parameter invalid */ - if ((xfer->data == NULL) || (xfer->dataSize == 0U)) - { - return kStatus_InvalidArgument; - } - - if (handle->saiQueue[handle->queueUser].data != NULL) - { - return kStatus_SAI_QueueFull; - } - - /* Change the state of handle */ - handle->state = (uint32_t)kSAI_Busy; - - /* Update queue state */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->saiQueue[handle->queueUser].data = xfer->data; - handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, (uint32_t *)srcAddr, handle->bytesPerFrame, xfer->data, handle->bytesPerFrame, - (uint32_t)handle->count * handle->bytesPerFrame, xfer->dataSize, kEDMA_PeripheralToMemory); - - /* Store the initially configured eDMA minor byte transfer count into the SAI handle */ - handle->nbytes = handle->count * handle->bytesPerFrame; - - if (EDMA_SubmitTransfer(handle->dmaHandle, &config) != kStatus_Success) - { - return kStatus_SAI_QueueFull; - } - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaHandle); - - /* Enable DMA enable bit */ - SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, true); - - /* Enable the channel FIFO */ - base->RCR3 |= I2S_RCR3_RCE(1UL << handle->channel); - - /* Enable SAI Rx clock */ - SAI_RxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Aborts a SAI transfer using eDMA. - * - * This function only aborts the current transfer slots, the other transfer slots' information still kept - * in the handler. If users want to terminate all transfer slots, just call SAI_TransferTerminateSendEDMA. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferAbortSendEDMA(I2S_Type *base, sai_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaHandle); - - /* Disable the channel FIFO */ - base->TCR3 &= ~I2S_TCR3_TCE_MASK; - - /* Disable DMA enable bit */ - SAI_TxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); - - /* Disable Tx */ - SAI_TxEnable(base, false); - - /* If Tx is disabled, reset the FIFO pointer and clear error flags */ - if ((base->TCSR & I2S_TCSR_TE_MASK) == 0UL) - { - base->TCSR |= (I2S_TCSR_FR_MASK | I2S_TCSR_SR_MASK); - base->TCSR &= ~I2S_TCSR_SR_MASK; - } - - /* Handle the queue index */ - (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Set the handle state */ - handle->state = (uint32_t)kSAI_Idle; -} - -/*! - * brief Aborts a SAI receive using eDMA. - * - * This function only aborts the current transfer slots, the other transfer slots' information still kept - * in the handler. If users want to terminate all transfer slots, just call SAI_TransferTerminateReceiveEDMA. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferAbortReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaHandle); - - /* Disable the channel FIFO */ - base->RCR3 &= ~I2S_RCR3_RCE_MASK; - - /* Disable DMA enable bit */ - SAI_RxEnableDMA(base, kSAI_FIFORequestDMAEnable, false); - - /* Disable Rx */ - SAI_RxEnable(base, false); - - /* If Rx is disabled, reset the FIFO pointer and clear error flags */ - if ((base->RCSR & I2S_RCSR_RE_MASK) == 0UL) - { - base->RCSR |= (I2S_RCSR_FR_MASK | I2S_RCSR_SR_MASK); - base->RCSR &= ~I2S_RCSR_SR_MASK; - } - - /* Handle the queue index */ - (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t)); - handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE; - - /* Set the handle state */ - handle->state = (uint32_t)kSAI_Idle; -} - -/*! - * brief Terminate all SAI send. - * - * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the - * current transfer slot, please call SAI_TransferAbortSendEDMA. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferTerminateSendEDMA(I2S_Type *base, sai_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Abort the current transfer */ - SAI_TransferAbortSendEDMA(base, handle); - - /* Clear all the internal information */ - (void)memset(handle->tcd, 0, sizeof(handle->tcd)); - (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - - handle->queueUser = 0U; - handle->queueDriver = 0U; -} - -/*! - * brief Terminate all SAI receive. - * - * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the - * current transfer slot, please call SAI_TransferAbortReceiveEDMA. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - */ -void SAI_TransferTerminateReceiveEDMA(I2S_Type *base, sai_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Abort the current transfer */ - SAI_TransferAbortReceiveEDMA(base, handle); - - /* Clear all the internal information */ - (void)memset(handle->tcd, 0, sizeof(handle->tcd)); - (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - - handle->queueUser = 0U; - handle->queueDriver = 0U; -} - -/*! - * brief Gets byte count sent by SAI. - * - * param base SAI base pointer. - * param handle SAI eDMA handle pointer. - * param count Bytes count sent by SAI. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. - */ -status_t SAI_TransferGetSendCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kSAI_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); - } - - return status; -} - -/*! - * brief Gets byte count received by SAI. - * - * param base SAI base pointer - * param handle SAI eDMA handle pointer. - * param count Bytes count received by SAI. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. - */ -status_t SAI_TransferGetReceiveCountEDMA(I2S_Type *base, sai_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kSAI_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaHandle->base, handle->dmaHandle->channel)); - } - - return status; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_semc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_semc.c deleted file mode 100644 index 49b22fba43..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_semc.c +++ /dev/null @@ -1,1148 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_semc.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.semc" -#endif - -/*! @brief Define macros for SEMC driver. */ -#define SEMC_IPCOMMANDDATASIZEBYTEMAX (4U) -#define SEMC_IPCOMMANDMAGICKEY (0xA55A) -#define SEMC_IOCR_PINMUXBITWIDTH (0x3U) -#define SEMC_IOCR_NAND_CE (4U) -#define SEMC_IOCR_NOR_CE (5U) -#define SEMC_IOCR_NOR_CE_A8 (2U) -#define SEMC_IOCR_PSRAM_CE (6U) -#define SEMC_IOCR_PSRAM_CE_A8 (3U) -#define SEMC_IOCR_DBI_CSX (7U) -#define SEMC_IOCR_DBI_CSX_A8 (4U) -#define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE (24U) -#define SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX (28U) -#define SEMC_BMCR0_TYPICAL_WQOS (5U) -#define SEMC_BMCR0_TYPICAL_WAGE (8U) -#define SEMC_BMCR0_TYPICAL_WSH (0x40U) -#define SEMC_BMCR0_TYPICAL_WRWS (0x10U) -#define SEMC_BMCR1_TYPICAL_WQOS (5U) -#define SEMC_BMCR1_TYPICAL_WAGE (8U) -#define SEMC_BMCR1_TYPICAL_WPH (0x60U) -#define SEMC_BMCR1_TYPICAL_WBR (0x40U) -#define SEMC_BMCR1_TYPICAL_WRWS (0x24U) -#define SEMC_STARTADDRESS (0x80000000U) -#define SEMC_ENDADDRESS (0xDFFFFFFFU) -#define SEMC_BR_MEMSIZE_MIN (4U) -#define SEMC_BR_MEMSIZE_OFFSET (2U) -#define SEMC_BR_MEMSIZE_MAX (4U * 1024U * 1024U) -#define SEMC_SDRAM_MODESETCAL_OFFSET (4U) -#define SEMC_BR_REG_NUM (9U) -#define SEMC_BYTE_NUMBIT (8U) -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for SEMC module. - * - * @param base SEMC peripheral base address - */ -static uint32_t SEMC_GetInstance(SEMC_Type *base); - -/*! - * @brief Covert the input memory size to internal register set value. - * - * @param base SEMC peripheral base address - * @param size_kbytes SEMC memory size in unit of kbytes. - * @param sizeConverted SEMC converted memory size to 0 ~ 0x1F. - * @return Execution status. - */ -static status_t SEMC_CovertMemorySize(SEMC_Type *base, uint32_t size_kbytes, uint8_t *sizeConverted); - -/*! - * @brief Covert the external timing nanosecond to internal clock cycle. - * - * @param time_ns SEMC external time interval in unit of nanosecond. - * @param clkSrc_Hz SEMC clock source frequency. - * @return The changed internal clock cycle. - */ -static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz); - -/*! - * @brief Configure IP command. - * - * @param base SEMC peripheral base address. - * @param size_bytes SEMC IP command data size. - * @return Execution status. - */ -static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes); - -/*! - * @brief Check if the IP command has finished. - * - * @param base SEMC peripheral base address. - * @return Execution status. - */ -static status_t SEMC_IsIPCommandDone(SEMC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to SEMC clocks for each instance. */ -static const clock_ip_name_t s_semcClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_CLOCKS; -static const clock_ip_name_t s_semcExtClock[FSL_FEATURE_SOC_SEMC_COUNT] = SEMC_EXSC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! @brief Pointers to SEMC bases for each instance. */ -static SEMC_Type *const s_semcBases[] = SEMC_BASE_PTRS; -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t SEMC_GetInstance(SEMC_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_semcBases); instance++) - { - if (s_semcBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_semcBases)); - - return instance; -} - -static status_t SEMC_CovertMemorySize(SEMC_Type *base, uint32_t size_kbytes, uint8_t *sizeConverted) -{ - assert(sizeConverted != NULL); - uint32_t memsize; - status_t status = kStatus_Success; - - if ((size_kbytes < SEMC_BR_MEMSIZE_MIN) || (size_kbytes > SEMC_BR_MEMSIZE_MAX)) - { - status = kStatus_SEMC_InvalidMemorySize; - } - else - { - *sizeConverted = 0U; - memsize = size_kbytes / 8U; - while (memsize != 0x00U) - { - memsize >>= 1U; - (*sizeConverted)++; - } - } - - return status; -} - -static uint8_t SEMC_ConvertTiming(uint32_t time_ns, uint32_t clkSrc_Hz) -{ - assert(clkSrc_Hz > 0x00UL); - - uint8_t clockCycles = 0; - uint32_t tClk_us; - - clkSrc_Hz /= 1000000UL; - tClk_us = 1000000UL / clkSrc_Hz; - - while ((tClk_us * clockCycles) < (time_ns * 1000UL)) - { - clockCycles++; - } - - return (clockCycles - 1U); -} - -static status_t SEMC_ConfigureIPCommand(SEMC_Type *base, uint8_t size_bytes) -{ - status_t status = kStatus_Success; - - if ((size_bytes > SEMC_IPCOMMANDDATASIZEBYTEMAX) || (size_bytes == 0x00U)) - { - status = kStatus_SEMC_InvalidIpcmdDataSize; - } - else - { - /* Set data size. */ - /* Note: It is better to set data size as the device data port width when transferring - * device command data. But for device memory data transfer, it can be set freely. - * Note: If the data size is greater than data port width, for example, datsz = 4, data port = 16bit, - * then the 4-byte data transfer will be split into two 2-byte transfers, the slave address - * will be switched automatically according to connected device type*/ - base->IPCR1 = SEMC_IPCR1_DATSZ(size_bytes); - /* Clear data size. */ - base->IPCR2 = 0; - /* Set data size. */ - if (size_bytes < 4U) - { - base->IPCR2 |= SEMC_IPCR2_BM3_MASK; - } - if (size_bytes < 3U) - { - base->IPCR2 |= SEMC_IPCR2_BM2_MASK; - } - if (size_bytes < 2U) - { - base->IPCR2 |= SEMC_IPCR2_BM1_MASK; - } - } - - return status; -} - -static status_t SEMC_IsIPCommandDone(SEMC_Type *base) -{ - status_t status = kStatus_Success; - - /* Poll status bit till command is done*/ - while ((base->INTR & (uint32_t)SEMC_INTR_IPCMDDONE_MASK) == 0x00U) - { - }; - - /* Clear status bit */ - base->INTR |= SEMC_INTR_IPCMDDONE_MASK; - - /* Check error status */ - if ((base->INTR & (uint32_t)SEMC_INTR_IPCMDERR_MASK) != 0x00U) - { - base->INTR |= SEMC_INTR_IPCMDERR_MASK; - status = kStatus_SEMC_IpCommandExecutionError; - } - - return status; -} - -/*! - * brief Gets the SEMC default basic configuration structure. - * - * The purpose of this API is to get the default SEMC - * configure structure for SEMC_Init(). User may use the initialized - * structure unchanged in SEMC_Init(), or modify some fields of the - * structure before calling SEMC_Init(). - * Example: - code - semc_config_t config; - SEMC_GetDefaultConfig(&config); - endcode - * param config The SEMC configuration structure pointer. - */ -void SEMC_GetDefaultConfig(semc_config_t *config) -{ - assert(config != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - semc_queuea_weight_struct_t *queueaWeight = &(config->queueWeight.queueaWeight.queueaConfig); - semc_queueb_weight_struct_t *queuebWeight = &(config->queueWeight.queuebWeight.queuebConfig); - - /* Get default settings. */ - config->dqsMode = kSEMC_Loopbackinternal; - config->cmdTimeoutCycles = 0; - config->busTimeoutCycles = 0x1F; - - queueaWeight->qos = SEMC_BMCR0_TYPICAL_WQOS; - queueaWeight->aging = SEMC_BMCR0_TYPICAL_WAGE; - queueaWeight->slaveHitSwith = SEMC_BMCR0_TYPICAL_WSH; - queueaWeight->slaveHitNoswitch = SEMC_BMCR0_TYPICAL_WRWS; - queuebWeight->qos = SEMC_BMCR1_TYPICAL_WQOS; - queuebWeight->aging = SEMC_BMCR1_TYPICAL_WAGE; - queuebWeight->slaveHitSwith = SEMC_BMCR1_TYPICAL_WRWS; - queuebWeight->weightPagehit = SEMC_BMCR1_TYPICAL_WPH; - queuebWeight->bankRotation = SEMC_BMCR1_TYPICAL_WBR; -} - -/*! - * brief Initializes SEMC. - * This function ungates the SEMC clock and initializes SEMC. - * This function must be called before calling any other SEMC driver functions. - * - * param base SEMC peripheral base address. - * param configure The SEMC configuration structure pointer. - */ -void SEMC_Init(SEMC_Type *base, semc_config_t *configure) -{ - assert(configure != NULL); - - uint8_t index = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Un-gate sdram controller clock. */ - CLOCK_EnableClock(s_semcClock[SEMC_GetInstance(base)]); - CLOCK_EnableClock(s_semcExtClock[SEMC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Initialize all BR to zero due to the default base address set. */ - for (index = 0; index < SEMC_BR_REG_NUM; index++) - { - base->BR[index] = 0; - } - - /* Software reset for SEMC internal logical . */ - base->MCR = SEMC_MCR_SWRST_MASK; - while ((base->MCR & (uint32_t)SEMC_MCR_SWRST_MASK) != 0x00U) - { - } - - /* Configure, disable module first. */ - base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_BTO(configure->busTimeoutCycles) | - SEMC_MCR_CTO(configure->cmdTimeoutCycles) | SEMC_MCR_DQSMD(configure->dqsMode); - - /* Configure Queue 0/1 for AXI bus. */ - base->BMCR0 = (uint32_t)(configure->queueWeight.queueaWeight.queueaValue); - base->BMCR1 = (uint32_t)(configure->queueWeight.queuebWeight.queuebValue); - - /* Enable SEMC. */ - base->MCR &= ~SEMC_MCR_MDIS_MASK; -} - -/*! - * brief Deinitializes the SEMC module and gates the clock. - * This function gates the SEMC clock. As a result, the SEMC - * module doesn't work after calling this function. - * - * param base SEMC peripheral base address. - */ -void SEMC_Deinit(SEMC_Type *base) -{ - /* Disable module. Check there is no pending command before disable module. */ - while ((base->STS0 & (uint32_t)SEMC_STS0_IDLE_MASK) == 0x00U) - { - ; - } - - base->MCR |= SEMC_MCR_MDIS_MASK | SEMC_MCR_SWRST_MASK; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable SDRAM clock. */ - CLOCK_DisableClock(s_semcClock[SEMC_GetInstance(base)]); - CLOCK_DisableClock(s_semcExtClock[SEMC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Configures SDRAM controller in SEMC. - * - * param base SEMC peripheral base address. - * param cs The chip selection. - * param config The sdram configuration. - * param clkSrc_Hz The SEMC clock frequency. - */ -status_t SEMC_ConfigureSDRAM(SEMC_Type *base, semc_sdram_cs_t cs, semc_sdram_config_t *config, uint32_t clkSrc_Hz) -{ - assert(config != NULL); - assert(clkSrc_Hz > 0x00U); - assert(config->refreshBurstLen > 0x00U); - - uint8_t memsize; - status_t result = kStatus_Success; - uint16_t prescale = (uint16_t)(config->tPrescalePeriod_Ns / 16U / (1000000000U / clkSrc_Hz)); - uint32_t refresh; - uint32_t urgentRef; - uint32_t idle; - uint32_t mode; - uint32_t timing; - - if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) - { - return kStatus_SEMC_InvalidBaseAddress; - } - - if (config->csxPinMux == kSEMC_MUXA8) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - - if (prescale > 256U) - { - return kStatus_SEMC_InvalidTimerSetting; - } - - refresh = config->refreshPeriod_nsPerRow / config->tPrescalePeriod_Ns; - urgentRef = config->refreshUrgThreshold / config->tPrescalePeriod_Ns; - idle = config->tIdleTimeout_Ns / config->tPrescalePeriod_Ns; - - uint32_t iocReg = base->IOCR & (~((uint32_t)SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->csxPinMux)); - - /* Base control. */ - result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - - base->BR[cs] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - base->SDRAMCR0 = SEMC_SDRAMCR0_PS(config->portSize) | SEMC_SDRAMCR0_BL(config->burstLen) | - SEMC_SDRAMCR0_COL(config->columnAddrBitNum) | SEMC_SDRAMCR0_CL(config->casLatency); - /* IOMUX setting. */ - if (cs != kSEMC_SDRAM_CS0) - { - base->IOCR = iocReg | ((uint32_t)cs << (uint32_t)config->csxPinMux); - } - - base->IOCR &= ~SEMC_IOCR_MUX_A8_MASK; - - timing = SEMC_SDRAMCR1_PRE2ACT(SEMC_ConvertTiming(config->tPrecharge2Act_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR1_ACT2RW(SEMC_ConvertTiming(config->tAct2ReadWrite_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR1_RFRC(SEMC_ConvertTiming(config->tRefreshRecovery_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR1_WRC(SEMC_ConvertTiming(config->tWriteRecovery_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR1_CKEOFF(SEMC_ConvertTiming(config->tCkeOff_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR1_ACT2PRE(SEMC_ConvertTiming(config->tAct2Prechage_Ns, clkSrc_Hz)); - /* SDRAMCR1 timing setting. */ - base->SDRAMCR1 = timing; - - timing = SEMC_SDRAMCR2_SRRC(SEMC_ConvertTiming(config->tSelfRefRecovery_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR2_REF2REF(SEMC_ConvertTiming(config->tRefresh2Refresh_Ns, clkSrc_Hz)); - timing |= SEMC_SDRAMCR2_ACT2ACT(SEMC_ConvertTiming(config->tAct2Act_Ns, clkSrc_Hz)) | SEMC_SDRAMCR2_ITO(idle); - /* SDRAMCR2 timing setting. */ - base->SDRAMCR2 = timing; - - /* SDRAMCR3 timing setting. */ - base->SDRAMCR3 = SEMC_SDRAMCR3_REBL((uint32_t)config->refreshBurstLen - 1UL) | - /* N * 16 * 1s / clkSrc_Hz = config->tPrescalePeriod_Ns */ - SEMC_SDRAMCR3_PRESCALE(prescale) | SEMC_SDRAMCR3_RT(refresh) | SEMC_SDRAMCR3_UT(urgentRef); - - SEMC->IPCR1 = 0x2U; - SEMC->IPCR2 = 0U; - - result = - SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_Prechargeall, 0, NULL); - if (result != kStatus_Success) - { - return result; - } - result = - SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_AutoRefresh, 0, NULL); - if (result != kStatus_Success) - { - return result; - } - result = - SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_AutoRefresh, 0, NULL); - if (result != kStatus_Success) - { - return result; - } - /* Mode setting value. */ - mode = (uint32_t)config->burstLen | (((uint32_t)config->casLatency) << SEMC_SDRAM_MODESETCAL_OFFSET); - result = - SEMC_SendIPCommand(base, kSEMC_MemType_SDRAM, config->address, (uint32_t)kSEMC_SDRAMCM_Modeset, mode, NULL); - if (result != kStatus_Success) - { - return result; - } - /* Enables refresh */ - base->SDRAMCR3 |= SEMC_SDRAMCR3_REN_MASK; - - return kStatus_Success; -} - -/*! - * brief Configures NAND controller in SEMC. - * - * param base SEMC peripheral base address. - * param config The nand configuration. - * param clkSrc_Hz The SEMC clock frequency. - */ -status_t SEMC_ConfigureNAND(SEMC_Type *base, semc_nand_config_t *config, uint32_t clkSrc_Hz) -{ - assert(config != NULL); - assert(config->timingConfig != NULL); - - uint8_t memsize; - status_t result; - uint32_t timing; - - if ((config->axiAddress < SEMC_STARTADDRESS) || (config->axiAddress > SEMC_ENDADDRESS)) - { - return kStatus_SEMC_InvalidBaseAddress; - } - - if (config->cePinMux == kSEMC_MUXRDY) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - - uint32_t iocReg = - base->IOCR & (~(((uint32_t)SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux) | SEMC_IOCR_MUX_RDY_MASK)); - - /* Base control. */ - if (config->rdyactivePolarity == kSEMC_RdyActivehigh) - { - base->MCR |= SEMC_MCR_WPOL1_MASK; - } - else - { - base->MCR &= ~SEMC_MCR_WPOL1_MASK; - } - result = SEMC_CovertMemorySize(base, config->axiMemsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - base->BR[4] = (config->axiAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - - result = SEMC_CovertMemorySize(base, config->ipgMemsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - base->BR[8] = (config->ipgAddress & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - - /* IOMUX setting. */ - if ((uint32_t)config->cePinMux != 0x00U) - { - base->IOCR = iocReg | ((uint32_t)SEMC_IOCR_NAND_CE << (uint32_t)config->cePinMux); - } - else - { - base->IOCR = iocReg | ((uint32_t)1U << (uint32_t)config->cePinMux); - } - - base->NANDCR0 = SEMC_NANDCR0_PS(config->portSize) | SEMC_NANDCR0_BL(config->burstLen) | - SEMC_NANDCR0_EDO(config->edoModeEnabled) | SEMC_NANDCR0_COL(config->columnAddrBitNum); - - timing = SEMC_NANDCR1_CES(SEMC_ConvertTiming(config->timingConfig->tCeSetup_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_CEH(SEMC_ConvertTiming(config->timingConfig->tCeHold_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_WEL(SEMC_ConvertTiming(config->timingConfig->tWeLow_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_WEH(SEMC_ConvertTiming(config->timingConfig->tWeHigh_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_REL(SEMC_ConvertTiming(config->timingConfig->tReLow_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_REH(SEMC_ConvertTiming(config->timingConfig->tReHigh_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_TA(SEMC_ConvertTiming(config->timingConfig->tTurnAround_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR1_CEITV(SEMC_ConvertTiming(config->timingConfig->tCeInterval_Ns, clkSrc_Hz)); - /* NANDCR1 timing setting. */ - base->NANDCR1 = timing; - - timing = SEMC_NANDCR2_TWHR(SEMC_ConvertTiming(config->timingConfig->tWehigh2Relow_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR2_TRHW(SEMC_ConvertTiming(config->timingConfig->tRehigh2Welow_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR2_TADL(SEMC_ConvertTiming(config->timingConfig->tAle2WriteStart_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR2_TRR(SEMC_ConvertTiming(config->timingConfig->tReady2Relow_Ns, clkSrc_Hz)); - timing |= SEMC_NANDCR2_TWB(SEMC_ConvertTiming(config->timingConfig->tWehigh2Busy_Ns, clkSrc_Hz)); - - /* NANDCR2 timing setting. */ - base->NANDCR2 = timing; - - /* NANDCR3 timing setting. */ - base->NANDCR3 = (uint32_t)config->arrayAddrOption; - return kStatus_Success; -} - -/*! - * brief Configures NOR controller in SEMC. - * - * param base SEMC peripheral base address. - * param config The nor configuration. - * param clkSrc_Hz The SEMC clock frequency. - */ -status_t SEMC_ConfigureNOR(SEMC_Type *base, semc_nor_config_t *config, uint32_t clkSrc_Hz) -{ - assert(config != NULL); - - uint8_t memsize; - status_t result; - uint32_t timing; - - if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) - { - return kStatus_SEMC_InvalidBaseAddress; - } - - uint32_t iocReg = base->IOCR & (~((uint32_t)SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux)); - uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ? - (SEMC_IOCR_NOR_CE - 1U) : - ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_NOR_CE_A8 : SEMC_IOCR_NOR_CE); - - /* IOMUX setting. */ - base->IOCR = iocReg | (muxCe << (uint32_t)config->cePinMux); - /* Address bit setting. */ - if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE) - { - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1U)) - { - /* Address bit 24 (A24) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX0_MASK; - if (config->cePinMux == kSEMC_MUXCSX0) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2U)) - { - /* Address bit 25 (A25) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX1_MASK; - if (config->cePinMux == kSEMC_MUXCSX1) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3U)) - { - /* Address bit 26 (A26) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX2_MASK; - if (config->cePinMux == kSEMC_MUXCSX2) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4U)) - { - if (config->addr27 == kSEMC_NORA27_MUXCSX3) - { - /* Address bit 27 (A27) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX3_MASK; - } - else if (config->addr27 == kSEMC_NORA27_MUXRDY) - { - base->IOCR |= SEMC_IOCR_MUX_RDY_MASK; - } - else - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - if (config->cePinMux == kSEMC_MUXCSX3) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX) - { - return kStatus_SEMC_InvalidAddressPortWidth; - } - } - - /* Base control. */ - if (config->rdyactivePolarity == kSEMC_RdyActivehigh) - { - base->MCR |= SEMC_MCR_WPOL0_MASK; - } - else - { - base->MCR &= ~SEMC_MCR_WPOL0_MASK; - } - result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - base->BR[5] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - base->NORCR0 = SEMC_NORCR0_PS(config->portSize) | SEMC_NORCR0_BL(config->burstLen) | - SEMC_NORCR0_AM(config->addrMode) | SEMC_NORCR0_ADVP(config->advActivePolarity) | - SEMC_NORCR0_COL(config->columnAddrBitNum); - - timing = SEMC_NORCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz)); - - /* NORCR1 timing setting. */ - base->NORCR1 = timing; - - timing = SEMC_NORCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz)); -#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME) - timing |= SEMC_NORCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz)); -#endif /* FSL_FEATURE_SEMC_HAS_NOR_WDS_TIME */ -#if defined(FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) && (FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME) - timing |= SEMC_NORCR2_WDH(SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz)); -#endif /* FSL_FEATURE_SEMC_HAS_NOR_WDH_TIME */ - timing |= SEMC_NORCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR2_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz)); - timing |= SEMC_NORCR2_LC(config->latencyCount) | SEMC_NORCR2_RD(config->readCycle); - - /* NORCR2 timing setting. */ - base->NORCR2 = timing; - - return SEMC_ConfigureIPCommand(base, ((uint8_t)config->portSize + 1U)); -} - -/*! - * brief Configures SRAM controller in SEMC. - * - * param base SEMC peripheral base address. - * param config The sram configuration. - * param clkSrc_Hz The SEMC clock frequency. - */ -status_t SEMC_ConfigureSRAM(SEMC_Type *base, semc_sram_config_t *config, uint32_t clkSrc_Hz) -{ - assert(config != NULL); - - uint8_t memsize; - uint32_t timing; - status_t result = kStatus_Success; - - if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) - { - return kStatus_SEMC_InvalidBaseAddress; - } - - uint32_t iocReg = base->IOCR & (~((uint32_t)SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->cePinMux)); - uint32_t muxCe = (config->cePinMux == kSEMC_MUXRDY) ? - (SEMC_IOCR_PSRAM_CE - 1U) : - ((config->cePinMux == kSEMC_MUXA8) ? SEMC_IOCR_PSRAM_CE_A8 : SEMC_IOCR_PSRAM_CE); - - /* IOMUX setting. */ - base->IOCR = iocReg | (muxCe << (uint32_t)config->cePinMux); - /* Address bit setting. */ - if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE) - { - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 1U)) - { - /* Address bit 24 (A24) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX0_MASK; - if (config->cePinMux == kSEMC_MUXCSX0) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 2U)) - { - /* Address bit 25 (A25) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX1_MASK; - if (config->cePinMux == kSEMC_MUXCSX1) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 3U)) - { - /* Address bit 26 (A26) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX2_MASK; - if (config->cePinMux == kSEMC_MUXCSX2) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth >= (SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHBASE + 4U)) - { - if (config->addr27 == kSEMC_NORA27_MUXCSX3) - { - /* Address bit 27 (A27) */ - base->IOCR &= ~(uint32_t)SEMC_IOCR_MUX_CSX3_MASK; - } - else if (config->addr27 == kSEMC_NORA27_MUXRDY) - { - base->IOCR |= SEMC_IOCR_MUX_RDY_MASK; - } - else - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - - if (config->cePinMux == kSEMC_MUXCSX3) - { - return kStatus_SEMC_InvalidSwPinmuxSelection; - } - } - if (config->addrPortWidth > SEMC_NORFLASH_SRAM_ADDR_PORTWIDTHMAX) - { - return kStatus_SEMC_InvalidAddressPortWidth; - } - } - /* Base control. */ - result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - base->BR[6] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - - /* SRAMCR0 timing setting. */ - base->SRAMCR0 = SEMC_SRAMCR0_PS(config->portSize) | SEMC_SRAMCR0_BL(config->burstLen) | - SEMC_SRAMCR0_AM(config->addrMode) | SEMC_SRAMCR0_ADVP(config->advActivePolarity) | - SEMC_SRAMCR0_COL_MASK; - - timing = SEMC_SRAMCR1_CES(SEMC_ConvertTiming(config->tCeSetup_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_CEH(SEMC_ConvertTiming(config->tCeHold_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_AS(SEMC_ConvertTiming(config->tAddrSetup_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_AH(SEMC_ConvertTiming(config->tAddrHold_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_WEL(SEMC_ConvertTiming(config->tWeLow_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_WEH(SEMC_ConvertTiming(config->tWeHigh_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_REL(SEMC_ConvertTiming(config->tReLow_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR1_REH(SEMC_ConvertTiming(config->tReHigh_Ns, clkSrc_Hz)); - - /* SRAMCR1 timing setting. */ - base->SRAMCR1 = timing; - - timing = SEMC_SRAMCR2_WDS(SEMC_ConvertTiming(config->tWriteSetup_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR2_WDH((uint32_t)SEMC_ConvertTiming(config->tWriteHold_Ns, clkSrc_Hz) + 1UL); - timing |= SEMC_SRAMCR2_TA(SEMC_ConvertTiming(config->tTurnAround_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR2_AWDH(SEMC_ConvertTiming(config->tAddr2WriteHold_Ns, clkSrc_Hz)); - timing |= SEMC_SRAMCR2_LC(config->latencyCount) | SEMC_SRAMCR2_RD((uint32_t)config->readCycle - 1UL); - timing |= SEMC_SRAMCR2_CEITV(SEMC_ConvertTiming(config->tCeInterval_Ns, clkSrc_Hz)); - - /* SRAMCR2 timing setting. */ - base->SRAMCR2 = timing; - - return result; -} - -/*! - * brief Configures DBI controller in SEMC. - * - * param base SEMC peripheral base address. - * param config The dbi configuration. - * param clkSrc_Hz The SEMC clock frequency. - */ -status_t SEMC_ConfigureDBI(SEMC_Type *base, semc_dbi_config_t *config, uint32_t clkSrc_Hz) -{ - assert(config != NULL); - - uint8_t memsize; - status_t result; - uint32_t timing; - - if ((config->address < SEMC_STARTADDRESS) || (config->address > SEMC_ENDADDRESS)) - { - return kStatus_SEMC_InvalidBaseAddress; - } - - uint32_t iocReg = base->IOCR & (~((uint32_t)SEMC_IOCR_PINMUXBITWIDTH << (uint32_t)config->csxPinMux)); - uint32_t muxCsx = (config->csxPinMux == kSEMC_MUXRDY) ? - (SEMC_IOCR_DBI_CSX - 1U) : - ((config->csxPinMux == kSEMC_MUXA8) ? SEMC_IOCR_DBI_CSX_A8 : SEMC_IOCR_DBI_CSX); - - /* IOMUX setting. */ - base->IOCR = iocReg | (muxCsx << (uint32_t)config->csxPinMux); - /* Base control. */ - result = SEMC_CovertMemorySize(base, config->memsize_kbytes, &memsize); - if (result != kStatus_Success) - { - return result; - } - base->BR[7] = (config->address & SEMC_BR_BA_MASK) | SEMC_BR_MS(memsize) | SEMC_BR_VLD_MASK; - - /* DBICR0 timing setting. */ - base->DBICR0 = - SEMC_DBICR0_PS(config->portSize) | SEMC_DBICR0_BL(config->burstLen) | SEMC_DBICR0_COL(config->columnAddrBitNum); - - timing = SEMC_DBICR1_CES(SEMC_ConvertTiming(config->tCsxSetup_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_CEH(SEMC_ConvertTiming(config->tCsxHold_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_WEL(SEMC_ConvertTiming(config->tWexLow_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_WEH(SEMC_ConvertTiming(config->tWexHigh_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_REL(SEMC_ConvertTiming(config->tRdxLow_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_REH(SEMC_ConvertTiming(config->tRdxHigh_Ns, clkSrc_Hz)); - timing |= SEMC_DBICR1_CEITV(SEMC_ConvertTiming(config->tCsxInterval_Ns, clkSrc_Hz)); - - /* DBICR1 timing setting. */ - base->DBICR1 = timing; - return SEMC_ConfigureIPCommand(base, ((uint8_t)config->portSize + 1U)); -} - -/*! - * brief SEMC IP command access. - * - * param base SEMC peripheral base address. - * param type SEMC memory type. refer to "semc_mem_type_t" - * param address SEMC device address. - * param command SEMC IP command. - * For NAND device, we should use the SEMC_BuildNandIPCommand to get the right nand command. - * For NOR/DBI device, take refer to "semc_ipcmd_nor_dbi_t". - * For SRAM device, take refer to "semc_ipcmd_sram_t". - * For SDRAM device, take refer to "semc_ipcmd_sdram_t". - * param write Data for write access. - * param read Data pointer for read data out. - */ -status_t SEMC_SendIPCommand( - SEMC_Type *base, semc_mem_type_t type, uint32_t address, uint32_t command, uint32_t write, uint32_t *read) -{ - uint32_t cmdMode; - bool readCmd = false; - bool writeCmd = false; - status_t result; - - /* Clear status bit */ - base->INTR |= SEMC_INTR_IPCMDDONE_MASK; - /* Set address. */ - base->IPCR0 = address; - - /* Check command mode. */ - cmdMode = (uint32_t)command & 0x0FU; - switch (type) - { - case kSEMC_MemType_NAND: - readCmd = (cmdMode == (uint32_t)kSEMC_NANDCM_CommandAddressRead) || - (cmdMode == (uint32_t)kSEMC_NANDCM_CommandRead) || (cmdMode == (uint32_t)kSEMC_NANDCM_Read); - writeCmd = (cmdMode == (uint32_t)kSEMC_NANDCM_CommandAddressWrite) || - (cmdMode == (uint32_t)kSEMC_NANDCM_CommandWrite) || (cmdMode == (uint32_t)kSEMC_NANDCM_Write); - break; - case kSEMC_MemType_NOR: - case kSEMC_MemType_8080: - readCmd = (cmdMode == (uint32_t)kSEMC_NORDBICM_Read); - writeCmd = (cmdMode == (uint32_t)kSEMC_NORDBICM_Write); - break; - case kSEMC_MemType_SRAM: - readCmd = (cmdMode == (uint32_t)kSEMC_SRAMCM_ArrayRead) || (cmdMode == (uint32_t)kSEMC_SRAMCM_RegRead); - writeCmd = (cmdMode == (uint32_t)kSEMC_SRAMCM_ArrayWrite) || (cmdMode == (uint32_t)kSEMC_SRAMCM_RegWrite); - break; - case kSEMC_MemType_SDRAM: - readCmd = (cmdMode == (uint32_t)kSEMC_SDRAMCM_Read); - writeCmd = (cmdMode == (uint32_t)kSEMC_SDRAMCM_Write) || (cmdMode == (uint32_t)kSEMC_SDRAMCM_Modeset); - break; - default: - assert(false); - break; - } - - if (writeCmd) - { - /* Set data. */ - base->IPTXDAT = write; - } - - /* Set command code. */ - base->IPCMD = command | SEMC_IPCMD_KEY(SEMC_IPCOMMANDMAGICKEY); - /* Wait for command done. */ - result = SEMC_IsIPCommandDone(base); - if (result != kStatus_Success) - { - return result; - } - - if (readCmd) - { - /* Get the read data */ - *read = base->IPRXDAT; - } - - return kStatus_Success; -} - -/*! - * brief SEMC NAND device memory write through IP command. - * - * param base SEMC peripheral base address. - * param address SEMC NAND device address. - * param data Data for write access. - * param size_bytes Data length. - */ -status_t SEMC_IPCommandNandWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) -{ - assert(data != NULL); - - status_t result = kStatus_Success; - uint16_t ipCmd; - uint32_t tempData = 0; - - union - { - uint32_t *u32Data; - uint8_t *u8Data; - } tmpData; - - tmpData.u8Data = data; - - /* Write command built */ - ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Write); - while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) - { - /* Configure IP command data size. */ - (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); - result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, *tmpData.u32Data, NULL); - if (result != kStatus_Success) - { - break; - } - - data += SEMC_IPCOMMANDDATASIZEBYTEMAX; - size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; - } - - if ((result == kStatus_Success) && (size_bytes != 0x00U)) - { - (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes); - - while (size_bytes != 0x00U) - { - tempData |= ((uint32_t)(data + size_bytes - 1U) << ((size_bytes - 1U) * SEMC_BYTE_NUMBIT)); - size_bytes--; - } - - result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, tempData, NULL); - } - - return result; -} - -/*! - * brief SEMC NAND device memory read through IP command. - * - * param base SEMC peripheral base address. - * param address SEMC NAND device address. - * param data Data pointer for data read out. - * param size_bytes Data length. - */ -status_t SEMC_IPCommandNandRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) -{ - assert(data != NULL); - - status_t result = kStatus_Success; - uint16_t ipCmd; - uint32_t tempData = 0; - - /* Configure IP command data size. */ - (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); - /* Read command built */ - ipCmd = SEMC_BuildNandIPCommand(0, kSEMC_NANDAM_ColumnRow, kSEMC_NANDCM_Read); - - union - { - uint32_t *u32Data; - uint8_t *u8Data; - } tmpData; - - tmpData.u8Data = data; - - while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) - { - result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, tmpData.u32Data); - if (result != kStatus_Success) - { - break; - } - - data += SEMC_IPCOMMANDDATASIZEBYTEMAX; - size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; - } - - if ((result == kStatus_Success) && (size_bytes != 0x00U)) - { - (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes); - result = SEMC_SendIPCommand(base, kSEMC_MemType_NAND, address, ipCmd, 0, &tempData); - - while (size_bytes != 0x00U) - { - size_bytes--; - *(data + size_bytes) = (uint8_t)((tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU); - } - } - - return result; -} - -/*! - * brief SEMC NOR device memory read through IP command. - * - * param base SEMC peripheral base address. - * param address SEMC NOR device address. - * param data Data pointer for data read out. - * param size_bytes Data length. - */ -status_t SEMC_IPCommandNorRead(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) -{ - assert(data != NULL); - - uint32_t tempData = 0; - status_t result = kStatus_Success; - uint8_t dataSize = (uint8_t)base->NORCR0 & SEMC_NORCR0_PS_MASK; - - /* Configure IP command data size. */ - (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); - - union - { - uint32_t *u32Data; - uint8_t *u8Data; - } tmpData; - - tmpData.u8Data = data; - - while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) - { - result = - SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Read, 0, tmpData.u32Data); - if (result != kStatus_Success) - { - break; - } - - data += SEMC_IPCOMMANDDATASIZEBYTEMAX; - size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; - } - - if ((result == kStatus_Success) && (size_bytes != 0x00U)) - { - (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes); - result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Read, 0, &tempData); - while (size_bytes != 0x00U) - { - size_bytes--; - *(data + size_bytes) = (uint8_t)((tempData >> (SEMC_BYTE_NUMBIT * size_bytes)) & 0xFFU); - } - } - - (void)SEMC_ConfigureIPCommand(base, dataSize); - return result; -} - -/*! - * brief SEMC NOR device memory write through IP command. - * - * param base SEMC peripheral base address. - * param address SEMC NOR device address. - * param data Data for write access. - * param size_bytes Data length. - */ -status_t SEMC_IPCommandNorWrite(SEMC_Type *base, uint32_t address, uint8_t *data, uint32_t size_bytes) -{ - assert(data != NULL); - - uint32_t tempData = 0; - status_t result = kStatus_Success; - uint8_t dataSize = (uint8_t)base->NORCR0 & SEMC_NORCR0_PS_MASK; - - union - { - uint32_t *u32Data; - uint8_t *u8Data; - } tmpData; - - tmpData.u8Data = data; - - /* Write command built */ - while (size_bytes >= SEMC_IPCOMMANDDATASIZEBYTEMAX) - { - /* Configure IP command data size. */ - (void)SEMC_ConfigureIPCommand(base, SEMC_IPCOMMANDDATASIZEBYTEMAX); - result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Write, *tmpData.u32Data, - NULL); - if (result != kStatus_Success) - { - break; - } - size_bytes -= SEMC_IPCOMMANDDATASIZEBYTEMAX; - data += SEMC_IPCOMMANDDATASIZEBYTEMAX; - } - - if ((result == kStatus_Success) && (size_bytes != 0x00U)) - { - (void)SEMC_ConfigureIPCommand(base, (uint8_t)size_bytes); - - while (size_bytes != 0x00U) - { - tempData |= ((uint32_t) * (data + size_bytes - 1U) << ((size_bytes - 1U) * SEMC_BYTE_NUMBIT)); - size_bytes--; - } - - result = SEMC_SendIPCommand(base, kSEMC_MemType_NOR, address, (uint16_t)kSEMC_NORDBICM_Write, tempData, NULL); - } - (void)SEMC_ConfigureIPCommand(base, dataSize); - - return result; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_hp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_hp.c deleted file mode 100644 index 2a2e0c7e40..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_hp.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2017-2019, NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_snvs_hp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.snvs_hp" -#endif - -#define SECONDS_IN_A_DAY (86400U) -#define SECONDS_IN_A_HOUR (3600U) -#define SECONDS_IN_A_MINUTE (60U) -#define DAYS_IN_A_YEAR (365U) -#define YEAR_RANGE_START (1970U) -#define YEAR_RANGE_END (2099U) - -#if !(defined(SNVS_HPSR_PI_MASK)) -#define SNVS_HPSR_PI_MASK (0x2U) -#endif -#if !(defined(SNVS_HPSR_HPTA_MASK)) -#define SNVS_HPSR_HPTA_MASK (0x1U) -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Checks whether the date and time passed in is valid - * - * @param datetime Pointer to structure where the date and time details are stored - * - * @return Returns false if the date & time details are out of range; true if in range - */ -static bool SNVS_HP_CheckDatetimeFormat(const snvs_hp_rtc_datetime_t *datetime); - -/*! - * @brief Converts time data from datetime to seconds - * - * @param datetime Pointer to datetime structure where the date and time details are stored - * - * @return The result of the conversion in seconds - */ -static uint32_t SNVS_HP_ConvertDatetimeToSeconds(const snvs_hp_rtc_datetime_t *datetime); - -/*! - * @brief Converts time data from seconds to a datetime structure - * - * @param seconds Seconds value that needs to be converted to datetime format - * @param datetime Pointer to the datetime structure where the result of the conversion is stored - */ -static void SNVS_HP_ConvertSecondsToDatetime(uint32_t seconds, snvs_hp_rtc_datetime_t *datetime); - -/*! - * @brief Returns RTC time in seconds. - * - * This function is used internally to get actual RTC time in seconds. - * - * @param base SNVS peripheral base address - * - * @return RTC time in seconds - */ -static uint32_t SNVS_HP_RTC_GetSeconds(SNVS_Type *base); - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) -/*! - * @brief Get the SNVS instance from peripheral base address. - * - * @param base SNVS peripheral base address. - * - * @return SNVS instance. - */ -static uint32_t SNVS_HP_GetInstance(SNVS_Type *base); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) -/*! @brief Pointer to snvs_hp clock. */ -static const clock_ip_name_t s_snvsHpClock[] = SNVS_HP_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static bool SNVS_HP_CheckDatetimeFormat(const snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - /* Table of days in a month for a non leap year. First entry in the table is not used, - * valid months start from 1 - */ - uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; - - /* Check year, month, hour, minute, seconds */ - if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || - (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) - { - /* If not correct then error*/ - return false; - } - - /* Adjust the days in February for a leap year */ - if ((((datetime->year & 3U) == 0U) && (datetime->year % 100U != 0U)) || (datetime->year % 400U == 0U)) - { - daysPerMonth[2] = 29U; - } - - /* Check the validity of the day */ - if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) - { - return false; - } - - return true; -} - -static uint32_t SNVS_HP_ConvertDatetimeToSeconds(const snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - /* Number of days from begin of the non Leap-year*/ - /* Number of days from begin of the non Leap-year*/ - uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; - uint32_t seconds; - - /* Compute number of days from 1970 till given year*/ - seconds = (((uint32_t)datetime->year - 1970U) * DAYS_IN_A_YEAR); - /* Add leap year days */ - seconds += (((uint32_t)datetime->year / 4U) - (1970U / 4U)); - /* Add number of days till given month*/ - seconds += monthDays[datetime->month]; - /* Add days in given month. We subtract the current day as it is - * represented in the hours, minutes and seconds field*/ - seconds += ((uint32_t)datetime->day - 1U); - /* For leap year if month less than or equal to Febraury, decrement day counter*/ - if ((0U == (datetime->year & 3U)) && (datetime->month <= 2U)) - { - seconds--; - } - - seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + - (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; - - return seconds; -} - -static void SNVS_HP_ConvertSecondsToDatetime(uint32_t seconds, snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t x; - uint32_t secondsRemaining, days; - uint16_t daysInYear; - /* Table of days in a month for a non leap year. First entry in the table is not used, - * valid months start from 1 - */ - uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; - - /* Start with the seconds value that is passed in to be converted to date time format */ - secondsRemaining = seconds; - - /* Calcuate the number of days, we add 1 for the current day which is represented in the - * hours and seconds field - */ - days = secondsRemaining / SECONDS_IN_A_DAY + 1U; - - /* Update seconds left*/ - secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; - - /* Calculate the datetime hour, minute and second fields */ - datetime->hour = (uint8_t)(secondsRemaining / SECONDS_IN_A_HOUR); - secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; - datetime->minute = (uint8_t)(secondsRemaining / 60U); - datetime->second = (uint8_t)(secondsRemaining % SECONDS_IN_A_MINUTE); - - /* Calculate year */ - daysInYear = DAYS_IN_A_YEAR; - datetime->year = YEAR_RANGE_START; - while (days > daysInYear) - { - /* Decrease day count by a year and increment year by 1 */ - days -= daysInYear; - datetime->year++; - - /* Adjust the number of days for a leap year */ - if ((datetime->year & 3U) != 0U) - { - daysInYear = DAYS_IN_A_YEAR; - } - else - { - daysInYear = DAYS_IN_A_YEAR + 1U; - } - } - - /* Adjust the days in February for a leap year */ - if (0U == (datetime->year & 3U)) - { - daysPerMonth[2] = 29U; - } - - for (x = 1U; x <= 12U; x++) - { - if (days <= daysPerMonth[x]) - { - datetime->month = (uint8_t)x; - break; - } - else - { - days -= daysPerMonth[x]; - } - } - - datetime->day = (uint8_t)days; -} - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) -static uint32_t SNVS_HP_GetInstance(SNVS_Type *base) -{ - return 0U; -} -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! - * brief Initialize the SNVS. - * - * note This API should be called at the beginning of the application using the SNVS driver. - * - * param base SNVS peripheral base address - */ -void SNVS_HP_Init(SNVS_Type *base) -{ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) - uint32_t instance = SNVS_HP_GetInstance(base); - CLOCK_EnableClock(s_snvsHpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Deinitialize the SNVS. - * - * param base SNVS peripheral base address - */ -void SNVS_HP_Deinit(SNVS_Type *base) -{ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) - uint32_t instance = SNVS_HP_GetInstance(base); - CLOCK_DisableClock(s_snvsHpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Ungates the SNVS clock and configures the peripheral for basic operation. - * - * note This API should be called at the beginning of the application using the SNVS driver. - * - * param base SNVS peripheral base address - * param config Pointer to the user's SNVS configuration structure. - */ -void SNVS_HP_RTC_Init(SNVS_Type *base, const snvs_hp_rtc_config_t *config) -{ - assert(config != NULL); - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) - uint32_t instance = SNVS_HP_GetInstance(base); - CLOCK_EnableClock(s_snvsHpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - base->HPCOMR |= SNVS_HPCOMR_NPSWA_EN_MASK; - - base->HPCR = SNVS_HPCR_PI_FREQ(config->periodicInterruptFreq); - - if (config->rtcCalEnable) - { - base->HPCR |= SNVS_HPCR_HPCALB_VAL_MASK & (config->rtcCalValue << SNVS_HPCR_HPCALB_VAL_SHIFT); - base->HPCR |= SNVS_HPCR_HPCALB_EN_MASK; - } -} - -/*! - * brief Stops the RTC and SRTC timers. - * - * param base SNVS peripheral base address - */ -void SNVS_HP_RTC_Deinit(SNVS_Type *base) -{ - base->HPCR &= ~SNVS_HPCR_RTC_EN_MASK; - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_HP_CLOCKS)) - uint32_t instance = SNVS_HP_GetInstance(base); - CLOCK_DisableClock(s_snvsHpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Fills in the SNVS config struct with the default settings. - * - * The default values are as follows. - * code - * config->rtccalenable = false; - * config->rtccalvalue = 0U; - * config->PIFreq = 0U; - * endcode - * param config Pointer to the user's SNVS configuration structure. - */ -void SNVS_HP_RTC_GetDefaultConfig(snvs_hp_rtc_config_t *config) -{ - assert(config != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->rtcCalEnable = false; - config->rtcCalValue = 0U; - config->periodicInterruptFreq = 0U; -} - -static uint32_t SNVS_HP_RTC_GetSeconds(SNVS_Type *base) -{ - uint32_t seconds = 0; - uint32_t tmp = 0; - - /* Do consecutive reads until value is correct */ - do - { - seconds = tmp; - tmp = (base->HPRTCMR << 17U); - tmp |= (base->HPRTCLR >> 15U); - } while (tmp != seconds); - - return seconds; -} - -/*! - * brief Sets the SNVS RTC date and time according to the given time structure. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the date and time details are stored. - * - * return kStatus_Success: Success in setting the time and starting the SNVS RTC - * kStatus_InvalidArgument: Error because the datetime format is incorrect - */ -status_t SNVS_HP_RTC_SetDatetime(SNVS_Type *base, const snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t seconds = 0U; - uint32_t tmp = base->HPCR; - - /* disable RTC */ - SNVS_HP_RTC_StopTimer(base); - - /* Return error if the time provided is not valid */ - if (!(SNVS_HP_CheckDatetimeFormat(datetime))) - { - return kStatus_InvalidArgument; - } - - /* Set time in seconds */ - seconds = SNVS_HP_ConvertDatetimeToSeconds(datetime); - - base->HPRTCMR = (uint32_t)(seconds >> 17U); - base->HPRTCLR = (uint32_t)(seconds << 15U); - - /* reenable RTC in case that it was enabled before */ - if ((tmp & SNVS_HPCR_RTC_EN_MASK) != 0U) - { - SNVS_HP_RTC_StartTimer(base); - } - - return kStatus_Success; -} - -/*! - * brief Gets the SNVS RTC time and stores it in the given time structure. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the date and time details are stored. - */ -void SNVS_HP_RTC_GetDatetime(SNVS_Type *base, snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - SNVS_HP_ConvertSecondsToDatetime(SNVS_HP_RTC_GetSeconds(base), datetime); -} - -/*! - * brief Sets the SNVS RTC alarm time. - * - * The function sets the RTC alarm. It also checks whether the specified alarm time - * is greater than the present time. If not, the function does not set the alarm - * and returns an error. - * - * param base SNVS peripheral base address - * param alarmTime Pointer to the structure where the alarm time is stored. - * - * return kStatus_Success: success in setting the SNVS RTC alarm - * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect - * kStatus_Fail: Error because the alarm time has already passed - */ -status_t SNVS_HP_RTC_SetAlarm(SNVS_Type *base, const snvs_hp_rtc_datetime_t *alarmTime) -{ - assert(alarmTime != NULL); - - uint32_t alarmSeconds = 0U; - uint32_t currSeconds = 0U; - uint32_t tmp = base->HPCR; - - /* Return error if the alarm time provided is not valid */ - if (!(SNVS_HP_CheckDatetimeFormat(alarmTime))) - { - return kStatus_InvalidArgument; - } - - alarmSeconds = SNVS_HP_ConvertDatetimeToSeconds(alarmTime); - currSeconds = SNVS_HP_RTC_GetSeconds(base); - - /* Return error if the alarm time has passed */ - if (alarmSeconds < currSeconds) - { - return kStatus_Fail; - } - - /* disable RTC alarm interrupt */ - base->HPCR &= ~SNVS_HPCR_HPTA_EN_MASK; - while ((base->HPCR & SNVS_HPCR_HPTA_EN_MASK) != 0U) - { - } - - /* Set alarm in seconds*/ - base->HPTAMR = (uint32_t)(alarmSeconds >> 17U); - base->HPTALR = (uint32_t)(alarmSeconds << 15U); - - /* reenable RTC alarm interrupt in case that it was enabled before */ - base->HPCR = tmp; - - return kStatus_Success; -} - -/*! - * brief Returns the SNVS RTC alarm time. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the alarm date and time details are stored. - */ -void SNVS_HP_RTC_GetAlarm(SNVS_Type *base, snvs_hp_rtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t alarmSeconds = 0U; - - /* Get alarm in seconds */ - alarmSeconds = (base->HPTAMR << 17U); - alarmSeconds |= (base->HPTALR >> 15U); - - SNVS_HP_ConvertSecondsToDatetime(alarmSeconds, datetime); -} - -#if (defined(FSL_FEATURE_SNVS_HAS_SRTC) && (FSL_FEATURE_SNVS_HAS_SRTC > 0)) -/*! - * brief The function synchronizes RTC counter value with SRTC. - * - * param base SNVS peripheral base address - */ -void SNVS_HP_RTC_TimeSynchronize(SNVS_Type *base) -{ - uint32_t tmp = base->HPCR; - - /* disable RTC */ - SNVS_HP_RTC_StopTimer(base); - - base->HPCR |= SNVS_HPCR_HP_TS_MASK; - - /* reenable RTC in case that it was enabled before */ - if ((tmp & SNVS_HPCR_RTC_EN_MASK) != 0U) - { - SNVS_HP_RTC_StartTimer(base); - } -} -#endif /* FSL_FEATURE_SNVS_HAS_SRTC */ - -/*! - * brief Gets the SNVS status flags. - * - * param base SNVS peripheral base address - * - * return The status flags. This is the logical OR of members of the - * enumeration ::snvs_status_flags_t - */ -uint32_t SNVS_HP_RTC_GetStatusFlags(SNVS_Type *base) -{ - uint32_t flags = 0U; - - if ((base->HPSR & SNVS_HPSR_PI_MASK) != 0U) - { - flags |= (uint32_t)kSNVS_RTC_PeriodicInterruptFlag; - } - - if ((base->HPSR & SNVS_HPSR_HPTA_MASK) != 0U) - { - flags |= (uint32_t)kSNVS_RTC_AlarmInterruptFlag; - } - - return flags; -} - -/*! - * brief Gets the enabled SNVS interrupts. - * - * param base SNVS peripheral base address - * - * return The enabled interrupts. This is the logical OR of members of the - * enumeration ::snvs_interrupt_enable_t - */ -uint32_t SNVS_HP_RTC_GetEnabledInterrupts(SNVS_Type *base) -{ - uint32_t val = 0U; - - if ((base->HPCR & SNVS_HPCR_PI_EN_MASK) != 0U) - { - val |= (uint32_t)kSNVS_RTC_PeriodicInterrupt; - } - - if ((base->HPCR & SNVS_HPCR_HPTA_EN_MASK) != 0U) - { - val |= (uint32_t)kSNVS_RTC_AlarmInterrupt; - } - - return val; -} - -#if defined(FSL_FEATURE_SNVS_HAS_SET_LOCK) && (FSL_FEATURE_SNVS_HAS_SET_LOCK > 0) -/*! - * brief Set SNVS HP Set locks. - * - * param base SNVS peripheral base address - * - */ -void SNVS_HP_SetLocks(SNVS_Type *base) -{ - uint32_t sec_config = ((OCOTP_CTRL->HW_OCOTP_OTFAD_CFG3 & OCOTP_CTRL_HW_OCOTP_SEC_CONFIG1_MASK) >> - OCOTP_CTRL_HW_OCOTP_SEC_CONFIG1_SHIFT); - - if (sec_config == SEC_CONFIG_OPEN) - { - /* Enable non-secure SW access */ - base->HPCOMR |= SNVS_HPCOMR_NPSWA_EN(1); - } - - /* Set LP Software Reset Disable lock and ZMK Write Soft Lock */ - base->HPCOMR |= SNVS_HPCOMR_LP_SWR_DIS(1); - base->HPLR |= SNVS_HPLR_ZMK_WSL(1); -} -#endif /* FSL_FEATURE_SNVS_HAS_SET_LOCK */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_lp.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_lp.c deleted file mode 100644 index bf5a7cb023..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_snvs_lp.c +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2017-2019, NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_snvs_lp.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.snvs_lp" -#endif - -#define SECONDS_IN_A_DAY (86400U) -#define SECONDS_IN_A_HOUR (3600U) -#define SECONDS_IN_A_MINUTE (60U) -#define DAYS_IN_A_YEAR (365U) -#define YEAR_RANGE_START (1970U) -#define YEAR_RANGE_END (2099U) - -#define SNVS_DEFAULT_PGD_VALUE (0x41736166U) - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Checks whether the date and time passed in is valid - * - * @param datetime Pointer to structure where the date and time details are stored - * - * @return Returns false if the date & time details are out of range; true if in range - */ -static bool SNVS_LP_CheckDatetimeFormat(const snvs_lp_srtc_datetime_t *datetime); - -/*! - * @brief Converts time data from datetime to seconds - * - * @param datetime Pointer to datetime structure where the date and time details are stored - * - * @return The result of the conversion in seconds - */ -static uint32_t SNVS_LP_ConvertDatetimeToSeconds(const snvs_lp_srtc_datetime_t *datetime); - -/*! - * @brief Converts time data from seconds to a datetime structure - * - * @param seconds Seconds value that needs to be converted to datetime format - * @param datetime Pointer to the datetime structure where the result of the conversion is stored - */ -static void SNVS_LP_ConvertSecondsToDatetime(uint32_t seconds, snvs_lp_srtc_datetime_t *datetime); - -/*! - * @brief Returns SRTC time in seconds. - * - * This function is used internally to get actual SRTC time in seconds. - * - * @param base SNVS peripheral base address - * - * @return SRTC time in seconds - */ -static uint32_t SNVS_LP_SRTC_GetSeconds(SNVS_Type *base); - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) -/*! - * @brief Get the SNVS instance from peripheral base address. - * - * @param base SNVS peripheral base address. - * - * @return SNVS instance. - */ -static uint32_t SNVS_LP_GetInstance(SNVS_Type *base); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) -/*! @brief Pointer to snvs_lp clock. */ -const clock_ip_name_t s_snvsLpClock[] = SNVS_LP_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ -static bool SNVS_LP_CheckDatetimeFormat(const snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - /* Table of days in a month for a non leap year. First entry in the table is not used, - * valid months start from 1 - */ - uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; - - /* Check year, month, hour, minute, seconds */ - if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || - (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) - { - /* If not correct then error*/ - return false; - } - - /* Adjust the days in February for a leap year */ - if ((((datetime->year & 3U) == 0U) && (datetime->year % 100U != 0U)) || (datetime->year % 400U == 0U)) - { - daysPerMonth[2] = 29U; - } - - /* Check the validity of the day */ - if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) - { - return false; - } - - return true; -} - -static uint32_t SNVS_LP_ConvertDatetimeToSeconds(const snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - /* Number of days from begin of the non Leap-year*/ - /* Number of days from begin of the non Leap-year*/ - uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; - uint32_t seconds; - - /* Compute number of days from 1970 till given year*/ - seconds = ((uint32_t)datetime->year - 1970U) * DAYS_IN_A_YEAR; - /* Add leap year days */ - seconds += (((uint32_t)datetime->year / 4U) - (1970U / 4U)); - /* Add number of days till given month*/ - seconds += monthDays[datetime->month]; - /* Add days in given month. We subtract the current day as it is - * represented in the hours, minutes and seconds field*/ - seconds += ((uint32_t)datetime->day - 1U); - /* For leap year if month less than or equal to Febraury, decrement day counter*/ - if ((0U == (datetime->year & 3U)) && (datetime->month <= 2U)) - { - seconds--; - } - - seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + - (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; - - return seconds; -} - -static void SNVS_LP_ConvertSecondsToDatetime(uint32_t seconds, snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t x; - uint32_t secondsRemaining, days; - uint16_t daysInYear; - /* Table of days in a month for a non leap year. First entry in the table is not used, - * valid months start from 1 - */ - uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; - - /* Start with the seconds value that is passed in to be converted to date time format */ - secondsRemaining = seconds; - - /* Calcuate the number of days, we add 1 for the current day which is represented in the - * hours and seconds field - */ - days = secondsRemaining / SECONDS_IN_A_DAY + 1U; - - /* Update seconds left*/ - secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; - - /* Calculate the datetime hour, minute and second fields */ - datetime->hour = (uint8_t)(secondsRemaining / SECONDS_IN_A_HOUR); - secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; - datetime->minute = (uint8_t)(secondsRemaining / 60U); - datetime->second = (uint8_t)(secondsRemaining % SECONDS_IN_A_MINUTE); - - /* Calculate year */ - daysInYear = DAYS_IN_A_YEAR; - datetime->year = YEAR_RANGE_START; - while (days > daysInYear) - { - /* Decrease day count by a year and increment year by 1 */ - days -= daysInYear; - datetime->year++; - - /* Adjust the number of days for a leap year */ - if ((datetime->year & 3U) != 0U) - { - daysInYear = DAYS_IN_A_YEAR; - } - else - { - daysInYear = DAYS_IN_A_YEAR + 1U; - } - } - - /* Adjust the days in February for a leap year */ - if (0U == (datetime->year & 3U)) - { - daysPerMonth[2] = 29U; - } - - for (x = 1U; x <= 12U; x++) - { - if (days <= daysPerMonth[x]) - { - datetime->month = (uint8_t)x; - break; - } - else - { - days -= daysPerMonth[x]; - } - } - - datetime->day = (uint8_t)days; -} - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) -static uint32_t SNVS_LP_GetInstance(SNVS_Type *base) -{ - return 0U; -} -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/*! - * brief Ungates the SNVS clock and configures the peripheral for basic operation. - * - * note This API should be called at the beginning of the application using the SNVS driver. - * - * param base SNVS peripheral base address - * param config Pointer to the user's SNVS configuration structure. - */ -void SNVS_LP_Init(SNVS_Type *base) -{ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) - uint32_t instance = SNVS_LP_GetInstance(base); - CLOCK_EnableClock(s_snvsLpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Power glitch detector: set the PGD value and clear the previous status. */ - base->LPPGDR = SNVS_DEFAULT_PGD_VALUE; - base->LPSR = SNVS_LPSR_PGD_MASK; -} - -/*! - * brief Deinit the SNVS LP section. - * - * param base SNVS peripheral base address - */ -void SNVS_LP_Deinit(SNVS_Type *base) -{ -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) - uint32_t instance = SNVS_LP_GetInstance(base); - CLOCK_DisableClock(s_snvsLpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Ungates the SNVS clock and configures the peripheral for basic operation. - * - * note This API should be called at the beginning of the application using the SNVS driver. - * - * param base SNVS peripheral base address - * param config Pointer to the user's SNVS configuration structure. - */ -void SNVS_LP_SRTC_Init(SNVS_Type *base, const snvs_lp_srtc_config_t *config) -{ - assert(config != NULL); - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) - uint32_t instance = SNVS_LP_GetInstance(base); - CLOCK_EnableClock(s_snvsLpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - int pin; - - if (config->srtcCalEnable) - { - base->LPCR = SNVS_LPCR_LPCALB_VAL_MASK & (config->srtcCalValue << SNVS_LPCR_LPCALB_VAL_SHIFT); - base->LPCR |= SNVS_LPCR_LPCALB_EN_MASK; - } - - for (pin = (int32_t)kSNVS_ExternalTamper1; pin <= (int32_t)SNVS_LP_MAX_TAMPER; pin++) - { - SNVS_LP_DisableExternalTamper(SNVS, (snvs_lp_external_tamper_t)pin); - SNVS_LP_ClearExternalTamperStatus(SNVS, (snvs_lp_external_tamper_t)pin); - } -} - -/*! - * brief Stops the SRTC timer. - * - * param base SNVS peripheral base address - */ -void SNVS_LP_SRTC_Deinit(SNVS_Type *base) -{ - base->LPCR &= ~SNVS_LPCR_SRTC_ENV_MASK; - -#if (!(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && \ - defined(SNVS_LP_CLOCKS)) - uint32_t instance = SNVS_LP_GetInstance(base); - CLOCK_DisableClock(s_snvsLpClock[instance]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Fills in the SNVS_LP config struct with the default settings. - * - * The default values are as follows. - * code - * config->srtccalenable = false; - * config->srtccalvalue = 0U; - * endcode - * param config Pointer to the user's SNVS configuration structure. - */ -void SNVS_LP_SRTC_GetDefaultConfig(snvs_lp_srtc_config_t *config) -{ - assert(config != NULL); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->srtcCalEnable = false; - config->srtcCalValue = 0U; -} - -static uint32_t SNVS_LP_SRTC_GetSeconds(SNVS_Type *base) -{ - uint32_t seconds = 0; - uint32_t tmp = 0; - - /* Do consecutive reads until value is correct */ - do - { - seconds = tmp; - tmp = (base->LPSRTCMR << 17U); - tmp |= (base->LPSRTCLR >> 15U); - } while (tmp != seconds); - - return seconds; -} - -/*! - * brief Sets the SNVS SRTC date and time according to the given time structure. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the date and time details are stored. - * - * return kStatus_Success: Success in setting the time and starting the SNVS SRTC - * kStatus_InvalidArgument: Error because the datetime format is incorrect - */ -status_t SNVS_LP_SRTC_SetDatetime(SNVS_Type *base, const snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t seconds = 0U; - uint32_t tmp = base->LPCR; - - /* disable RTC */ - SNVS_LP_SRTC_StopTimer(base); - - /* Return error if the time provided is not valid */ - if (!(SNVS_LP_CheckDatetimeFormat(datetime))) - { - return kStatus_InvalidArgument; - } - - /* Set time in seconds */ - seconds = SNVS_LP_ConvertDatetimeToSeconds(datetime); - - base->LPSRTCMR = (uint32_t)(seconds >> 17U); - base->LPSRTCLR = (uint32_t)(seconds << 15U); - - /* reenable SRTC in case that it was enabled before */ - if ((tmp & SNVS_LPCR_SRTC_ENV_MASK) != 0U) - { - SNVS_LP_SRTC_StartTimer(base); - } - - return kStatus_Success; -} - -/*! - * brief Gets the SNVS SRTC time and stores it in the given time structure. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the date and time details are stored. - */ -void SNVS_LP_SRTC_GetDatetime(SNVS_Type *base, snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - SNVS_LP_ConvertSecondsToDatetime(SNVS_LP_SRTC_GetSeconds(base), datetime); -} - -/*! - * brief Sets the SNVS SRTC alarm time. - * - * The function sets the SRTC alarm. It also checks whether the specified alarm - * time is greater than the present time. If not, the function does not set the alarm - * and returns an error. - * Please note, that SRTC alarm has limited resolution because only 32 most - * significant bits of SRTC counter are compared to SRTC Alarm register. - * If the alarm time is beyond SRTC resolution, the function does not set the alarm - * and returns an error. - * - * param base SNVS peripheral base address - * param alarmTime Pointer to the structure where the alarm time is stored. - * - * return kStatus_Success: success in setting the SNVS SRTC alarm - * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect - * kStatus_Fail: Error because the alarm time has already passed or is beyond resolution - */ -status_t SNVS_LP_SRTC_SetAlarm(SNVS_Type *base, const snvs_lp_srtc_datetime_t *alarmTime) -{ - assert(alarmTime != NULL); - - uint32_t alarmSeconds = 0U; - uint32_t currSeconds = 0U; - uint32_t tmp = base->LPCR; - - /* Return error if the alarm time provided is not valid */ - if (!(SNVS_LP_CheckDatetimeFormat(alarmTime))) - { - return kStatus_InvalidArgument; - } - - alarmSeconds = SNVS_LP_ConvertDatetimeToSeconds(alarmTime); - currSeconds = SNVS_LP_SRTC_GetSeconds(base); - - /* Return error if the alarm time has passed */ - if (alarmSeconds <= currSeconds) - { - return kStatus_Fail; - } - - /* disable SRTC alarm interrupt */ - base->LPCR &= ~SNVS_LPCR_LPTA_EN_MASK; - while ((base->LPCR & SNVS_LPCR_LPTA_EN_MASK) != 0U) - { - } - - /* Set alarm in seconds*/ - base->LPTAR = alarmSeconds; - - /* reenable SRTC alarm interrupt in case that it was enabled before */ - base->LPCR = tmp; - - return kStatus_Success; -} - -/*! - * brief Returns the SNVS SRTC alarm time. - * - * param base SNVS peripheral base address - * param datetime Pointer to the structure where the alarm date and time details are stored. - */ -void SNVS_LP_SRTC_GetAlarm(SNVS_Type *base, snvs_lp_srtc_datetime_t *datetime) -{ - assert(datetime != NULL); - - uint32_t alarmSeconds = 0U; - - /* Get alarm in seconds */ - alarmSeconds = base->LPTAR; - - SNVS_LP_ConvertSecondsToDatetime(alarmSeconds, datetime); -} - -/*! - * brief Gets the SNVS status flags. - * - * param base SNVS peripheral base address - * - * return The status flags. This is the logical OR of members of the - * enumeration ::snvs_status_flags_t - */ -uint32_t SNVS_LP_SRTC_GetStatusFlags(SNVS_Type *base) -{ - uint32_t flags = 0U; - - if ((base->LPSR & SNVS_LPSR_LPTA_MASK) != 0U) - { - flags |= (uint32_t)kSNVS_SRTC_AlarmInterruptFlag; - } - - return flags; -} - -/*! - * brief Gets the enabled SNVS interrupts. - * - * param base SNVS peripheral base address - * - * return The enabled interrupts. This is the logical OR of members of the - * enumeration ::snvs_interrupt_enable_t - */ -uint32_t SNVS_LP_SRTC_GetEnabledInterrupts(SNVS_Type *base) -{ - uint32_t val = 0U; - - if ((base->LPCR & SNVS_LPCR_LPTA_EN_MASK) != 0U) - { - val |= (uint32_t)kSNVS_SRTC_AlarmInterrupt; - } - - return val; -} - -/*! - * brief Enables the specified SNVS external tamper. - * - * param base SNVS peripheral base address - * param pin SNVS external tamper pin - * param polarity Polarity of external tamper - */ -void SNVS_LP_EnableExternalTamper(SNVS_Type *base, - snvs_lp_external_tamper_t pin, - snvs_lp_external_tamper_polarity_t polarity) -{ - switch (pin) - { - case (kSNVS_ExternalTamper1): - base->LPTDCR = - (base->LPTDCR & ~(1UL << SNVS_LPTDCR_ET1P_SHIFT)) | ((uint32_t)polarity << SNVS_LPTDCR_ET1P_SHIFT); - base->LPTDCR |= SNVS_LPTDCR_ET1_EN_MASK; - break; -#if defined(FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER) && (FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER > 1) - case (kSNVS_ExternalTamper2): - base->LPTDCR = (base->LPTDCR & ~(1U << SNVS_LPTDCR_ET2P_SHIFT)) | (polarity << SNVS_LPTDCR_ET2P_SHIFT); - base->LPTDCR |= SNVS_LPTDCR_ET2_EN_MASK; - break; - case (kSNVS_ExternalTamper3): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET3P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET3P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET3_EN_MASK; - break; - case (kSNVS_ExternalTamper4): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET4P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET4P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET4_EN_MASK; - break; - case (kSNVS_ExternalTamper5): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET5P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET5P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET5_EN_MASK; - break; - case (kSNVS_ExternalTamper6): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET6P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET6P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET6_EN_MASK; - break; - case (kSNVS_ExternalTamper7): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET7P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET7P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET7_EN_MASK; - break; - case (kSNVS_ExternalTamper8): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET8P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET8P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET8_EN_MASK; - break; - case (kSNVS_ExternalTamper9): - base->LPTDC2R = (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET9P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET9P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET9_EN_MASK; - break; - case (kSNVS_ExternalTamper10): - base->LPTDC2R = - (base->LPTDC2R & ~(1U << SNVS_LPTDC2R_ET10P_SHIFT)) | (polarity << SNVS_LPTDC2R_ET10P_SHIFT); - base->LPTDC2R |= SNVS_LPTDC2R_ET10_EN_MASK; - break; -#endif - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } -} - -/*! - * brief Disables the specified SNVS external tamper. - * - * param base SNVS peripheral base address - * param pin SNVS external tamper pin - */ -void SNVS_LP_DisableExternalTamper(SNVS_Type *base, snvs_lp_external_tamper_t pin) -{ - switch (pin) - { - case (kSNVS_ExternalTamper1): - base->LPTDCR &= ~SNVS_LPTDCR_ET1_EN_MASK; - break; -#if defined(FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER) && (FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER > 1) - case (kSNVS_ExternalTamper2): - base->LPTDCR &= ~SNVS_LPTDCR_ET2_EN_MASK; - break; - case (kSNVS_ExternalTamper3): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET3_EN_MASK; - break; - case (kSNVS_ExternalTamper4): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET4_EN_MASK; - break; - case (kSNVS_ExternalTamper5): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET5_EN_MASK; - break; - case (kSNVS_ExternalTamper6): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET6_EN_MASK; - break; - case (kSNVS_ExternalTamper7): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET7_EN_MASK; - break; - case (kSNVS_ExternalTamper8): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET8_EN_MASK; - break; - case (kSNVS_ExternalTamper9): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET9_EN_MASK; - break; - case (kSNVS_ExternalTamper10): - base->LPTDC2R &= ~SNVS_LPTDC2R_ET10_EN_MASK; - break; -#endif - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } -} - -/*! - * brief Returns status of the specified external tamper. - * - * param base SNVS peripheral base address - * param pin SNVS external tamper pin - * - * return The status flag. This is the enumeration ::snvs_external_tamper_status_t - */ -snvs_lp_external_tamper_status_t SNVS_LP_GetExternalTamperStatus(SNVS_Type *base, snvs_lp_external_tamper_t pin) -{ - snvs_lp_external_tamper_status_t status = kSNVS_TamperNotDetected; - - switch (pin) - { - case (kSNVS_ExternalTamper1): - status = (bool)(base->LPSR & SNVS_LPSR_ET1D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; -#if defined(FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER) && (FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER > 1) - case (kSNVS_ExternalTamper2): - status = (base->LPSR & SNVS_LPSR_ET2D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper3): - status = (base->LPTDSR & SNVS_LPTDSR_ET3D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper4): - status = (base->LPTDSR & SNVS_LPTDSR_ET4D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper5): - status = (base->LPTDSR & SNVS_LPTDSR_ET5D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper6): - status = (base->LPTDSR & SNVS_LPTDSR_ET6D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper7): - status = (base->LPTDSR & SNVS_LPTDSR_ET7D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper8): - status = (base->LPTDSR & SNVS_LPTDSR_ET8D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper9): - status = (base->LPTDSR & SNVS_LPTDSR_ET9D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; - case (kSNVS_ExternalTamper10): - status = (base->LPTDSR & SNVS_LPTDSR_ET10D_MASK) ? kSNVS_TamperDetected : kSNVS_TamperNotDetected; - break; -#endif - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } - return status; -} - -/*! - * brief Clears status of the specified external tamper. - * - * param base SNVS peripheral base address - * param pin SNVS external tamper pin - */ -void SNVS_LP_ClearExternalTamperStatus(SNVS_Type *base, snvs_lp_external_tamper_t pin) -{ - base->LPSR |= SNVS_LPSR_ET1D_MASK; - - switch (pin) - { - case (kSNVS_ExternalTamper1): - base->LPSR |= SNVS_LPSR_ET1D_MASK; - break; -#if defined(FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER) && (FSL_FEATURE_SNVS_HAS_MULTIPLE_TAMPER > 1) - case (kSNVS_ExternalTamper2): - base->LPSR |= SNVS_LPSR_ET2D_MASK; - break; - case (kSNVS_ExternalTamper3): - base->LPTDSR |= SNVS_LPTDSR_ET3D_MASK; - break; - case (kSNVS_ExternalTamper4): - base->LPTDSR |= SNVS_LPTDSR_ET4D_MASK; - break; - case (kSNVS_ExternalTamper5): - base->LPTDSR |= SNVS_LPTDSR_ET5D_MASK; - break; - case (kSNVS_ExternalTamper6): - base->LPTDSR |= SNVS_LPTDSR_ET6D_MASK; - break; - case (kSNVS_ExternalTamper7): - base->LPTDSR |= SNVS_LPTDSR_ET7D_MASK; - break; - case (kSNVS_ExternalTamper8): - base->LPTDSR |= SNVS_LPTDSR_ET8D_MASK; - break; - case (kSNVS_ExternalTamper9): - base->LPTDSR |= SNVS_LPTDSR_ET9D_MASK; - break; - case (kSNVS_ExternalTamper10): - base->LPTDSR |= SNVS_LPTDSR_ET10D_MASK; - break; -#endif - default: - /* All the cases have been listed above, the default clause should not be reached. */ - break; - } -} - -/*! - * brief Get the current Monotonic Counter. - * - * param base SNVS peripheral base address - * return Current Monotonic Counter value. - */ -uint64_t SNVS_LP_GetMonotonicCounter(SNVS_Type *base) -{ - uint32_t mc_lsb, mc_msb; - - mc_msb = base->LPSMCMR; - mc_lsb = base->LPSMCLR; - - return ((uint64_t)mc_msb << 32UL) | (uint64_t)mc_lsb; -} - -/*! - * brief Write Zeroizable Master Key (ZMK) to the SNVS registers. - * - * param base SNVS peripheral base address - * param ZMKey The ZMK write to the SNVS register. - */ -void SNVS_LP_WriteZeroizableMasterKey(SNVS_Type *base, uint32_t ZMKey[SNVS_ZMK_REG_COUNT]) -{ - uint8_t i = 0; - - for (i = 0; i < SNVS_ZMK_REG_COUNT; i++) - { - base->LPZMKR[i] = ZMKey[i]; - } -} - -#if defined(FSL_FEATURE_SNVS_HAS_STATE_TRANSITION) && (FSL_FEATURE_SNVS_HAS_STATE_TRANSITION > 0) -/*! - * brief Transition SNVS SSM state to Trusted/Non-secure from Check state - * - * param base SNVS peripheral base address - * - * return kStatus_Success: Success in transitioning SSM State - * kStatus_Fail: SSM State transition failed - */ -status_t SNVS_LP_SSM_State_Transition(SNVS_Type *base) -{ - uint32_t curr_ssm_state = ((base->HPSR & SNVS_HPSR_SSM_STATE_MASK) >> SNVS_HPSR_SSM_STATE_SHIFT); - uint32_t sec_config = ((OCOTP_CTRL->HW_OCOTP_OTFAD_CFG3 & OCOTP_CTRL_HW_OCOTP_SEC_CONFIG1_MASK) >> - OCOTP_CTRL_HW_OCOTP_SEC_CONFIG1_SHIFT); - - /* Check if SSM State is Check state */ - if (curr_ssm_state == SNVS_SSM_STATE_CHECK) - { - if (sec_config == SEC_CONFIG_OPEN) - { - /* Transition to Non-secure state */ - base->HPCOMR |= SNVS_HPCOMR_SW_SV(1); - } - else - { - /* Transition to Trusted state */ - base->HPCOMR |= SNVS_HPCOMR_SSM_ST(1); - } - } - - uint32_t new_ssm_state = ((base->HPSR & SNVS_HPSR_SSM_STATE_MASK) >> SNVS_HPSR_SSM_STATE_SHIFT); - - if (new_ssm_state != SNVS_SSM_STATE_CHECK) - { - return kStatus_Success; - } - else - { - return kStatus_Fail; - } -} -#endif /* FSL_FEATURE_SNVS_HAS_STATE_TRANSITION */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif.c deleted file mode 100644 index e03c28b6a0..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_spdif.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.spdif" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ -/*! @brief spdif transfer state. */ -enum -{ - kSPDIF_Busy = 0x0U, /*!< SPDIF is busy */ - kSPDIF_Idle, /*!< Transfer is done. */ - kSPDIF_Error /*!< Transfer error occurred. */ -}; - -/*! @brief Typedef for spdif tx interrupt handler. */ -typedef void (*spdif_isr_t)(SPDIF_Type *base, spdif_handle_t *handle); -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* Base pointer array */ -static SPDIF_Type *const s_spdifBases[] = SPDIF_BASE_PTRS; -/*! @brief SPDIF handle pointer */ -static spdif_handle_t *s_spdifHandle[ARRAY_SIZE(s_spdifBases)][2]; -/* IRQ number array */ -static const IRQn_Type s_spdifIRQ[] = SPDIF_IRQS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Clock name array */ -static const clock_ip_name_t s_spdifClock[] = SPDIF_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -/*! @brief Pointer to IRQ handler for each instance. */ -static spdif_isr_t s_spdifTxIsr; -/*! @brief Pointer to IRQ handler for each instance. */ -static spdif_isr_t s_spdifRxIsr; -/*! @brief Used for spdif gain */ -static uint8_t s_spdif_gain[8] = {24U, 16U, 12U, 8U, 6U, 4U, 3U, 1U}; -static uint8_t s_spdif_tx_watermark[4] = {16, 12, 8, 4}; -static uint8_t s_spdif_rx_watermark[4] = {1, 4, 8, 16}; - -/******************************************************************************* - * Code - ******************************************************************************/ -uint32_t SPDIF_GetInstance(SPDIF_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_spdifBases); instance++) - { - if (s_spdifBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_spdifBases)); - - return instance; -} - -/*! - * brief Initializes the SPDIF peripheral. - * - * Ungates the SPDIF clock, resets the module, and configures SPDIF with a configuration structure. - * The configuration structure can be custom filled or set with default values by - * SPDIF_GetDefaultConfig(). - * - * note This API should be called at the beginning of the application to use - * the SPDIF driver. Otherwise, accessing the SPDIF module can cause a hard fault - * because the clock is not enabled. - * - * param base SPDIF base pointer - * param config SPDIF configuration structure. - */ -void SPDIF_Init(SPDIF_Type *base, const spdif_config_t *config) -{ - uint32_t val = 0; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the SPDIF clock */ - CLOCK_EnableClock(s_spdifClock[SPDIF_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Reset the internal logic */ - base->SCR |= SPDIF_SCR_SOFT_RESET_MASK; - - /* Waiting for reset finish */ - while ((base->SCR & SPDIF_SCR_SOFT_RESET_MASK) != 0x00U) - { - } - - /* Setting the SPDIF settings */ - base->SCR = SPDIF_SCR_RXFIFOFULL_SEL(config->rxFullSelect) | SPDIF_SCR_RXAUTOSYNC(config->isRxAutoSync) | - SPDIF_SCR_TXAUTOSYNC(config->isRxAutoSync) | SPDIF_SCR_TXFIFOEMPTY_SEL(config->txFullSelect) | - SPDIF_SCR_TXFIFO_CTRL(1U) | SPDIF_SCR_VALCTRL(config->validityConfig) | - SPDIF_SCR_TXSEL(config->txSource) | SPDIF_SCR_USRC_SEL(config->uChannelSrc); - - /* Set DPLL clock source */ - base->SRPC = SPDIF_SRPC_CLKSRC_SEL(config->DPLLClkSource) | SPDIF_SRPC_GAINSEL(config->gain); - - /* Set SPDIF tx clock source */ - val = base->STC & ~SPDIF_STC_TXCLK_SOURCE_MASK; - val |= SPDIF_STC_TXCLK_SOURCE(config->txClkSource); - base->STC = val; -} - -/*! - * brief De-initializes the SPDIF peripheral. - * - * This API gates the SPDIF clock. The SPDIF module can't operate unless SPDIF_Init is called to enable the clock. - * - * param base SPDIF base pointer - */ -void SPDIF_Deinit(SPDIF_Type *base) -{ - SPDIF_TxEnable(base, false); - SPDIF_RxEnable(base, false); -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - CLOCK_DisableClock(s_spdifClock[SPDIF_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Sets the SPDIF configuration structure to default values. - * - * This API initializes the configuration structure for use in SPDIF_Init. - * The initialized structure can remain unchanged in SPDIF_Init, or it can be modified - * before calling SPDIF_Init. - * This is an example. - code - spdif_config_t config; - SPDIF_GetDefaultConfig(&config); - endcode - * - * param config pointer to master configuration structure - */ -void SPDIF_GetDefaultConfig(spdif_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->isTxAutoSync = true; - config->isRxAutoSync = true; - config->DPLLClkSource = 1; - config->txClkSource = 1; - config->rxFullSelect = kSPDIF_RxFull8Samples; - config->txFullSelect = kSPDIF_TxEmpty8Samples; - config->uChannelSrc = kSPDIF_UChannelFromTx; - config->txSource = kSPDIF_txNormal; - config->validityConfig = kSPDIF_validityFlagAlwaysClear; - config->gain = kSPDIF_GAIN_8; -} - -/*! - * brief Enables/disables the SPDIF Tx. - * - * param base SPDIF base pointer - * param enable True means enable SPDIF Tx, false means disable. - */ -void SPDIF_TxEnable(SPDIF_Type *base, bool enable) -{ - uint32_t val = 0; - - if (enable) - { - /* Open Tx FIFO */ - val = base->SCR & (~SPDIF_SCR_TXFIFO_CTRL_MASK); - val |= SPDIF_SCR_TXFIFO_CTRL(1U); - base->SCR = val; - /* Enable transfer clock */ - base->STC |= SPDIF_STC_TX_ALL_CLK_EN_MASK; - } - else - { - base->SCR &= ~(SPDIF_SCR_TXFIFO_CTRL_MASK | SPDIF_SCR_TXSEL_MASK); - /* Disable transfer clock */ - base->STC &= ~SPDIF_STC_TX_ALL_CLK_EN_MASK; - } -} - -/*! - * brief Configures the SPDIF Tx sample rate. - * - * The audio format can be changed at run-time. This function configures the sample rate. - * - * param base SPDIF base pointer. - * param sampleRate_Hz SPDIF sample rate frequency in Hz. - * param sourceClockFreq_Hz SPDIF tx clock source frequency in Hz. - */ -void SPDIF_TxSetSampleRate(SPDIF_Type *base, uint32_t sampleRate_Hz, uint32_t sourceClockFreq_Hz) -{ - uint32_t clkDiv = sourceClockFreq_Hz / (sampleRate_Hz * 64U); - uint32_t mod = sourceClockFreq_Hz % (sampleRate_Hz * 64U); - uint32_t val = 0; - uint8_t clockSource = (uint8_t)(((base->STC) & SPDIF_STC_TXCLK_SOURCE_MASK) >> SPDIF_STC_TXCLK_SOURCE_SHIFT); - - /* Compute the nearest divider */ - if (mod > ((sampleRate_Hz * 64U) / 2U)) - { - clkDiv += 1U; - } - - /* If use divided systeme clock */ - if (clockSource == 5U) - { - if (clkDiv > 256U) - { - val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK)); - val |= SPDIF_STC_SYSCLK_DF((clkDiv / 128U) - 1U) | SPDIF_STC_TXCLK_DF(127U); - base->STC = val; - } - else - { - val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK)); - val |= SPDIF_STC_SYSCLK_DF(1U) | SPDIF_STC_TXCLK_DF(clkDiv - 1U); - base->STC = val; - } - } - else - { - /* Other clock only uses txclk div */ - val = base->STC & (~(SPDIF_STC_TXCLK_DF_MASK | SPDIF_STC_SYSCLK_DF_MASK)); - val |= SPDIF_STC_TXCLK_DF(clkDiv - 1U); - base->STC = val; - } -} - -/*! - * brief Configures the SPDIF Rx audio format. - * - * The audio format can be changed at run-time. This function configures the sample rate and audio data - * format to be transferred. - * - * param base SPDIF base pointer. - * param clockSourceFreq_Hz SPDIF system clock frequency in hz. - */ -uint32_t SPDIF_GetRxSampleRate(SPDIF_Type *base, uint32_t clockSourceFreq_Hz) -{ - uint64_t gain = s_spdif_gain[((base->SRPC & SPDIF_SRPC_GAINSEL_MASK) >> SPDIF_SRPC_GAINSEL_SHIFT)]; - uint32_t measure = 0; - uint32_t sampleRate = 0; - uint64_t temp = 0; - - /* Wait the DPLL locked */ - while ((base->SRPC & SPDIF_SRPC_LOCK_MASK) == 0U) - { - } - - /* Get the measure value */ - measure = base->SRFM; - temp = (uint64_t)measure * (uint64_t)clockSourceFreq_Hz; - temp /= 1024U * 1024U * 128U * gain; - sampleRate = (uint32_t)temp; - - return sampleRate; -} - -/*! - * brief Sends data using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SPDIF base pointer. - * param buffer Pointer to the data to be written. - * param size Bytes to be written. - */ -void SPDIF_WriteBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size) -{ - assert(buffer != NULL); - assert((size % 6U) == 0U); - - uint32_t i = 0, j = 0, data = 0; - - while (i < size) - { - /* Wait until it can write data */ - while ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_TxFIFOEmpty) == 0x00U) - { - } - - /* Write left channel data */ - for (j = 0; j < 3U; j++) - { - data |= ((uint32_t)(*buffer) << (j * 8U)); - buffer++; - } - SPDIF_WriteLeftData(base, data); - - /* Write right channel data */ - data = 0; - for (j = 0; j < 3U; j++) - { - data |= ((uint32_t)(*buffer) << (j * 8U)); - buffer++; - } - SPDIF_WriteRightData(base, data); - - i += 6U; - } -} - -/*! - * brief Receives data using a blocking method. - * - * note This function blocks by polling until data is ready to be sent. - * - * param base SPDIF base pointer. - * param buffer Pointer to the data to be read. - * param size Bytes to be read. - */ -void SPDIF_ReadBlocking(SPDIF_Type *base, uint8_t *buffer, uint32_t size) -{ - assert(buffer != NULL); - assert((size % 6U) == 0U); - - uint32_t i = 0, j = 0, data = 0; - - while (i < size) - { - /* Wait until it can write data */ - while ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxFIFOFull) == 0x00U) - { - } - - /* Write left channel data */ - data = SPDIF_ReadLeftData(base); - for (j = 0; j < 3U; j++) - { - *buffer = ((uint8_t)(data >> (j * 8U)) & 0xFFU); - buffer++; - } - - /* Write right channel data */ - data = SPDIF_ReadRightData(base); - for (j = 0; j < 3U; j++) - { - *buffer = ((uint8_t)(data >> (j * 8U)) & 0xFFU); - buffer++; - } - - i += 6U; - } -} - -/*! - * brief Initializes the SPDIF Tx handle. - * - * This function initializes the Tx handle for the SPDIF Tx transactional APIs. Call - * this function once to get the handle initialized. - * - * param base SPDIF base pointer - * param handle SPDIF handle pointer. - * param callback Pointer to the user callback function. - * param userData User parameter passed to the callback function - */ -void SPDIF_TransferTxCreateHandle(SPDIF_Type *base, - spdif_handle_t *handle, - spdif_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - s_spdifHandle[SPDIF_GetInstance(base)][0] = handle; - - handle->callback = callback; - handle->userData = userData; - handle->watermark = - s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT]; - - /* Set the isr pointer */ - s_spdifTxIsr = SPDIF_TransferTxHandleIRQ; - - /* Enable Tx irq */ - (void)EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]); -} - -/*! - * brief Initializes the SPDIF Rx handle. - * - * This function initializes the Rx handle for the SPDIF Rx transactional APIs. Call - * this function once to get the handle initialized. - * - * param base SPDIF base pointer. - * param handle SPDIF handle pointer. - * param callback Pointer to the user callback function. - * param userData User parameter passed to the callback function. - */ -void SPDIF_TransferRxCreateHandle(SPDIF_Type *base, - spdif_handle_t *handle, - spdif_transfer_callback_t callback, - void *userData) -{ - assert(handle != NULL); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - s_spdifHandle[SPDIF_GetInstance(base)][1] = handle; - - handle->callback = callback; - handle->userData = userData; - handle->watermark = - s_spdif_rx_watermark[(base->SCR & SPDIF_SCR_RXFIFOFULL_SEL_MASK) >> SPDIF_SCR_RXFIFOFULL_SEL_SHIFT]; - - /* Set the isr pointer */ - s_spdifRxIsr = SPDIF_TransferRxHandleIRQ; - - /* Enable Rx irq */ - (void)EnableIRQ(s_spdifIRQ[SPDIF_GetInstance(base)]); -} - -/*! - * brief Performs an interrupt non-blocking send transfer on SPDIF. - * - * note This API returns immediately after the transfer initiates. - * Call the SPDIF_TxGetTransferStatusIRQ to poll the transfer status and check whether - * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer - * is finished. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - * param xfer Pointer to the spdif_transfer_t structure. - * retval kStatus_Success Successfully started the data receive. - * retval kStatus_SPDIF_TxBusy Previous receive still not finished. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t SPDIF_TransferSendNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer) -{ - assert(handle != NULL); - - /* Check if the queue is full */ - if (handle->spdifQueue[handle->queueUser].data != NULL) - { - return kStatus_SPDIF_QueueFull; - } - - /* Add into queue */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->spdifQueue[handle->queueUser].data = xfer->data; - handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - - /* Set the state to busy */ - handle->state = kSPDIF_Busy; - - /* Enable interrupt */ - SPDIF_EnableInterrupts(base, kSPDIF_TxFIFOEmpty); - - /* Enable Tx transfer */ - SPDIF_TxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Performs an interrupt non-blocking receive transfer on SPDIF. - * - * note This API returns immediately after the transfer initiates. - * Call the SPDIF_RxGetTransferStatusIRQ to poll the transfer status and check whether - * the transfer is finished. If the return status is not kStatus_SPDIF_Busy, the transfer - * is finished. - * - * param base SPDIF base pointer - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - * param xfer Pointer to the spdif_transfer_t structure. - * retval kStatus_Success Successfully started the data receive. - * retval kStatus_SPDIF_RxBusy Previous receive still not finished. - * retval kStatus_InvalidArgument The input parameter is invalid. - */ -status_t SPDIF_TransferReceiveNonBlocking(SPDIF_Type *base, spdif_handle_t *handle, spdif_transfer_t *xfer) -{ - assert(handle != NULL); - - /* Check if the queue is full */ - if (handle->spdifQueue[handle->queueUser].data != NULL) - { - return kStatus_SPDIF_QueueFull; - } - - /* Add into queue */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->spdifQueue[handle->queueUser].data = xfer->data; - handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->spdifQueue[handle->queueUser].udata = xfer->udata; - handle->spdifQueue[handle->queueUser].qdata = xfer->qdata; - handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - - /* Set state to busy */ - handle->state = kSPDIF_Busy; - - /* Enable interrupt */ - SPDIF_EnableInterrupts(base, (uint32_t)kSPDIF_UChannelReceiveRegisterFull | - (uint32_t)kSPDIF_QChannelReceiveRegisterFull | (uint32_t)kSPDIF_RxFIFOFull | - (uint32_t)kSPDIF_RxControlChannelChange); - - /* Enable Rx transfer */ - SPDIF_RxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Gets a set byte count. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - * param count Bytes count sent. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t SPDIF_TransferGetSendCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint8_t queueDriver = handle->queueDriver; - - if (handle->state != (uint32_t)kSPDIF_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriver] - handle->spdifQueue[queueDriver].dataSize); - } - - return status; -} - -/*! - * brief Gets a received byte count. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - * param count Bytes count received. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress. - */ -status_t SPDIF_TransferGetReceiveCount(SPDIF_Type *base, spdif_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - uint8_t queueDriver = handle->queueDriver; - - if (handle->state != (uint32_t)kSPDIF_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[queueDriver] - handle->spdifQueue[queueDriver].dataSize); - } - - return status; -} - -/*! - * brief Aborts the current send. - * - * note This API can be called any time when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - */ -void SPDIF_TransferAbortSend(SPDIF_Type *base, spdif_handle_t *handle) -{ - assert(handle != NULL); - - /* Use FIFO request interrupt and fifo error */ - SPDIF_DisableInterrupts(base, kSPDIF_TxFIFOEmpty); - - handle->state = kSPDIF_Idle; - - /* Clear the queue */ - (void)memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Aborts the current IRQ receive. - * - * note This API can be called when an interrupt non-blocking transfer initiates - * to abort the transfer early. - * - * param base SPDIF base pointer - * param handle Pointer to the spdif_handle_t structure which stores the transfer state. - */ -void SPDIF_TransferAbortReceive(SPDIF_Type *base, spdif_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable interrupt */ - SPDIF_DisableInterrupts(base, (uint32_t)kSPDIF_UChannelReceiveRegisterFull | - (uint32_t)kSPDIF_QChannelReceiveRegisterFull | (uint32_t)kSPDIF_RxFIFOFull | - (uint32_t)kSPDIF_RxControlChannelChange); - - handle->state = kSPDIF_Idle; - - /* Clear the queue */ - (void)memset(handle->spdifQueue, 0, sizeof(spdif_transfer_t) * SPDIF_XFER_QUEUE_SIZE); - handle->queueDriver = 0; - handle->queueUser = 0; -} - -/*! - * brief Tx interrupt handler. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure. - */ -void SPDIF_TransferTxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle) -{ - assert(handle != NULL); - - uint8_t *buffer = handle->spdifQueue[handle->queueDriver].data; - uint8_t dataSize = 0; - uint32_t i = 0, j = 0, data = 0; - - /* Do Transfer */ - if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_TxFIFOEmpty) != 0x00U) && - ((base->SIE & (uint32_t)kSPDIF_TxFIFOEmpty) != 0x00U)) - { - dataSize = handle->watermark; - while (i < dataSize) - { - data = 0; - /* Write left channel data */ - for (j = 0; j < 3U; j++) - { - data |= ((uint32_t)(*buffer) << (j * 8U)); - buffer++; - } - SPDIF_WriteLeftData(base, data); - - /* Write right channel data */ - data = 0; - for (j = 0; j < 3U; j++) - { - data |= ((uint32_t)(*buffer) << (j * 8U)); - buffer++; - } - SPDIF_WriteRightData(base, data); - - i++; - } - handle->spdifQueue[handle->queueDriver].dataSize -= (uint32_t)dataSize * 6U; - handle->spdifQueue[handle->queueDriver].data += dataSize * 6U; - - /* If finished a block, call the callback function */ - if (handle->spdifQueue[handle->queueDriver].dataSize == 0U) - { - (void)memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t)); - handle->queueDriver = (handle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_TxIdle, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->spdifQueue[handle->queueDriver].data == NULL) - { - SPDIF_TransferAbortSend(base, handle); - } - } -} - -/*! - * brief Tx interrupt handler. - * - * param base SPDIF base pointer. - * param handle Pointer to the spdif_handle_t structure. - */ -void SPDIF_TransferRxHandleIRQ(SPDIF_Type *base, spdif_handle_t *handle) -{ - assert(handle != NULL); - - uint8_t *buffer = NULL; - uint8_t dataSize = 0; - uint32_t i = 0, j = 0, data = 0; - - /* Handle Cnew flag */ - if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxControlChannelChange) != 0x00U) - { - /* Clear the interrupt flag */ - SPDIF_ClearStatusFlags(base, SPDIF_SIE_CNEW_MASK); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_RxCnew, handle->userData); - } - } - - /* Handle illegal symbol */ - if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxIllegalSymbol) != 0x00U) - { - SPDIF_ClearStatusFlags(base, kSPDIF_RxIllegalSymbol); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_RxIllegalSymbol, handle->userData); - } - } - - /* Handle Parity Bit Error */ - if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxParityBitError) != 0x00U) - { - SPDIF_ClearStatusFlags(base, kSPDIF_RxParityBitError); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_RxParityBitError, handle->userData); - } - } - - /* Handle DPlocked */ - if ((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxDPLLLocked) != 0x00U) - { - SPDIF_ClearStatusFlags(base, kSPDIF_RxDPLLLocked); - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_RxDPLLLocked, handle->userData); - } - } - - /* Handle Q channel full flag */ - if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_QChannelReceiveRegisterFull) != 0x00U) && - ((base->SIE & (uint32_t)kSPDIF_QChannelReceiveRegisterFull) != 0x00U)) - { - buffer = handle->spdifQueue[handle->queueDriver].qdata; - data = SPDIF_ReadQChannel(base); - buffer[0] = (uint8_t)data & 0xFFU; - buffer[1] = (uint8_t)(data >> 8U) & 0xFFU; - buffer[2] = (uint8_t)(data >> 16U) & 0xFFU; - } - - /* Handle U channel full flag */ - if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_UChannelReceiveRegisterFull) != 0x00U) && - ((base->SIE & (uint32_t)kSPDIF_UChannelReceiveRegisterFull) != 0x00U)) - { - buffer = handle->spdifQueue[handle->queueDriver].udata; - data = SPDIF_ReadUChannel(base); - buffer[0] = (uint8_t)data & 0xFFU; - buffer[1] = (uint8_t)(data >> 8U) & 0xFFU; - buffer[2] = (uint8_t)(data >> 16U) & 0xFFU; - } - - /* Handle audio data transfer */ - if (((SPDIF_GetStatusFlag(base) & (uint32_t)kSPDIF_RxFIFOFull) != 0x00U) && - ((base->SIE & (uint32_t)kSPDIF_RxFIFOFull) != 0x00U)) - { - dataSize = handle->watermark; - buffer = handle->spdifQueue[handle->queueDriver].data; - while (i < dataSize) - { - /* Read left channel data */ - data = SPDIF_ReadLeftData(base); - for (j = 0; j < 3U; j++) - { - *buffer = (uint8_t)((data >> (j * 8U)) & 0xFFU); - buffer++; - } - - /* Read right channel data */ - data = SPDIF_ReadRightData(base); - for (j = 0; j < 3U; j++) - { - *buffer = (uint8_t)((data >> (j * 8U)) & 0xFFU); - buffer++; - } - - i++; - } - handle->spdifQueue[handle->queueDriver].dataSize -= (uint32_t)dataSize * 6U; - handle->spdifQueue[handle->queueDriver].data += dataSize * 6U; - - /* If finished a block, call the callback function */ - if (handle->spdifQueue[handle->queueDriver].dataSize == 0x00U) - { - (void)memset(&handle->spdifQueue[handle->queueDriver], 0, sizeof(spdif_transfer_t)); - handle->queueDriver = (handle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - if (handle->callback != NULL) - { - (handle->callback)(base, handle, kStatus_SPDIF_RxIdle, handle->userData); - } - } - - /* If all data finished, just stop the transfer */ - if (handle->spdifQueue[handle->queueDriver].data == NULL) - { - SPDIF_TransferAbortReceive(base, handle); - } - } -} - -#ifndef __rtems__ -#if defined(SPDIF) -void SPDIF_DriverIRQHandler(void) -{ - if ((s_spdifHandle[0][0] != NULL) && (s_spdifTxIsr != NULL)) - { - s_spdifTxIsr(SPDIF, s_spdifHandle[0][0]); - } - - if ((s_spdifHandle[0][1] != NULL) && (s_spdifRxIsr != NULL)) - { - s_spdifRxIsr(SPDIF, s_spdifHandle[0][1]); - } - SDK_ISR_EXIT_BARRIER; -} -#endif -#endif /* __rtems__ */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif_edma.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif_edma.c deleted file mode 100644 index 8338a55f58..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_spdif_edma.c +++ /dev/null @@ -1,598 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2017-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_spdif_edma.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.spdif_edma" -#endif - -/******************************************************************************* - * Definitations - ******************************************************************************/ -/* Used for 32byte aligned */ -#define STCD_ADDR(address) (edma_tcd_t *)(((uint32_t)(address) + 32U) & ~0x1FU) - -/*<! Structure definition for uart_edma_private_handle_t. The structure is private. */ -typedef struct _spdif_edma_private_handle -{ - SPDIF_Type *base; - spdif_edma_handle_t *handle; -} spdif_edma_private_handle_t; - -/*! - * @brief Used for conversion between `void*` and `uint32_t`. - */ -typedef union pvoid_to_u32 -{ - void *pvoid; - uint32_t u32; -} pvoid_to_u32_t; - -/*! @brief spdif edma transfer state. */ -enum -{ - kSPDIF_Busy = 0x0U, /*!< SPDIF is busy */ - kSPDIF_Idle, /*!< Transfer is done. */ -}; - -/*<! Private handle only used for internally. */ -static spdif_edma_private_handle_t s_edmaPrivateHandle[FSL_FEATURE_SOC_SPDIF_COUNT][2]; -static uint8_t s_spdif_tx_watermark[4] = {16, 12, 8, 4}; -static uint8_t s_spdif_rx_watermark[4] = {1, 4, 8, 16}; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Submit SPDIF tcds to EDMA. - * - * @param base SPDIF base pointer. - */ -static status_t SPDIF_SubmitTransfer(edma_handle_t *handle, - const edma_transfer_config_t *config, - uint32_t rightChannel); - -/*! - * @brief SPDIF EDMA callback for send. - * - * @param handle pointer to spdif_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void SPDIF_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/*! - * @brief SPDIF EDMA callback for receive. - * - * @param handle pointer to spdif_edma_handle_t structure which stores the transfer state. - * @param userData Parameter for user callback. - * @param done If the DMA transfer finished. - * @param tcds The TCD index. - */ -static void SPDIF_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds); - -/******************************************************************************* - * Code - ******************************************************************************/ -static void SPDIF_TxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - spdif_edma_private_handle_t *privHandle = (spdif_edma_private_handle_t *)userData; - spdif_edma_handle_t *spdifHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&spdifHandle->spdifQueue[spdifHandle->queueDriver], 0, sizeof(spdif_edma_transfer_t)); - spdifHandle->queueDriver = (spdifHandle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - if (spdifHandle->callback != NULL) - { - (spdifHandle->callback)(privHandle->base, spdifHandle, kStatus_SPDIF_TxIdle, spdifHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (spdifHandle->spdifQueue[spdifHandle->queueDriver].rightData == NULL) - { - SPDIF_TransferAbortSendEDMA(privHandle->base, spdifHandle); - } -} - -static void SPDIF_RxEDMACallback(edma_handle_t *handle, void *userData, bool done, uint32_t tcds) -{ - spdif_edma_private_handle_t *privHandle = (spdif_edma_private_handle_t *)userData; - spdif_edma_handle_t *spdifHandle = privHandle->handle; - - /* If finished a block, call the callback function */ - (void)memset(&spdifHandle->spdifQueue[spdifHandle->queueDriver], 0, sizeof(spdif_edma_transfer_t)); - spdifHandle->queueDriver = (spdifHandle->queueDriver + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - if (spdifHandle->callback != NULL) - { - (spdifHandle->callback)(privHandle->base, spdifHandle, kStatus_SPDIF_RxIdle, spdifHandle->userData); - } - - /* If all data finished, just stop the transfer */ - if (spdifHandle->spdifQueue[spdifHandle->queueDriver].rightData == NULL) - { - SPDIF_TransferAbortReceiveEDMA(privHandle->base, spdifHandle); - } -} - -static status_t SPDIF_SubmitTransfer(edma_handle_t *handle, const edma_transfer_config_t *config, uint32_t rightChannel) -{ - edma_tcd_t *tcdRegs = (edma_tcd_t *)&handle->base->TCD[handle->channel]; - uint32_t primask; - uint16_t csr; - int8_t currentTcd; - int8_t previousTcd; - int8_t nextTcd; - int8_t tcdUsed = handle->tcdUsed; - int8_t tcdSize = handle->tcdSize; - - /* Check if tcd pool is full. */ - primask = DisableGlobalIRQ(); - if (tcdUsed >= tcdSize) - { - EnableGlobalIRQ(primask); - - return kStatus_EDMA_QueueFull; - } - currentTcd = handle->tail; - handle->tcdUsed++; - /* Calculate index of next TCD */ - nextTcd = currentTcd + 0x01; - if (nextTcd == handle->tcdSize) - { - nextTcd = 0x00; - } - /* Advance queue tail index */ - handle->tail = nextTcd; - EnableGlobalIRQ(primask); - /* Calculate index of previous TCD */ - previousTcd = (currentTcd != 0x00) ? (currentTcd - 0x01) : (handle->tcdSize - 0x01); - /* Configure current TCD block. */ - EDMA_TcdReset(&handle->tcdPool[currentTcd]); - EDMA_TcdSetTransferConfig(&handle->tcdPool[currentTcd], config, NULL); - /* Set channel link */ - EDMA_TcdSetChannelLink(&handle->tcdPool[currentTcd], kEDMA_MinorLink, rightChannel); - EDMA_TcdSetChannelLink(&handle->tcdPool[currentTcd], kEDMA_MajorLink, rightChannel); - /* Enable major interrupt */ - handle->tcdPool[currentTcd].CSR |= DMA_CSR_INTMAJOR_MASK; - /* Link current TCD with next TCD for identification of current TCD */ - handle->tcdPool[currentTcd].DLAST_SGA = (uint32_t)&handle->tcdPool[nextTcd]; - /* Chain from previous descriptor unless tcd pool size is 1(this descriptor is its own predecessor). */ - if (currentTcd != previousTcd) - { - /* Enable scatter/gather feature in the previous TCD block. */ - csr = (handle->tcdPool[previousTcd].CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK; - handle->tcdPool[previousTcd].CSR = csr; - /* - Check if the TCD block in the registers is the previous one (points to current TCD block). It - is used to check if the previous TCD linked has been loaded in TCD register. If so, it need to - link the TCD register in case link the current TCD with the dead chain when TCD loading occurs - before link the previous TCD block. - */ - if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[currentTcd]) - { - /* Enable scatter/gather also in the TCD registers. */ - csr = (tcdRegs->CSR | (uint16_t)DMA_CSR_ESG_MASK) & ~(uint16_t)DMA_CSR_DREQ_MASK; - /* Must write the CSR register one-time, because the transfer maybe finished anytime. */ - tcdRegs->CSR = csr; - /* - It is very important to check the ESG bit! - Because this hardware design: if DONE bit is set, the ESG bit can not be set. So it can - be used to check if the dynamic TCD link operation is successful. If ESG bit is not set - and the DLAST_SGA is not the next TCD address(it means the dynamic TCD link succeed and - the current TCD block has been loaded into TCD registers), it means transfer finished - and TCD link operation fail, so must install TCD content into TCD registers and enable - transfer again. And if ESG is set, it means transfer has notfinished, so TCD dynamic - link succeed. - */ - if ((tcdRegs->CSR & DMA_CSR_ESG_MASK) != 0x00U) - { - return kStatus_Success; - } - /* - Check whether the current TCD block is already loaded in the TCD registers. It is another - condition when ESG bit is not set: it means the dynamic TCD link succeed and the current - TCD block has been loaded into TCD registers. - */ - if (tcdRegs->DLAST_SGA == (uint32_t)&handle->tcdPool[nextTcd]) - { - return kStatus_Success; - } - /* - If go to this, means the previous transfer finished, and the DONE bit is set. - So shall configure TCD registers. - */ - } - else if (tcdRegs->DLAST_SGA != 0x00U) - { - /* The current TCD block has been linked successfully. */ - return kStatus_Success; - } - else - { - /* - DLAST_SGA is 0 and it means the first submit transfer, so shall configure - TCD registers. - */ - } - } - /* There is no live chain, TCD block need to be installed in TCD registers. */ - EDMA_InstallTCD(handle->base, handle->channel, &handle->tcdPool[currentTcd]); - /* Enable channel request again. */ - if ((handle->flags & 0x80U) != 0x00U) - { - handle->base->SERQ = DMA_SERQ_SERQ(handle->channel); - } - else - { - ; /* Intentional empty */ - } - - return kStatus_Success; -} - -/*! - * brief Initializes the SPDIF eDMA handle. - * - * This function initializes the SPDIF master DMA handle, which can be used for other SPDIF master transactional APIs. - * Usually, for a specified SPDIF instance, call this API once to get the initialized handle. - * - * param base SPDIF base pointer. - * param handle SPDIF eDMA handle pointer. - * param base SPDIF peripheral base address. - * param callback Pointer to user callback function. - * param userData User parameter passed to the callback function. - * param dmaLeftHandle eDMA handle pointer for left channel, this handle shall be static allocated by users. - * param dmaRightHandle eDMA handle pointer for right channel, this handle shall be static allocated by users. - */ -void SPDIF_TransferTxCreateHandleEDMA(SPDIF_Type *base, - spdif_edma_handle_t *handle, - spdif_edma_callback_t callback, - void *userData, - edma_handle_t *dmaLeftHandle, - edma_handle_t *dmaRightHandle) -{ - assert(handle != NULL); - assert(dmaLeftHandle != NULL); - assert(dmaRightHandle != NULL); - - uint32_t instance = SPDIF_GetInstance(base); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set spdif base to handle */ - handle->dmaLeftHandle = dmaLeftHandle; - handle->dmaRightHandle = dmaRightHandle; - handle->callback = callback; - handle->userData = userData; - handle->count = - s_spdif_tx_watermark[(base->SCR & SPDIF_SCR_TXFIFOEMPTY_SEL_MASK) >> SPDIF_SCR_TXFIFOEMPTY_SEL_SHIFT]; - - /* Set SPDIF state to idle */ - handle->state = kSPDIF_Idle; - - s_edmaPrivateHandle[instance][0].base = base; - s_edmaPrivateHandle[instance][0].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(dmaLeftHandle, STCD_ADDR(handle->leftTcd), SPDIF_XFER_QUEUE_SIZE); - EDMA_InstallTCDMemory(dmaRightHandle, STCD_ADDR(handle->rightTcd), SPDIF_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel, only right channel finished, a transfer finished */ - EDMA_SetCallback(dmaRightHandle, SPDIF_TxEDMACallback, &s_edmaPrivateHandle[instance][0]); -} - -/*! - * brief Initializes the SPDIF Rx eDMA handle. - * - * This function initializes the SPDIF slave DMA handle, which can be used for other SPDIF master transactional APIs. - * Usually, for a specified SPDIF instance, call this API once to get the initialized handle. - * - * param base SPDIF base pointer. - * param handle SPDIF eDMA handle pointer. - * param base SPDIF peripheral base address. - * param callback Pointer to user callback function. - * param userData User parameter passed to the callback function. - * param dmaLeftHandle eDMA handle pointer for left channel, this handle shall be static allocated by users. - * param dmaRightHandle eDMA handle pointer for right channel, this handle shall be static allocated by users. - */ -void SPDIF_TransferRxCreateHandleEDMA(SPDIF_Type *base, - spdif_edma_handle_t *handle, - spdif_edma_callback_t callback, - void *userData, - edma_handle_t *dmaLeftHandle, - edma_handle_t *dmaRightHandle) -{ - assert(handle != NULL); - assert(dmaLeftHandle != NULL); - assert(dmaRightHandle != NULL); - - uint32_t instance = SPDIF_GetInstance(base); - - /* Zero the handle */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set spdif base to handle */ - handle->dmaLeftHandle = dmaLeftHandle; - handle->dmaRightHandle = dmaRightHandle; - handle->callback = callback; - handle->userData = userData; - handle->count = s_spdif_rx_watermark[(base->SCR & SPDIF_SCR_RXFIFOFULL_SEL_MASK) >> SPDIF_SCR_RXFIFOFULL_SEL_SHIFT]; - - /* Set SPDIF state to idle */ - handle->state = kSPDIF_Idle; - - s_edmaPrivateHandle[instance][1].base = base; - s_edmaPrivateHandle[instance][1].handle = handle; - - /* Need to use scatter gather */ - EDMA_InstallTCDMemory(dmaLeftHandle, STCD_ADDR(handle->leftTcd), SPDIF_XFER_QUEUE_SIZE); - EDMA_InstallTCDMemory(dmaRightHandle, STCD_ADDR(handle->rightTcd), SPDIF_XFER_QUEUE_SIZE); - - /* Install callback for Tx dma channel */ - EDMA_SetCallback(dmaRightHandle, SPDIF_RxEDMACallback, &s_edmaPrivateHandle[instance][1]); -} - -/*! - * brief Performs a non-blocking SPDIF transfer using DMA. - * - * note This interface returns immediately after the transfer initiates. Call - * SPDIF_GetTransferStatus to poll the transfer status and check whether the SPDIF transfer is finished. - * - * param base SPDIF base pointer. - * param handle SPDIF eDMA handle pointer. - * param xfer Pointer to the DMA transfer structure. - * retval kStatus_Success Start a SPDIF eDMA send successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - * retval kStatus_TxBusy SPDIF is busy sending data. - */ -status_t SPDIF_TransferSendEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, spdif_edma_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - pvoid_to_u32_t destAddr; - edma_transfer_config_t config = {0}; - destAddr.u32 = SPDIF_TxGetLeftDataRegisterAddress(base); - - /* Check if input parameter invalid */ - if ((xfer->leftData == NULL) || (xfer->dataSize == 0U) || (xfer->rightData == NULL)) - { - return kStatus_InvalidArgument; - } - - if ((handle->spdifQueue[handle->queueUser].leftData != NULL) || - (handle->spdifQueue[handle->queueUser].rightData != NULL)) - { - return kStatus_SPDIF_QueueFull; - } - - /* Change the state of handle */ - handle->state = kSPDIF_Busy; - - /* Update the queue state */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->spdifQueue[handle->queueUser].leftData = xfer->leftData; - handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->spdifQueue[handle->queueUser].rightData = xfer->rightData; - handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - - /* Store the initially configured eDMA minor byte transfer count into the SPDIF handle */ - handle->nbytes = handle->count * 8U; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, xfer->leftData, 4U, destAddr.pvoid, 4U, (uint32_t)handle->count * 4U, xfer->dataSize, - kEDMA_MemoryToPeripheral); - (void)SPDIF_SubmitTransfer(handle->dmaLeftHandle, &config, handle->dmaRightHandle->channel); - - /* Prepare right channel */ - destAddr.u32 = SPDIF_TxGetRightDataRegisterAddress(base); - EDMA_PrepareTransfer(&config, xfer->rightData, 4U, destAddr.pvoid, 4U, (uint32_t)handle->count * 4U, xfer->dataSize, - kEDMA_MemoryToPeripheral); - (void)EDMA_SubmitTransfer(handle->dmaRightHandle, &config); - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaLeftHandle); - EDMA_StartTransfer(handle->dmaRightHandle); - - /* Enable DMA enable bit */ - SPDIF_EnableDMA(base, kSPDIF_TxDMAEnable, true); - - /* Enable SPDIF Tx clock */ - SPDIF_TxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Performs a non-blocking SPDIF receive using eDMA. - * - * note This interface returns immediately after the transfer initiates. Call - * the SPDIF_GetReceiveRemainingBytes to poll the transfer status and check whether the SPDIF transfer is finished. - * - * param base SPDIF base pointer - * param handle SPDIF eDMA handle pointer. - * param xfer Pointer to DMA transfer structure. - * retval kStatus_Success Start a SPDIF eDMA receive successfully. - * retval kStatus_InvalidArgument The input argument is invalid. - * retval kStatus_RxBusy SPDIF is busy receiving data. - */ -status_t SPDIF_TransferReceiveEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, spdif_edma_transfer_t *xfer) -{ - assert(handle != NULL); - assert(xfer != NULL); - - pvoid_to_u32_t srcAddr; - edma_transfer_config_t config = {0}; - srcAddr.u32 = SPDIF_RxGetLeftDataRegisterAddress(base); - - /* Check if input parameter invalid */ - if ((xfer->leftData == NULL) || (xfer->dataSize == 0U) || (xfer->rightData == NULL)) - { - return kStatus_InvalidArgument; - } - - if ((handle->spdifQueue[handle->queueUser].leftData != NULL) || - (handle->spdifQueue[handle->queueUser].rightData != NULL)) - { - return kStatus_SPDIF_QueueFull; - } - - /* Change the state of handle */ - handle->state = kSPDIF_Busy; - - /* Update the queue state */ - handle->transferSize[handle->queueUser] = xfer->dataSize; - handle->spdifQueue[handle->queueUser].leftData = xfer->leftData; - handle->spdifQueue[handle->queueUser].dataSize = xfer->dataSize; - handle->spdifQueue[handle->queueUser].rightData = xfer->rightData; - handle->queueUser = (handle->queueUser + 0x01U) % SPDIF_XFER_QUEUE_SIZE; - - /* Store the initially configured eDMA minor byte transfer count into the SPDIF handle */ - handle->nbytes = handle->count * 8U; - - /* Prepare edma configure */ - EDMA_PrepareTransfer(&config, srcAddr.pvoid, 4U, xfer->leftData, 4U, (uint32_t)handle->count * 4U, xfer->dataSize, - kEDMA_PeripheralToMemory); - /* Use specific submit function to enable channel link */ - (void)SPDIF_SubmitTransfer(handle->dmaLeftHandle, &config, handle->dmaRightHandle->channel); - - /* Prepare right channel */ - srcAddr.u32 = SPDIF_RxGetRightDataRegisterAddress(base); - EDMA_PrepareTransfer(&config, srcAddr.pvoid, 4U, xfer->rightData, 4U, (uint32_t)handle->count * 4U, xfer->dataSize, - kEDMA_PeripheralToMemory); - (void)EDMA_SubmitTransfer(handle->dmaRightHandle, &config); - - /* Start DMA transfer */ - EDMA_StartTransfer(handle->dmaLeftHandle); - EDMA_StartTransfer(handle->dmaRightHandle); - - /* Enable DMA enable bit */ - SPDIF_EnableDMA(base, kSPDIF_RxDMAEnable, true); - - /* Enable SPDIF Rx clock */ - SPDIF_RxEnable(base, true); - - return kStatus_Success; -} - -/*! - * brief Aborts a SPDIF transfer using eDMA. - * - * param base SPDIF base pointer. - * param handle SPDIF eDMA handle pointer. - */ -void SPDIF_TransferAbortSendEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaLeftHandle); - EDMA_AbortTransfer(handle->dmaRightHandle); - - /* Disable DMA enable bit */ - SPDIF_EnableDMA(base, kSPDIF_TxDMAEnable, false); - - /* Set internal state */ - (void)memset(handle->spdifQueue, 0, sizeof(handle->spdifQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - handle->queueUser = 0U; - handle->queueDriver = 0U; - - /* Set the handle state */ - handle->state = kSPDIF_Idle; -} - -/*! - * brief Aborts a SPDIF receive using eDMA. - * - * param base SPDIF base pointer - * param handle SPDIF eDMA handle pointer. - */ -void SPDIF_TransferAbortReceiveEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle) -{ - assert(handle != NULL); - - /* Disable dma */ - EDMA_AbortTransfer(handle->dmaLeftHandle); - EDMA_AbortTransfer(handle->dmaRightHandle); - - /* Disable DMA enable bit */ - SPDIF_EnableDMA(base, kSPDIF_RxDMAEnable, false); - - /* Set internal state */ - (void)memset(handle->spdifQueue, 0, sizeof(handle->spdifQueue)); - (void)memset(handle->transferSize, 0, sizeof(handle->transferSize)); - handle->queueUser = 0U; - handle->queueDriver = 0U; - - /* Set the handle state */ - handle->state = kSPDIF_Idle; -} - -/*! - * brief Gets byte count sent by SPDIF. - * - * param base SPDIF base pointer. - * param handle SPDIF eDMA handle pointer. - * param count Bytes count sent by SPDIF. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. - */ -status_t SPDIF_TransferGetSendCountEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kSPDIF_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaRightHandle->base, handle->dmaRightHandle->channel)); - } - - return status; -} - -/*! - * brief Gets byte count received by SPDIF. - * - * param base SPDIF base pointer - * param handle SPDIF eDMA handle pointer. - * param count Bytes count received by SPDIF. - * retval kStatus_Success Succeed get the transfer count. - * retval kStatus_NoTransferInProgress There is no non-blocking transaction in progress. - */ -status_t SPDIF_TransferGetReceiveCountEDMA(SPDIF_Type *base, spdif_edma_handle_t *handle, size_t *count) -{ - assert(handle != NULL); - - status_t status = kStatus_Success; - - if (handle->state != (uint32_t)kSPDIF_Busy) - { - status = kStatus_NoTransferInProgress; - } - else - { - *count = (handle->transferSize[handle->queueDriver] - - (uint32_t)handle->nbytes * - EDMA_GetRemainingMajorLoopCount(handle->dmaRightHandle->base, handle->dmaRightHandle->channel)); - } - - return status; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_src.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_src.c deleted file mode 100644 index 10af22893a..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_src.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_src.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.src" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/******************************************************************************* - * Code - ******************************************************************************/ - -/*! - * brief Clear the status flags of SRC. - * - * param base SRC peripheral base address. - * param Mask value of status flags to be cleared, see to #_src_reset_status_flags. - */ -void SRC_ClearResetStatusFlags(SRC_Type *base, uint32_t flags) -{ - uint32_t tmp32 = base->SRSR; - - if (0U != (SRC_SRSR_TSR_MASK & flags)) - { - tmp32 &= ~SRC_SRSR_TSR_MASK; /* Write 0 to clear. */ - } - - if (0U != (SRC_SRSR_W1C_BITS_MASK & flags)) - { - tmp32 |= (SRC_SRSR_W1C_BITS_MASK & flags); /* Write 1 to clear. */ - } - - base->SRSR = tmp32; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tempmon.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tempmon.c deleted file mode 100644 index 1f65d3bc5f..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tempmon.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2018-2019 NXP - * All rights reserved. - * - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_tempmon.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.tempmon" -#endif - -/*! @brief TEMPMON calibration data mask. */ -#define TEMPMON_HOTTEMPMASK 0xFFU -#define TEMPMON_HOTTEMPSHIFT 0x00U -#define TEMPMON_HOTCOUNTMASK 0xFFF00U -#define TEMPMON_HOTCOUNTSHIFT 0X08U -#define TEMPMON_ROOMCOUNTMASK 0xFFF00000U -#define TEMPMON_ROOMCOUNTSHIFT 0x14U - -/*! @brief the room temperature. */ -#define TEMPMON_ROOMTEMP 25.0f - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/******************************************************************************* - * Variables - ******************************************************************************/ - -static uint32_t s_hotTemp; /*!< The value of TEMPMON_TEMPSENSE0[TEMP_VALUE] at room temperature .*/ -static uint32_t s_hotCount; /*!< The value of TEMPMON_TEMPSENSE0[TEMP_VALUE] at the hot temperature.*/ -static float s_hotT_ROOM; /*!< The value of s_hotTemp minus room temperature(25��).*/ -static uint32_t s_roomC_hotC; /*!< The value of s_roomCount minus s_hotCount.*/ - -/******************************************************************************* - * Code - ******************************************************************************/ -/*! - * brief Initializes the TEMPMON module. - * - * param base TEMPMON base pointer - * param config Pointer to configuration structure. - */ -void TEMPMON_Init(TEMPMON_Type *base, const tempmon_config_t *config) -{ - assert(NULL != config); - - uint32_t calibrationData; - uint32_t roomCount; - - /* Power on the temperature sensor*/ - base->TEMPSENSE0 &= ~TEMPMON_TEMPSENSE0_POWER_DOWN_MASK; - - /* Set temperature monitor frequency */ - base->TEMPSENSE1 = TEMPMON_TEMPSENSE1_MEASURE_FREQ(config->frequency); - - /* ready to read calibration data */ - calibrationData = OCOTP->ANA1; - s_hotTemp = (uint32_t)(calibrationData & TEMPMON_HOTTEMPMASK) >> TEMPMON_HOTTEMPSHIFT; - s_hotCount = (uint32_t)(calibrationData & TEMPMON_HOTCOUNTMASK) >> TEMPMON_HOTCOUNTSHIFT; - roomCount = (uint32_t)(calibrationData & TEMPMON_ROOMCOUNTMASK) >> TEMPMON_ROOMCOUNTSHIFT; - - s_hotT_ROOM = (float)s_hotTemp - TEMPMON_ROOMTEMP; - s_roomC_hotC = roomCount - s_hotCount; - - /* Set alarm temperature */ - TEMPMON_SetTempAlarm(base, config->highAlarmTemp, kTEMPMON_HighAlarmMode); - TEMPMON_SetTempAlarm(base, config->panicAlarmTemp, kTEMPMON_PanicAlarmMode); - TEMPMON_SetTempAlarm(base, config->lowAlarmTemp, kTEMPMON_LowAlarmMode); -} - -/*! - * brief Deinitializes the TEMPMON module. - * - * param base TEMPMON base pointer - */ -void TEMPMON_Deinit(TEMPMON_Type *base) -{ - base->TEMPSENSE0 |= TEMPMON_TEMPSENSE0_POWER_DOWN_MASK; -} - -/*! - * brief Gets the default configuration structure. - * - * This function initializes the TEMPMON configuration structure to a default value. The default - * values are: - * tempmonConfig->frequency = 0x02U; - * tempmonConfig->highAlarmTemp = 44U; - * tempmonConfig->panicAlarmTemp = 90U; - * tempmonConfig->lowAlarmTemp = 39U; - * - * param config Pointer to a configuration structure. - */ -void TEMPMON_GetDefaultConfig(tempmon_config_t *config) -{ - assert(config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - /* Default measure frequency */ - config->frequency = 0x03U; - /* Default high alarm temperature */ - config->highAlarmTemp = 40U; - /* Default panic alarm temperature */ - config->panicAlarmTemp = 90U; - /* Default low alarm temperature */ - config->lowAlarmTemp = 20U; -} - -/*! - * brief Get current temperature with the fused temperature calibration data. - * - * param base TEMPMON base pointer - * return current temperature with degrees Celsius. - */ -float TEMPMON_GetCurrentTemperature(TEMPMON_Type *base) -{ - /* Check arguments */ - assert(NULL != base); - - uint32_t nmeas; - float tmeas; - - while (0U == (base->TEMPSENSE0 & TEMPMON_TEMPSENSE0_FINISHED_MASK)) - { - } - - /* ready to read temperature code value */ - nmeas = (base->TEMPSENSE0 & TEMPMON_TEMPSENSE0_TEMP_CNT_MASK) >> TEMPMON_TEMPSENSE0_TEMP_CNT_SHIFT; - - /* Calculate temperature */ - tmeas = (float)s_hotTemp - (((float)nmeas - (float)s_hotCount) * s_hotT_ROOM / (float)s_roomC_hotC); - - return tmeas; -} - -/*! - * brief Set the temperature count (raw sensor output) that will generate an alarm interrupt. - * - * param base TEMPMON base pointer - * param tempVal The alarm temperature with degrees Celsius - * param alarmMode The alarm mode. - */ -void TEMPMON_SetTempAlarm(TEMPMON_Type *base, uint32_t tempVal, tempmon_alarm_mode alarmMode) -{ - /* Check arguments */ - assert(NULL != base); - - uint32_t tempCodeVal; - uint32_t tempRegVal; - - /* Calculate alarm temperature code value */ - tempCodeVal = (uint32_t)(s_hotCount + (s_hotTemp - tempVal) * s_roomC_hotC / (uint32_t)s_hotT_ROOM); - - switch (alarmMode) - { - case kTEMPMON_HighAlarmMode: - /* Clear alarm value and set a new high alarm temperature code value */ - tempRegVal = base->TEMPSENSE0; - tempRegVal = - (tempRegVal & ~TEMPMON_TEMPSENSE0_ALARM_VALUE_MASK) | TEMPMON_TEMPSENSE0_ALARM_VALUE(tempCodeVal); - base->TEMPSENSE0 = tempRegVal; - break; - - case kTEMPMON_PanicAlarmMode: - /* Clear panic alarm value and set a new panic alarm temperature code value */ - tempRegVal = base->TEMPSENSE2; - tempRegVal = (tempRegVal & ~TEMPMON_TEMPSENSE2_PANIC_ALARM_VALUE_MASK) | - TEMPMON_TEMPSENSE2_PANIC_ALARM_VALUE(tempCodeVal); - base->TEMPSENSE2 = tempRegVal; - break; - - case kTEMPMON_LowAlarmMode: - /* Clear low alarm value and set a new low alarm temperature code value */ - tempRegVal = base->TEMPSENSE2; - tempRegVal = (tempRegVal & ~TEMPMON_TEMPSENSE2_LOW_ALARM_VALUE_MASK) | - TEMPMON_TEMPSENSE2_LOW_ALARM_VALUE(tempCodeVal); - base->TEMPSENSE2 = tempRegVal; - break; - - default: - assert(false); - break; - } -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_trng.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_trng.c deleted file mode 100644 index 4f4773d9c0..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_trng.c +++ /dev/null @@ -1,1935 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2017, 2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include "fsl_trng.h" - -#if defined(FSL_FEATURE_SOC_TRNG_COUNT) && FSL_FEATURE_SOC_TRNG_COUNT - -/******************************************************************************* - * Definitions - *******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.trng" -#endif - -/* Default values for user configuration structure.*/ -#if (defined(KW40Z4_SERIES) || defined(KW41Z4_SERIES) || defined(KW31Z4_SERIES) || defined(KW21Z4_SERIES) || \ - defined(MCIMX7U5_M4_SERIES) || defined(KW36Z4_SERIES) || defined(KW37A4_SERIES) || defined(KW37Z4_SERIES) || \ - defined(KW38A4_SERIES) || defined(KW38Z4_SERIES) || defined(KW39A4_SERIES) || defined(KW35Z4_SERIES)) -#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv8 -#elif (defined(KV56F24_SERIES) || defined(KV58F24_SERIES) || defined(KL28Z7_SERIES) || defined(KL81Z7_SERIES) || \ - defined(KL82Z7_SERIES) || defined(K32L2A41A_SERIES)) -#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv4 -#elif defined(K81F25615_SERIES) -#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv2 -#else -/* Default value for the TRNG user configuration structure can be optionally - defined by device specific preprocessor macros. */ -#if defined(FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_OSC_DIV) && \ - (FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_OSC_DIV > 0) -#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV (FSL_FEATURE_TRNG_USER_CONFIG_DEFAULT_OSC_DIV_VALUE) -#else -#define TRNG_USER_CONFIG_DEFAULT_OSC_DIV kTRNG_RingOscDiv0 -#endif -#endif - -#define TRNG_USER_CONFIG_DEFAULT_LOCK 0 -#define TRNG_USER_CONFIG_DEFAULT_ENTROPY_DELAY 3200 -#define TRNG_USER_CONFIG_DEFAULT_SAMPLE_SIZE 2500 -#define TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT 63 -#define TRNG_USER_CONFIG_DEFAULT_RETRY_COUNT 1 -#define TRNG_USER_CONFIG_DEFAULT_RUN_MAX_LIMIT 34 - -#define TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM 1384 -#define TRNG_USER_CONFIG_DEFAULT_MONOBIT_MINIMUM (TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM - 268) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM 405 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM - 178) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM 220 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM - 122) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM 125 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM - 88) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM 75 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM - 64) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM 47 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM - 46) -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM 47 -#define TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MINIMUM (TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM - 46) -#define TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM 26912 -#define TRNG_USER_CONFIG_DEFAULT_POKER_MINIMUM (TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM - 2467) - -#if defined(FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM) && \ - (FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM > 0) -#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM (FSL_FEATURE_TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM_VALUE) -#else -#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM 25600 -#endif - -#if defined(FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM) && \ - (FSL_FEATURE_TRNG_FORCE_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM > 0) -#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM (FSL_FEATURE_TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM_VALUE) -#else -#define TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM 1600 -#endif - -/*! @brief TRNG work mode */ -typedef enum _trng_work_mode -{ - kTRNG_WorkModeRun = 0U, /*!< Run Mode. */ - kTRNG_WorkModeProgram = 1U /*!< Program Mode. */ -} trng_work_mode_t; - -/*! @brief TRNG statistical check type*/ -typedef enum _trng_statistical_check -{ - kTRNG_StatisticalCheckMonobit = - 1U, /*!< Statistical check of number of ones/zero detected during entropy generation. */ - kTRNG_StatisticalCheckRunBit1, /*!< Statistical check of number of runs of length 1 detected during entropy - generation. */ - kTRNG_StatisticalCheckRunBit2, /*!< Statistical check of number of runs of length 2 detected during entropy - generation. */ - kTRNG_StatisticalCheckRunBit3, /*!< Statistical check of number of runs of length 3 detected during entropy - generation. */ - kTRNG_StatisticalCheckRunBit4, /*!< Statistical check of number of runs of length 4 detected during entropy - generation. */ - kTRNG_StatisticalCheckRunBit5, /*!< Statistical check of number of runs of length 5 detected during entropy - generation. */ - kTRNG_StatisticalCheckRunBit6Plus, /*!< Statistical check of number of runs of length 6 or more detected during - entropy generation. */ - kTRNG_StatisticalCheckPoker, /*!< Statistical check of "Poker Test". */ - kTRNG_StatisticalCheckFrequencyCount /*!< Statistical check of entropy sample frequency count. */ -} trng_statistical_check_t; - -/******************************************************************************* - * TRNG_SCMISC - RNG Statistical Check Miscellaneous Register - ******************************************************************************/ -/*! - * @name Register TRNG_SCMISC, field RTY_CT[19:16] (RW) - * - * RETRY COUNT. If a statistical check fails during the TRNG Entropy Generation, - * the RTY_CT value indicates the number of times a retry should occur before - * generating an error. This field is writable only if MCTL[PRGM] bit is 1. This - * field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 1h by writing - * the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCMISC_RTY_CT field. */ -#define TRNG_RD_SCMISC_RTY_CT(base) ((TRNG_SCMISC_REG(base) & TRNG_SCMISC_RTY_CT_MASK) >> TRNG_SCMISC_RTY_CT_SHIFT) - -/*! @brief Set the RTY_CT field to a new value. */ -#define TRNG_WR_SCMISC_RTY_CT(base, value) (TRNG_RMW_SCMISC(base, TRNG_SCMISC_RTY_CT_MASK, TRNG_SCMISC_RTY_CT(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCML - RNG Statistical Check Monobit Limit Register - ******************************************************************************/ -/*! - * @brief TRNG_SCML - RNG Statistical Check Monobit Limit Register (RW) - * - * Reset value: 0x010C0568U - * - * The RNG Statistical Check Monobit Limit Register defines the allowable - * maximum and minimum number of ones/zero detected during entropy generation. To pass - * the test, the number of ones/zeroes generated must be less than the programmed - * maximum value, and the number of ones/zeroes generated must be greater than - * (maximum - range). If this test fails, the Retry Counter in SCMISC will be - * decremented, and a retry will occur if the Retry Count has not reached zero. If - * the Retry Count has reached zero, an error will be generated. Note that this - * offset (0xBASE_0620) is used as SCML only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, - * this offset is used as SCMC readback register. - */ -/*! - * @name Constants and macros for entire TRNG_SCML register - */ -/*@{*/ -#define TRNG_SCML_REG(base) ((base)->SCML) -#define TRNG_RD_SCML(base) (TRNG_SCML_REG(base)) -#define TRNG_WR_SCML(base, value) (TRNG_SCML_REG(base) = (value)) -#define TRNG_RMW_SCML(base, mask, value) (TRNG_WR_SCML(base, (TRNG_RD_SCML(base) & ~(mask)) | (value))) -/*@}*/ -/*! - * @name Register TRNG_SCML, field MONO_MAX[15:0] (RW) - * - * Monobit Maximum Limit. Defines the maximum allowable count taken during - * entropy generation. The number of ones/zeroes detected during entropy generation - * must be less than MONO_MAX, else a retry or error will occur. This register is - * cleared to 00056Bh (decimal 1387) by writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCML_MONO_MAX field. */ -#define TRNG_RD_SCML_MONO_MAX(base) ((TRNG_SCML_REG(base) & TRNG_SCML_MONO_MAX_MASK) >> TRNG_SCML_MONO_MAX_SHIFT) - -/*! @brief Set the MONO_MAX field to a new value. */ -#define TRNG_WR_SCML_MONO_MAX(base, value) (TRNG_RMW_SCML(base, TRNG_SCML_MONO_MAX_MASK, TRNG_SCML_MONO_MAX(value))) -/*@}*/ -/*! - * @name Register TRNG_SCML, field MONO_RNG[31:16] (RW) - * - * Monobit Range. The number of ones/zeroes detected during entropy generation - * must be greater than MONO_MAX - MONO_RNG, else a retry or error will occur. - * This register is cleared to 000112h (decimal 274) by writing the MCTL[RST_DEF] - * bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCML_MONO_RNG field. */ -#define TRNG_RD_SCML_MONO_RNG(base) ((TRNG_SCML_REG(base) & TRNG_SCML_MONO_RNG_MASK) >> TRNG_SCML_MONO_RNG_SHIFT) - -/*! @brief Set the MONO_RNG field to a new value. */ -#define TRNG_WR_SCML_MONO_RNG(base, value) (TRNG_RMW_SCML(base, TRNG_SCML_MONO_RNG_MASK, TRNG_SCML_MONO_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR1L - RNG Statistical Check Run Length 1 Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR1L - RNG Statistical Check Run Length 1 Limit Register (RW) - * - * Reset value: 0x00B20195U - * - * The RNG Statistical Check Run Length 1 Limit Register defines the allowable - * maximum and minimum number of runs of length 1 detected during entropy - * generation. To pass the test, the number of runs of length 1 (for samples of both 0 - * and 1) must be less than the programmed maximum value, and the number of runs of - * length 1 must be greater than (maximum - range). If this test fails, the - * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry - * Count has not reached zero. If the Retry Count has reached zero, an error will - * be generated. Note that this address (0xBASE_0624) is used as SCR1L only if - * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR1C readback - * register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR1L register - */ -/*@{*/ -#define TRNG_SCR1L_REG(base) ((base)->SCR1L) -#define TRNG_RD_SCR1L(base) (TRNG_SCR1L_REG(base)) -#define TRNG_WR_SCR1L(base, value) (TRNG_SCR1L_REG(base) = (value)) -#define TRNG_RMW_SCR1L(base, mask, value) (TRNG_WR_SCR1L(base, (TRNG_RD_SCR1L(base) & ~(mask)) | (value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR1L, field RUN1_MAX[14:0] (RW) - * - * Run Length 1 Maximum Limit. Defines the maximum allowable runs of length 1 - * (for both 0 and 1) detected during entropy generation. The number of runs of - * length 1 detected during entropy generation must be less than RUN1_MAX, else a - * retry or error will occur. This register is cleared to 01E5h (decimal 485) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR1L_RUN1_MAX field. */ -#define TRNG_RD_SCR1L_RUN1_MAX(base) ((TRNG_SCR1L_REG(base) & TRNG_SCR1L_RUN1_MAX_MASK) >> TRNG_SCR1L_RUN1_MAX_SHIFT) - -/*! @brief Set the RUN1_MAX field to a new value. */ -#define TRNG_WR_SCR1L_RUN1_MAX(base, value) (TRNG_RMW_SCR1L(base, TRNG_SCR1L_RUN1_MAX_MASK, TRNG_SCR1L_RUN1_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR1L, field RUN1_RNG[30:16] (RW) - * - * Run Length 1 Range. The number of runs of length 1 (for both 0 and 1) - * detected during entropy generation must be greater than RUN1_MAX - RUN1_RNG, else a - * retry or error will occur. This register is cleared to 0102h (decimal 258) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR1L_RUN1_RNG field. */ -#define TRNG_RD_SCR1L_RUN1_RNG(base) ((TRNG_SCR1L_REG(base) & TRNG_SCR1L_RUN1_RNG_MASK) >> TRNG_SCR1L_RUN1_RNG_SHIFT) - -/*! @brief Set the RUN1_RNG field to a new value. */ -#define TRNG_WR_SCR1L_RUN1_RNG(base, value) (TRNG_RMW_SCR1L(base, TRNG_SCR1L_RUN1_RNG_MASK, TRNG_SCR1L_RUN1_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR2L - RNG Statistical Check Run Length 2 Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR2L - RNG Statistical Check Run Length 2 Limit Register (RW) - * - * Reset value: 0x007A00DCU - * - * The RNG Statistical Check Run Length 2 Limit Register defines the allowable - * maximum and minimum number of runs of length 2 detected during entropy - * generation. To pass the test, the number of runs of length 2 (for samples of both 0 - * and 1) must be less than the programmed maximum value, and the number of runs of - * length 2 must be greater than (maximum - range). If this test fails, the - * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry - * Count has not reached zero. If the Retry Count has reached zero, an error will - * be generated. Note that this address (0xBASE_0628) is used as SCR2L only if - * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR2C readback - * register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR2L register - */ -/*@{*/ -#define TRNG_SCR2L_REG(base) ((base)->SCR2L) -#define TRNG_RD_SCR2L(base) (TRNG_SCR2L_REG(base)) -#define TRNG_WR_SCR2L(base, value) (TRNG_SCR2L_REG(base) = (value)) -#define TRNG_RMW_SCR2L(base, mask, value) (TRNG_WR_SCR2L(base, (TRNG_RD_SCR2L(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCR2L bitfields - */ - -/*! - * @name Register TRNG_SCR2L, field RUN2_MAX[13:0] (RW) - * - * Run Length 2 Maximum Limit. Defines the maximum allowable runs of length 2 - * (for both 0 and 1) detected during entropy generation. The number of runs of - * length 2 detected during entropy generation must be less than RUN2_MAX, else a - * retry or error will occur. This register is cleared to 00DCh (decimal 220) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR2L_RUN2_MAX field. */ -#define TRNG_RD_SCR2L_RUN2_MAX(base) ((TRNG_SCR2L_REG(base) & TRNG_SCR2L_RUN2_MAX_MASK) >> TRNG_SCR2L_RUN2_MAX_SHIFT) - -/*! @brief Set the RUN2_MAX field to a new value. */ -#define TRNG_WR_SCR2L_RUN2_MAX(base, value) (TRNG_RMW_SCR2L(base, TRNG_SCR2L_RUN2_MAX_MASK, TRNG_SCR2L_RUN2_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR2L, field RUN2_RNG[29:16] (RW) - * - * Run Length 2 Range. The number of runs of length 2 (for both 0 and 1) - * detected during entropy generation must be greater than RUN2_MAX - RUN2_RNG, else a - * retry or error will occur. This register is cleared to 007Ah (decimal 122) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR2L_RUN2_RNG field. */ -#define TRNG_RD_SCR2L_RUN2_RNG(base) ((TRNG_SCR2L_REG(base) & TRNG_SCR2L_RUN2_RNG_MASK) >> TRNG_SCR2L_RUN2_RNG_SHIFT) - -/*! @brief Set the RUN2_RNG field to a new value. */ -#define TRNG_WR_SCR2L_RUN2_RNG(base, value) (TRNG_RMW_SCR2L(base, TRNG_SCR2L_RUN2_RNG_MASK, TRNG_SCR2L_RUN2_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR3L - RNG Statistical Check Run Length 3 Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR3L - RNG Statistical Check Run Length 3 Limit Register (RW) - * - * Reset value: 0x0058007DU - * - * The RNG Statistical Check Run Length 3 Limit Register defines the allowable - * maximum and minimum number of runs of length 3 detected during entropy - * generation. To pass the test, the number of runs of length 3 (for samples of both 0 - * and 1) must be less than the programmed maximum value, and the number of runs of - * length 3 must be greater than (maximum - range). If this test fails, the - * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry - * Count has not reached zero. If the Retry Count has reached zero, an error will - * be generated. Note that this address (0xBASE_062C) is used as SCR3L only if - * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR3C readback - * register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR3L register - */ -/*@{*/ -#define TRNG_SCR3L_REG(base) ((base)->SCR3L) -#define TRNG_RD_SCR3L(base) (TRNG_SCR3L_REG(base)) -#define TRNG_WR_SCR3L(base, value) (TRNG_SCR3L_REG(base) = (value)) -#define TRNG_RMW_SCR3L(base, mask, value) (TRNG_WR_SCR3L(base, (TRNG_RD_SCR3L(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCR3L bitfields - */ - -/*! - * @name Register TRNG_SCR3L, field RUN3_MAX[12:0] (RW) - * - * Run Length 3 Maximum Limit. Defines the maximum allowable runs of length 3 - * (for both 0 and 1) detected during entropy generation. The number of runs of - * length 3 detected during entropy generation must be less than RUN3_MAX, else a - * retry or error will occur. This register is cleared to 007Dh (decimal 125) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR3L_RUN3_MAX field. */ -#define TRNG_RD_SCR3L_RUN3_MAX(base) ((TRNG_SCR3L_REG(base) & TRNG_SCR3L_RUN3_MAX_MASK) >> TRNG_SCR3L_RUN3_MAX_SHIFT) - -/*! @brief Set the RUN3_MAX field to a new value. */ -#define TRNG_WR_SCR3L_RUN3_MAX(base, value) (TRNG_RMW_SCR3L(base, TRNG_SCR3L_RUN3_MAX_MASK, TRNG_SCR3L_RUN3_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR3L, field RUN3_RNG[28:16] (RW) - * - * Run Length 3 Range. The number of runs of length 3 (for both 0 and 1) - * detected during entropy generation must be greater than RUN3_MAX - RUN3_RNG, else a - * retry or error will occur. This register is cleared to 0058h (decimal 88) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR3L_RUN3_RNG field. */ -#define TRNG_RD_SCR3L_RUN3_RNG(base) ((TRNG_SCR3L_REG(base) & TRNG_SCR3L_RUN3_RNG_MASK) >> TRNG_SCR3L_RUN3_RNG_SHIFT) - -/*! @brief Set the RUN3_RNG field to a new value. */ -#define TRNG_WR_SCR3L_RUN3_RNG(base, value) (TRNG_RMW_SCR3L(base, TRNG_SCR3L_RUN3_RNG_MASK, TRNG_SCR3L_RUN3_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR4L - RNG Statistical Check Run Length 4 Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR4L - RNG Statistical Check Run Length 4 Limit Register (RW) - * - * Reset value: 0x0040004BU - * - * The RNG Statistical Check Run Length 4 Limit Register defines the allowable - * maximum and minimum number of runs of length 4 detected during entropy - * generation. To pass the test, the number of runs of length 4 (for samples of both 0 - * and 1) must be less than the programmed maximum value, and the number of runs of - * length 4 must be greater than (maximum - range). If this test fails, the - * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry - * Count has not reached zero. If the Retry Count has reached zero, an error will - * be generated. Note that this address (0xBASE_0630) is used as SCR4L only if - * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR4C readback - * register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR4L register - */ -/*@{*/ -#define TRNG_SCR4L_REG(base) ((base)->SCR4L) -#define TRNG_RD_SCR4L(base) (TRNG_SCR4L_REG(base)) -#define TRNG_WR_SCR4L(base, value) (TRNG_SCR4L_REG(base) = (value)) -#define TRNG_RMW_SCR4L(base, mask, value) (TRNG_WR_SCR4L(base, (TRNG_RD_SCR4L(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCR4L bitfields - */ - -/*! - * @name Register TRNG_SCR4L, field RUN4_MAX[11:0] (RW) - * - * Run Length 4 Maximum Limit. Defines the maximum allowable runs of length 4 - * (for both 0 and 1) detected during entropy generation. The number of runs of - * length 4 detected during entropy generation must be less than RUN4_MAX, else a - * retry or error will occur. This register is cleared to 004Bh (decimal 75) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR4L_RUN4_MAX field. */ -#define TRNG_RD_SCR4L_RUN4_MAX(base) ((TRNG_SCR4L_REG(base) & TRNG_SCR4L_RUN4_MAX_MASK) >> TRNG_SCR4L_RUN4_MAX_SHIFT) - -/*! @brief Set the RUN4_MAX field to a new value. */ -#define TRNG_WR_SCR4L_RUN4_MAX(base, value) (TRNG_RMW_SCR4L(base, TRNG_SCR4L_RUN4_MAX_MASK, TRNG_SCR4L_RUN4_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR4L, field RUN4_RNG[27:16] (RW) - * - * Run Length 4 Range. The number of runs of length 4 (for both 0 and 1) - * detected during entropy generation must be greater than RUN4_MAX - RUN4_RNG, else a - * retry or error will occur. This register is cleared to 0040h (decimal 64) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR4L_RUN4_RNG field. */ -#define TRNG_RD_SCR4L_RUN4_RNG(base) ((TRNG_SCR4L_REG(base) & TRNG_SCR4L_RUN4_RNG_MASK) >> TRNG_SCR4L_RUN4_RNG_SHIFT) - -/*! @brief Set the RUN4_RNG field to a new value. */ -#define TRNG_WR_SCR4L_RUN4_RNG(base, value) (TRNG_RMW_SCR4L(base, TRNG_SCR4L_RUN4_RNG_MASK, TRNG_SCR4L_RUN4_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR5L - RNG Statistical Check Run Length 5 Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR5L - RNG Statistical Check Run Length 5 Limit Register (RW) - * - * Reset value: 0x002E002FU - * - * The RNG Statistical Check Run Length 5 Limit Register defines the allowable - * maximum and minimum number of runs of length 5 detected during entropy - * generation. To pass the test, the number of runs of length 5 (for samples of both 0 - * and 1) must be less than the programmed maximum value, and the number of runs of - * length 5 must be greater than (maximum - range). If this test fails, the - * Retry Counter in SCMISC will be decremented, and a retry will occur if the Retry - * Count has not reached zero. If the Retry Count has reached zero, an error will - * be generated. Note that this address (0xBASE_0634) is used as SCR5L only if - * MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this address is used as SCR5C readback - * register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR5L register - */ -/*@{*/ -#define TRNG_SCR5L_REG(base) ((base)->SCR5L) -#define TRNG_RD_SCR5L(base) (TRNG_SCR5L_REG(base)) -#define TRNG_WR_SCR5L(base, value) (TRNG_SCR5L_REG(base) = (value)) -#define TRNG_RMW_SCR5L(base, mask, value) (TRNG_WR_SCR5L(base, (TRNG_RD_SCR5L(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCR5L bitfields - */ - -/*! - * @name Register TRNG_SCR5L, field RUN5_MAX[10:0] (RW) - * - * Run Length 5 Maximum Limit. Defines the maximum allowable runs of length 5 - * (for both 0 and 1) detected during entropy generation. The number of runs of - * length 5 detected during entropy generation must be less than RUN5_MAX, else a - * retry or error will occur. This register is cleared to 002Fh (decimal 47) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR5L_RUN5_MAX field. */ -#define TRNG_RD_SCR5L_RUN5_MAX(base) ((TRNG_SCR5L_REG(base) & TRNG_SCR5L_RUN5_MAX_MASK) >> TRNG_SCR5L_RUN5_MAX_SHIFT) - -/*! @brief Set the RUN5_MAX field to a new value. */ -#define TRNG_WR_SCR5L_RUN5_MAX(base, value) (TRNG_RMW_SCR5L(base, TRNG_SCR5L_RUN5_MAX_MASK, TRNG_SCR5L_RUN5_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR5L, field RUN5_RNG[26:16] (RW) - * - * Run Length 5 Range. The number of runs of length 5 (for both 0 and 1) - * detected during entropy generation must be greater than RUN5_MAX - RUN5_RNG, else a - * retry or error will occur. This register is cleared to 002Eh (decimal 46) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR5L_RUN5_RNG field. */ -#define TRNG_RD_SCR5L_RUN5_RNG(base) ((TRNG_SCR5L_REG(base) & TRNG_SCR5L_RUN5_RNG_MASK) >> TRNG_SCR5L_RUN5_RNG_SHIFT) - -/*! @brief Set the RUN5_RNG field to a new value. */ -#define TRNG_WR_SCR5L_RUN5_RNG(base, value) (TRNG_RMW_SCR5L(base, TRNG_SCR5L_RUN5_RNG_MASK, TRNG_SCR5L_RUN5_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCR6PL - RNG Statistical Check Run Length 6+ Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCR6PL - RNG Statistical Check Run Length 6+ Limit Register (RW) - * - * Reset value: 0x002E002FU - * - * The RNG Statistical Check Run Length 6+ Limit Register defines the allowable - * maximum and minimum number of runs of length 6 or more detected during entropy - * generation. To pass the test, the number of runs of length 6 or more (for - * samples of both 0 and 1) must be less than the programmed maximum value, and the - * number of runs of length 6 or more must be greater than (maximum - range). If - * this test fails, the Retry Counter in SCMISC will be decremented, and a retry - * will occur if the Retry Count has not reached zero. If the Retry Count has - * reached zero, an error will be generated. Note that this offset (0xBASE_0638) is - * used as SCR6PL only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this offset is - * used as SCR6PC readback register. - */ -/*! - * @name Constants and macros for entire TRNG_SCR6PL register - */ -/*@{*/ -#define TRNG_SCR6PL_REG(base) ((base)->SCR6PL) -#define TRNG_RD_SCR6PL(base) (TRNG_SCR6PL_REG(base)) -#define TRNG_WR_SCR6PL(base, value) (TRNG_SCR6PL_REG(base) = (value)) -#define TRNG_RMW_SCR6PL(base, mask, value) (TRNG_WR_SCR6PL(base, (TRNG_RD_SCR6PL(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCR6PL bitfields - */ - -/*! - * @name Register TRNG_SCR6PL, field RUN6P_MAX[10:0] (RW) - * - * Run Length 6+ Maximum Limit. Defines the maximum allowable runs of length 6 - * or more (for both 0 and 1) detected during entropy generation. The number of - * runs of length 6 or more detected during entropy generation must be less than - * RUN6P_MAX, else a retry or error will occur. This register is cleared to 002Fh - * (decimal 47) by writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR6PL_RUN6P_MAX field. */ -#define TRNG_RD_SCR6PL_RUN6P_MAX(base) \ - ((TRNG_SCR6PL_REG(base) & TRNG_SCR6PL_RUN6P_MAX_MASK) >> TRNG_SCR6PL_RUN6P_MAX_SHIFT) - -/*! @brief Set the RUN6P_MAX field to a new value. */ -#define TRNG_WR_SCR6PL_RUN6P_MAX(base, value) \ - (TRNG_RMW_SCR6PL(base, TRNG_SCR6PL_RUN6P_MAX_MASK, TRNG_SCR6PL_RUN6P_MAX(value))) -/*@}*/ - -/*! - * @name Register TRNG_SCR6PL, field RUN6P_RNG[26:16] (RW) - * - * Run Length 6+ Range. The number of runs of length 6 or more (for both 0 and - * 1) detected during entropy generation must be greater than RUN6P_MAX - - * RUN6P_RNG, else a retry or error will occur. This register is cleared to 002Eh - * (decimal 46) by writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCR6PL_RUN6P_RNG field. */ -#define TRNG_RD_SCR6PL_RUN6P_RNG(base) \ - ((TRNG_SCR6PL_REG(base) & TRNG_SCR6PL_RUN6P_RNG_MASK) >> TRNG_SCR6PL_RUN6P_RNG_SHIFT) - -/*! @brief Set the RUN6P_RNG field to a new value. */ -#define TRNG_WR_SCR6PL_RUN6P_RNG(base, value) \ - (TRNG_RMW_SCR6PL(base, TRNG_SCR6PL_RUN6P_RNG_MASK, TRNG_SCR6PL_RUN6P_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_PKRMAX - RNG Poker Maximum Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_PKRMAX - RNG Poker Maximum Limit Register (RW) - * - * Reset value: 0x00006920U - * - * The RNG Poker Maximum Limit Register defines Maximum Limit allowable during - * the TRNG Statistical Check Poker Test. Note that this offset (0xBASE_060C) is - * used as PKRMAX only if MCTL[PRGM] is 1. If MCTL[PRGM] is 0, this offset is used - * as the PKRSQ readback register. - */ -/*! - * @name Constants and macros for entire TRNG_PKRMAX register - */ -/*@{*/ -#define TRNG_PKRMAX_REG(base) ((base)->PKRMAX) -#define TRNG_RD_PKRMAX(base) (TRNG_PKRMAX_REG(base)) -#define TRNG_WR_PKRMAX(base, value) (TRNG_PKRMAX_REG(base) = (value)) -#define TRNG_RMW_PKRMAX(base, mask, value) (TRNG_WR_PKRMAX(base, (TRNG_RD_PKRMAX(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_PKRMAX bitfields - */ - -/*! - * @name Register TRNG_PKRMAX, field PKR_MAX[23:0] (RW) - * - * Poker Maximum Limit. During the TRNG Statistical Checks, a "Poker Test" is - * run which requires a maximum and minimum limit. The maximum allowable result is - * programmed in the PKRMAX[PKR_MAX] register. This field is writable only if - * MCTL[PRGM] bit is 1. This register is cleared to 006920h (decimal 26912) by - * writing the MCTL[RST_DEF] bit to 1. Note that the PKRMAX and PKRRNG registers - * combined are used to define the minimum allowable Poker result, which is PKR_MAX - - * PKR_RNG + 1. Note that if MCTL[PRGM] bit is 0, this register address is used - * to read the Poker Test Square Calculation result in register PKRSQ, as defined - * in the following section. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_PKRMAX_PKR_MAX field. */ -#define TRNG_RD_PKRMAX_PKR_MAX(base) ((TRNG_PKRMAX_REG(base) & TRNG_PKRMAX_PKR_MAX_MASK) >> TRNG_PKRMAX_PKR_MAX_SHIFT) - -/*! @brief Set the PKR_MAX field to a new value. */ -#define TRNG_WR_PKRMAX_PKR_MAX(base, value) \ - (TRNG_RMW_PKRMAX(base, TRNG_PKRMAX_PKR_MAX_MASK, TRNG_PKRMAX_PKR_MAX(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_PKRRNG - RNG Poker Range Register - ******************************************************************************/ - -/*! - * @brief TRNG_PKRRNG - RNG Poker Range Register (RW) - * - * Reset value: 0x000009A3U - * - * The RNG Poker Range Register defines the difference between the TRNG Poker - * Maximum Limit and the minimum limit. These limits are used during the TRNG - * Statistical Check Poker Test. - */ -/*! - * @name Constants and macros for entire TRNG_PKRRNG register - */ -/*@{*/ -#define TRNG_PKRRNG_REG(base) ((base)->PKRRNG) -#define TRNG_RD_PKRRNG(base) (TRNG_PKRRNG_REG(base)) -#define TRNG_WR_PKRRNG(base, value) (TRNG_PKRRNG_REG(base) = (value)) -#define TRNG_RMW_PKRRNG(base, mask, value) (TRNG_WR_PKRRNG(base, (TRNG_RD_PKRRNG(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_PKRRNG bitfields - */ - -/*! - * @name Register TRNG_PKRRNG, field PKR_RNG[15:0] (RW) - * - * Poker Range. During the TRNG Statistical Checks, a "Poker Test" is run which - * requires a maximum and minimum limit. The maximum is programmed in the - * RTPKRMAX[PKR_MAX] register, and the minimum is derived by subtracting the PKR_RNG - * value from the programmed maximum value. This field is writable only if - * MCTL[PRGM] bit is 1. This field will read zeroes if MCTL[PRGM] = 0. This field is - * cleared to 09A3h (decimal 2467) by writing the MCTL[RST_DEF] bit to 1. Note that - * the minimum allowable Poker result is PKR_MAX - PKR_RNG + 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_PKRRNG_PKR_RNG field. */ -#define TRNG_RD_PKRRNG_PKR_RNG(base) ((TRNG_PKRRNG_REG(base) & TRNG_PKRRNG_PKR_RNG_MASK) >> TRNG_PKRRNG_PKR_RNG_SHIFT) - -/*! @brief Set the PKR_RNG field to a new value. */ -#define TRNG_WR_PKRRNG_PKR_RNG(base, value) \ - (TRNG_RMW_PKRRNG(base, TRNG_PKRRNG_PKR_RNG_MASK, TRNG_PKRRNG_PKR_RNG(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_FRQMAX - RNG Frequency Count Maximum Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_FRQMAX - RNG Frequency Count Maximum Limit Register (RW) - * - * Reset value: 0x00006400U - * - * The RNG Frequency Count Maximum Limit Register defines the maximum allowable - * count taken by the Entropy sample counter during each Entropy sample. During - * any sample period, if the count is greater than this programmed maximum, a - * Frequency Count Fail is flagged in MCTL[FCT_FAIL] and an error is generated. Note - * that this address (061C) is used as FRQMAX only if MCTL[PRGM] is 1. If - * MCTL[PRGM] is 0, this address is used as FRQCNT readback register. - */ -/*! - * @name Constants and macros for entire TRNG_FRQMAX register - */ -/*@{*/ -#define TRNG_FRQMAX_REG(base) ((base)->FRQMAX) -#define TRNG_RD_FRQMAX(base) (TRNG_FRQMAX_REG(base)) -#define TRNG_WR_FRQMAX(base, value) (TRNG_FRQMAX_REG(base) = (value)) -#define TRNG_RMW_FRQMAX(base, mask, value) (TRNG_WR_FRQMAX(base, (TRNG_RD_FRQMAX(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_FRQMAX bitfields - */ - -/*! - * @name Register TRNG_FRQMAX, field FRQ_MAX[21:0] (RW) - * - * Frequency Counter Maximum Limit. Defines the maximum allowable count taken - * during each entropy sample. This field is writable only if MCTL[PRGM] bit is 1. - * This register is cleared to 000640h by writing the MCTL[RST_DEF] bit to 1. - * Note that if MCTL[PRGM] bit is 0, this register address is used to read the - * Frequency Count result in register FRQCNT, as defined in the following section. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_FRQMAX_FRQ_MAX field. */ -#define TRNG_RD_FRQMAX_FRQ_MAX(base) ((TRNG_FRQMAX_REG(base) & TRNG_FRQMAX_FRQ_MAX_MASK) >> TRNG_FRQMAX_FRQ_MAX_SHIFT) - -/*! @brief Set the FRQ_MAX field to a new value. */ -#define TRNG_WR_FRQMAX_FRQ_MAX(base, value) \ - (TRNG_RMW_FRQMAX(base, TRNG_FRQMAX_FRQ_MAX_MASK, TRNG_FRQMAX_FRQ_MAX(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_FRQMIN - RNG Frequency Count Minimum Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_FRQMIN - RNG Frequency Count Minimum Limit Register (RW) - * - * Reset value: 0x00000640U - * - * The RNG Frequency Count Minimum Limit Register defines the minimum allowable - * count taken by the Entropy sample counter during each Entropy sample. During - * any sample period, if the count is less than this programmed minimum, a - * Frequency Count Fail is flagged in MCTL[FCT_FAIL] and an error is generated. - */ -/*! - * @name Constants and macros for entire TRNG_FRQMIN register - */ -/*@{*/ -#define TRNG_FRQMIN_REG(base) ((base)->FRQMIN) -#define TRNG_RD_FRQMIN(base) (TRNG_FRQMIN_REG(base)) -#define TRNG_WR_FRQMIN(base, value) (TRNG_FRQMIN_REG(base) = (value)) -#define TRNG_RMW_FRQMIN(base, mask, value) (TRNG_WR_FRQMIN(base, (TRNG_RD_FRQMIN(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_FRQMIN bitfields - */ - -/*! - * @name Register TRNG_FRQMIN, field FRQ_MIN[21:0] (RW) - * - * Frequency Count Minimum Limit. Defines the minimum allowable count taken - * during each entropy sample. This field is writable only if MCTL[PRGM] bit is 1. - * This field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 0000h64 - * by writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_FRQMIN_FRQ_MIN field. */ -#define TRNG_RD_FRQMIN_FRQ_MIN(base) ((TRNG_FRQMIN_REG(base) & TRNG_FRQMIN_FRQ_MIN_MASK) >> TRNG_FRQMIN_FRQ_MIN_SHIFT) - -/*! @brief Set the FRQ_MIN field to a new value. */ -#define TRNG_WR_FRQMIN_FRQ_MIN(base, value) \ - (TRNG_RMW_FRQMIN(base, TRNG_FRQMIN_FRQ_MIN_MASK, TRNG_FRQMIN_FRQ_MIN(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_MCTL - RNG Miscellaneous Control Register - ******************************************************************************/ - -/*! - * @brief TRNG_MCTL - RNG Miscellaneous Control Register (RW) - * - * Reset value: 0x00012001U - * - * This register is intended to be used for programming, configuring and testing - * the RNG. It is the main register to read/write, in order to enable Entropy - * generation, to stop entropy generation and to block access to entropy registers. - * This is done via the special TRNG_ACC and PRGM bits below. The RNG - * Miscellaneous Control Register is a read/write register used to control the RNG's True - * Random Number Generator (TRNG) access, operation and test. Note that in many - * cases two RNG registers share the same address, and a particular register at the - * shared address is selected based upon the value in the PRGM field of the MCTL - * register. - */ -/*! - * @name Constants and macros for entire TRNG_MCTL register - */ -/*@{*/ -#define TRNG_MCTL_REG(base) ((base)->MCTL) -#define TRNG_RD_MCTL(base) (TRNG_MCTL_REG(base)) -#define TRNG_WR_MCTL(base, value) (TRNG_MCTL_REG(base) = (value)) -#define TRNG_RMW_MCTL(base, mask, value) (TRNG_WR_MCTL(base, (TRNG_RD_MCTL(base) & ~(mask)) | (value))) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field FOR_SCLK[7] (RW) - * - * Force System Clock. If set, the system clock is used to operate the TRNG, - * instead of the ring oscillator. This is for test use only, and indeterminate - * results may occur. This bit is writable only if PRGM bit is 1, or PRGM bit is - * being written to 1 simultaneously to writing this bit. This bit is cleared by - * writing the RST_DEF bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_FOR_SCLK field. */ -#define TRNG_RD_MCTL_FOR_SCLK(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_FOR_SCLK_MASK) >> TRNG_MCTL_FOR_SCLK_SHIFT) - -/*! @brief Set the FOR_SCLK field to a new value. */ -#define TRNG_WR_MCTL_FOR_SCLK(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_FOR_SCLK_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_FOR_SCLK(value))) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field OSC_DIV[3:2] (RW) - * - * Oscillator Divide. Determines the amount of dividing done to the ring - * oscillator before it is used by the TRNG.This field is writable only if PRGM bit is - * 1, or PRGM bit is being written to 1 simultaneously to writing this field. This - * field is cleared to 00 by writing the RST_DEF bit to 1. - * - * Values: - * - 0b00 - use ring oscillator with no divide - * - 0b01 - use ring oscillator divided-by-2 - * - 0b10 - use ring oscillator divided-by-4 - * - 0b11 - use ring oscillator divided-by-8 - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_OSC_DIV field. */ -#define TRNG_RD_MCTL_OSC_DIV(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_OSC_DIV_MASK) >> TRNG_MCTL_OSC_DIV_SHIFT) - -/*! @brief Set the OSC_DIV field to a new value. */ -#define TRNG_WR_MCTL_OSC_DIV(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_OSC_DIV_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_OSC_DIV(value))) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field SAMP_MODE[1:0] (RW) - * - * Sample Mode. Determines the method of sampling the ring oscillator while - * generating the Entropy value:This field is writable only if PRGM bit is 1, or PRGM - * bit is being written to 1 simultaneously with writing this field. This field - * is cleared to 01 by writing the RST_DEF bit to 1. - * - * Values: - * - 0b00 - use Von Neumann data into both Entropy shifter and Statistical - * Checker - * - 0b01 - use raw data into both Entropy shifter and Statistical Checker - * - 0b10 - use Von Neumann data into Entropy shifter. Use raw data into - * Statistical Checker - * - 0b11 - reserved. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_SAMP_MODE field. */ -#define TRNG_RD_MCTL_SAMP_MODE(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_SAMP_MODE_MASK) >> TRNG_MCTL_SAMP_MODE_SHIFT) - -/*! @brief Set the SAMP_MODE field to a new value. */ -#define TRNG_WR_MCTL_SAMP_MODE(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_SAMP_MODE_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_SAMP_MODE(value))) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field PRGM[16] (RW) - * - * Programming Mode Select. When this bit is 1, the TRNG is in Program Mode, - * otherwise it is in Run Mode. No Entropy value will be generated while the TRNG is - * in Program Mode. Note that different RNG registers are accessible at the same - * address depending on whether PRGM is set to 1 or 0. This is noted in the RNG - * register descriptions. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_PRGM field. */ -#define TRNG_RD_MCTL_PRGM(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_PRGM_MASK) >> TRNG_MCTL_PRGM_SHIFT) - -/*! @brief Set the PRGM field to a new value. */ -#define TRNG_WR_MCTL_PRGM(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_PRGM(value))) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field RST_DEF[6] (WO) - * - * Reset Defaults. Writing a 1 to this bit clears various TRNG registers, and - * bits within registers, to their default state. This bit is writable only if PRGM - * bit is 1, or PRGM bit is being written to 1 simultaneously to writing this - * bit. Reading this bit always produces a 0. - */ -/*@{*/ -/*! @brief Set the RST_DEF field to a new value. */ -#define TRNG_WR_MCTL_RST_DEF(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_RST_DEF_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_RST_DEF(value))) -/*@}*/ - -#if !(defined(FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC) && (FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC > 0)) -/*! - * @name Register TRNG_MCTL, field TRNG_ACC[5] (RW) - * - * TRNG Access Mode. If this bit is set to 1, the TRNG will generate an Entropy - * value that can be read via the ENT0-ENT15 registers. The Entropy value may be - * read once the ENT VAL bit is asserted. Also see ENTa register descriptions - * (For a = 0 to 15). - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_TRNG_ACC field. */ -#define TRNG_RD_MCTL_TRNG_ACC(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_TRNG_ACC_MASK) >> TRNG_MCTL_TRNG_ACC_SHIFT) - -/*! @brief Set the TRNG_ACC field to a new value. */ -#define TRNG_WR_MCTL_TRNG_ACC(base, value) \ - (TRNG_RMW_MCTL(base, (TRNG_MCTL_TRNG_ACC_MASK | TRNG_MCTL_ERR_MASK), TRNG_MCTL_TRNG_ACC(value))) -/*@}*/ -#endif - -/*! - * @name Register TRNG_MCTL, field TSTOP_OK[13] (RO) - * - * TRNG_OK_TO_STOP. Software should check that this bit is a 1 before - * transitioning RNG to low power mode (RNG clock stopped). RNG turns on the TRNG - * free-running ring oscillator whenever new entropy is being generated and turns off the - * ring oscillator when entropy generation is complete. If the RNG clock is - * stopped while the TRNG ring oscillator is running, the oscillator will continue - * running even though the RNG clock is stopped. TSTOP_OK is asserted when the TRNG - * ring oscillator is not running. and therefore it is ok to stop the RNG clock. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_TSTOP_OK field. */ -#define TRNG_RD_MCTL_TSTOP_OK(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_TSTOP_OK_MASK) >> TRNG_MCTL_TSTOP_OK_SHIFT) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field ENT_VAL[10] (RO) - * - * Read only: Entropy Valid. Will assert only if TRNG ACC bit is set, and then - * after an entropy value is generated. Will be cleared when ENT15 is read. (ENT0 - * through ENT14 should be read before reading ENT15). - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_ENT_VAL field. */ -#define TRNG_RD_MCTL_ENT_VAL(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_ENT_VAL_MASK) >> TRNG_MCTL_ENT_VAL_SHIFT) -/*@}*/ - -/*! - * @name Register TRNG_MCTL, field ERR[12] (W1C) - * - * Read: Error status. 1 = error detected. 0 = no error.Write: Write 1 to clear - * errors. Writing 0 has no effect. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_MCTL_ERR field. */ -#define TRNG_RD_MCTL_ERR(base) ((TRNG_MCTL_REG(base) & TRNG_MCTL_ERR_MASK) >> TRNG_MCTL_ERR_SHIFT) - -/*! @brief Set the ERR field to a new value. */ -#define TRNG_WR_MCTL_ERR(base, value) (TRNG_RMW_MCTL(base, TRNG_MCTL_ERR_MASK, TRNG_MCTL_ERR(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SDCTL - RNG Seed Control Register - ******************************************************************************/ - -/*! - * @brief TRNG_SDCTL - RNG Seed Control Register (RW) - * - * Reset value: 0x0C8009C4U - * - * The RNG Seed Control Register contains two fields. One field defines the - * length (in system clocks) of each Entropy sample (ENT_DLY), and the other field - * indicates the number of samples that will taken during each TRNG Entropy - * generation (SAMP_SIZE). - */ -/*! - * @name Constants and macros for entire TRNG_SDCTL register - */ -/*@{*/ -#define TRNG_SDCTL_REG(base) ((base)->SDCTL) -#define TRNG_RD_SDCTL(base) (TRNG_SDCTL_REG(base)) -#define TRNG_WR_SDCTL(base, value) (TRNG_SDCTL_REG(base) = (value)) -#define TRNG_RMW_SDCTL(base, mask, value) (TRNG_WR_SDCTL(base, (TRNG_RD_SDCTL(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SDCTL bitfields - */ - -/*! - * @name Register TRNG_SDCTL, field SAMP_SIZE[15:0] (RW) - * - * Sample Size. Defines the total number of Entropy samples that will be taken - * during Entropy generation. This field is writable only if MCTL[PRGM] bit is 1. - * This field will read zeroes if MCTL[PRGM] = 0. This field is cleared to 09C4h - * (decimal 2500) by writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SDCTL_SAMP_SIZE field. */ -#define TRNG_RD_SDCTL_SAMP_SIZE(base) ((TRNG_SDCTL_REG(base) & TRNG_SDCTL_SAMP_SIZE_MASK) >> TRNG_SDCTL_SAMP_SIZE_SHIFT) - -/*! @brief Set the SAMP_SIZE field to a new value. */ -#define TRNG_WR_SDCTL_SAMP_SIZE(base, value) \ - (TRNG_RMW_SDCTL(base, TRNG_SDCTL_SAMP_SIZE_MASK, TRNG_SDCTL_SAMP_SIZE(value))) -/*@}*/ - -/*! - * @name Register TRNG_SDCTL, field ENT_DLY[31:16] (RW) - * - * Entropy Delay. Defines the length (in system clocks) of each Entropy sample - * taken. This field is writable only if MCTL[PRGM] bit is 1. This field will read - * zeroes if MCTL[PRGM] = 0. This field is cleared to 0C80h (decimal 3200) by - * writing the MCTL[RST_DEF] bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SDCTL_ENT_DLY field. */ -#define TRNG_RD_SDCTL_ENT_DLY(base) ((TRNG_SDCTL_REG(base) & TRNG_SDCTL_ENT_DLY_MASK) >> TRNG_SDCTL_ENT_DLY_SHIFT) - -/*! @brief Set the ENT_DLY field to a new value. */ -#define TRNG_WR_SDCTL_ENT_DLY(base, value) (TRNG_RMW_SDCTL(base, TRNG_SDCTL_ENT_DLY_MASK, TRNG_SDCTL_ENT_DLY(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SBLIM - RNG Sparse Bit Limit Register - ******************************************************************************/ - -/*! - * @brief TRNG_SBLIM - RNG Sparse Bit Limit Register (RW) - * - * Reset value: 0x0000003FU - * - * The RNG Sparse Bit Limit Register is used when Von Neumann sampling is - * selected during Entropy Generation. It defines the maximum number of consecutive Von - * Neumann samples which may be discarded before an error is generated. Note - * that this address (0xBASE_0614) is used as SBLIM only if MCTL[PRGM] is 1. If - * MCTL[PRGM] is 0, this address is used as TOTSAM readback register. - */ -/*! - * @name Constants and macros for entire TRNG_SBLIM register - */ -/*@{*/ -#define TRNG_SBLIM_REG(base) ((base)->SBLIM) -#define TRNG_RD_SBLIM(base) (TRNG_SBLIM_REG(base)) -#define TRNG_WR_SBLIM(base, value) (TRNG_SBLIM_REG(base) = (value)) -#define TRNG_RMW_SBLIM(base, mask, value) (TRNG_WR_SBLIM(base, (TRNG_RD_SBLIM(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SBLIM bitfields - */ - -/*! - * @name Register TRNG_SBLIM, field SB_LIM[9:0] (RW) - * - * Sparse Bit Limit. During Von Neumann sampling (if enabled by MCTL[SAMP_MODE], - * samples are discarded if two consecutive raw samples are both 0 or both 1. If - * this discarding occurs for a long period of time, it indicates that there is - * insufficient Entropy. The Sparse Bit Limit defines the maximum number of - * consecutive samples that may be discarded before an error is generated. This field - * is writable only if MCTL[PRGM] bit is 1. This register is cleared to 03hF by - * writing the MCTL[RST_DEF] bit to 1. Note that if MCTL[PRGM] bit is 0, this - * register address is used to read the Total Samples count in register TOTSAM, as - * defined in the following section. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SBLIM_SB_LIM field. */ -#define TRNG_RD_SBLIM_SB_LIM(base) ((TRNG_SBLIM_REG(base) & TRNG_SBLIM_SB_LIM_MASK) >> TRNG_SBLIM_SB_LIM_SHIFT) - -/*! @brief Set the SB_LIM field to a new value. */ -#define TRNG_WR_SBLIM_SB_LIM(base, value) (TRNG_RMW_SBLIM(base, TRNG_SBLIM_SB_LIM_MASK, TRNG_SBLIM_SB_LIM(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_SCMISC - RNG Statistical Check Miscellaneous Register - ******************************************************************************/ - -/*! - * @brief TRNG_SCMISC - RNG Statistical Check Miscellaneous Register (RW) - * - * Reset value: 0x0001001FU - * - * The RNG Statistical Check Miscellaneous Register contains the Long Run - * Maximum Limit value and the Retry Count value. This register is accessible only when - * the MCTL[PRGM] bit is 1, otherwise this register will read zeroes, and cannot - * be written. - */ -/*! - * @name Constants and macros for entire TRNG_SCMISC register - */ -/*@{*/ -#define TRNG_SCMISC_REG(base) ((base)->SCMISC) -#define TRNG_RD_SCMISC(base) (TRNG_SCMISC_REG(base)) -#define TRNG_WR_SCMISC(base, value) (TRNG_SCMISC_REG(base) = (value)) -#define TRNG_RMW_SCMISC(base, mask, value) (TRNG_WR_SCMISC(base, (TRNG_RD_SCMISC(base) & ~(mask)) | (value))) -/*@}*/ - -/* - * Constants & macros for individual TRNG_SCMISC bitfields - */ - -/*! - * @name Register TRNG_SCMISC, field LRUN_MAX[7:0] (RW) - * - * LONG RUN MAX LIMIT. This value is the largest allowable number of consecutive - * samples of all 1, or all 0, that is allowed during the Entropy generation. - * This field is writable only if MCTL[PRGM] bit is 1. This field will read zeroes - * if MCTL[PRGM] = 0. This field is cleared to 22h by writing the MCTL[RST_DEF] - * bit to 1. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SCMISC_LRUN_MAX field. */ -#define TRNG_RD_SCMISC_LRUN_MAX(base) \ - ((TRNG_SCMISC_REG(base) & TRNG_SCMISC_LRUN_MAX_MASK) >> TRNG_SCMISC_LRUN_MAX_SHIFT) - -/*! @brief Set the LRUN_MAX field to a new value. */ -#define TRNG_WR_SCMISC_LRUN_MAX(base, value) \ - (TRNG_RMW_SCMISC(base, TRNG_SCMISC_LRUN_MAX_MASK, TRNG_SCMISC_LRUN_MAX(value))) -/*@}*/ - -/******************************************************************************* - * TRNG_ENT - RNG TRNG Entropy Read Register - ******************************************************************************/ - -/*! - * @brief TRNG_ENT - RNG TRNG Entropy Read Register (RO) - * - * Reset value: 0x00000000U - * - * The RNG TRNG can be programmed to generate an entropy value that is readable - * via the SkyBlue bus. To do this, set the MCTL[TRNG_ACC] bit to 1. Once the - * entropy value has been generated, the MCTL[ENT_VAL] bit will be set to 1. At this - * point, ENT0 through ENT15 may be read to retrieve the 512-bit entropy value. - * Note that once ENT15 is read, the entropy value will be cleared and a new - * value will begin generation, so it is important that ENT15 be read last. These - * registers are readable only when MCTL[PRGM] = 0 (Run Mode), MCTL[TRNG_ACC] = 1 - * (TRNG access mode) and MCTL[ENT_VAL] = 1, otherwise zeroes will be read. - */ -/*! - * @name Constants and macros for entire TRNG_ENT register - */ -/*@{*/ -#define TRNG_ENT_REG(base, index) ((base)->ENT[index]) -#define TRNG_RD_ENT(base, index) (TRNG_ENT_REG(base, index)) -/*@}*/ - -/******************************************************************************* - * TRNG_SEC_CFG - RNG Security Configuration Register - ******************************************************************************/ - -/*! - * @brief TRNG_SEC_CFG - RNG Security Configuration Register (RW) - * - * Reset value: 0x00000000U - * - * The RNG Security Configuration Register is a read/write register used to - * control the test mode, programmability and state modes of the RNG. Many bits are - * place holders for this version. More configurability will be added here. Clears - * on asynchronous reset. For SA-TRNG releases before 2014/July/01, offsets 0xA0 - * to 0xAC used to be 0xB0 to 0xBC respectively. So, update newer tests that use - * these registers, if hard coded. - */ -/*! - * @name Constants and macros for entire TRNG_SEC_CFG register - */ -/*@{*/ -#define TRNG_SEC_CFG_REG(base) ((base)->SEC_CFG) -#define TRNG_RD_SEC_CFG(base) (TRNG_SEC_CFG_REG(base)) -#define TRNG_WR_SEC_CFG(base, value) (TRNG_SEC_CFG_REG(base) = (value)) -#define TRNG_RMW_SEC_CFG(base, mask, value) (TRNG_WR_SEC_CFG(base, (TRNG_RD_SEC_CFG(base) & ~(mask)) | (value))) -/*@}*/ - -/*! - * @name Register TRNG_SEC_CFG, field NO_PRGM[1] (RW) - * - * If set the TRNG registers cannot be programmed. That is, regardless of the - * TRNG access mode in the SA-TRNG Miscellaneous Control Register. - * - * Values: - * - 0b0 - Programability of registers controlled only by the RNG Miscellaneous - * Control Register's access mode bit. - * - 0b1 - Overides RNG Miscellaneous Control Register access mode and prevents - * TRNG register programming. - */ -/*@{*/ -/*! @brief Read current value of the TRNG_SEC_CFG_NO_PRGM field. */ -#define TRNG_RD_SEC_CFG_NO_PRGM(base) \ - ((TRNG_SEC_CFG_REG(base) & TRNG_SEC_CFG_NO_PRGM_MASK) >> TRNG_SEC_CFG_NO_PRGM_SHIFT) - -/*! @brief Set the NO_PRGM field to a new value. */ -#define TRNG_WR_SEC_CFG_NO_PRGM(base, value) \ - (TRNG_RMW_SEC_CFG(base, TRNG_SEC_CFG_NO_PRGM_MASK, TRNG_SEC_CFG_NO_PRGM(value))) -/*@}*/ - -/*! @brief Array to map TRNG instance number to base pointer. */ -static TRNG_Type *const s_trngBases[] = TRNG_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Clock array name */ -static const clock_ip_name_t s_trngClock[] = TRNG_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Prototypes - *******************************************************************************/ -static status_t trng_ApplyUserConfig(TRNG_Type *base, const trng_config_t *userConfig); -static status_t trng_SetRetryCount(TRNG_Type *base, uint8_t retry_count); -static status_t trng_SetMonobitLimit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit1Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit2Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit3Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit4Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit5Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetRunBit6Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetPokerMaxLimit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum); -static status_t trng_SetFrequencyCountMaxLimit(TRNG_Type *base, uint32_t limit_minimum, uint32_t limit_maximum); -static status_t trng_SetStatisticalCheckLimit(TRNG_Type *base, - trng_statistical_check_t statistical_check, - const trng_statistical_check_limit_t *limit); -static uint32_t trng_ReadEntropy(TRNG_Type *base, uint32_t index); -static uint32_t trng_GetInstance(TRNG_Type *base); - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t trng_GetInstance(TRNG_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_trngBases); instance++) - { - if (s_trngBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_trngBases)); - - return instance; -} - -/*FUNCTION********************************************************************* - * - * Function Name : TRNG_InitUserConfigDefault - * Description : Initializes user configuration structure to default settings. - * - *END*************************************************************************/ -/*! - * brief Initializes the user configuration structure to default values. - * - * This function initializes the configuration structure to default values. The default - * values are as follows. - * code - * userConfig->lock = 0; - * userConfig->clockMode = kTRNG_ClockModeRingOscillator; - * userConfig->ringOscDiv = kTRNG_RingOscDiv0; Or to other kTRNG_RingOscDiv[2|8] depending on the platform. - * userConfig->sampleMode = kTRNG_SampleModeRaw; - * userConfig->entropyDelay = 3200; - * userConfig->sampleSize = 2500; - * userConfig->sparseBitLimit = TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT; - * userConfig->retryCount = 63; - * userConfig->longRunMaxLimit = 34; - * userConfig->monobitLimit.maximum = 1384; - * userConfig->monobitLimit.minimum = 1116; - * userConfig->runBit1Limit.maximum = 405; - * userConfig->runBit1Limit.minimum = 227; - * userConfig->runBit2Limit.maximum = 220; - * userConfig->runBit2Limit.minimum = 98; - * userConfig->runBit3Limit.maximum = 125; - * userConfig->runBit3Limit.minimum = 37; - * userConfig->runBit4Limit.maximum = 75; - * userConfig->runBit4Limit.minimum = 11; - * userConfig->runBit5Limit.maximum = 47; - * userConfig->runBit5Limit.minimum = 1; - * userConfig->runBit6PlusLimit.maximum = 47; - * userConfig->runBit6PlusLimit.minimum = 1; - * userConfig->pokerLimit.maximum = 26912; - * userConfig->pokerLimit.minimum = 24445; - * userConfig->frequencyCountLimit.maximum = 25600; - * userConfig->frequencyCountLimit.minimum = 1600; - * endcode - * - * param userConfig User configuration structure. - * return If successful, returns the kStatus_TRNG_Success. Otherwise, it returns an error. - */ -status_t TRNG_GetDefaultConfig(trng_config_t *userConfig) -{ - status_t result; - - if (userConfig != NULL) - { - /* Initializes the configuration structure to default values. */ - - /* Lock programmability of TRNG registers. */ - userConfig->lock = (bool)TRNG_USER_CONFIG_DEFAULT_LOCK; - /* Clock settings */ - userConfig->clockMode = kTRNG_ClockModeRingOscillator; - userConfig->ringOscDiv = TRNG_USER_CONFIG_DEFAULT_OSC_DIV; - userConfig->sampleMode = kTRNG_SampleModeRaw; - /* Seed control*/ - userConfig->entropyDelay = TRNG_USER_CONFIG_DEFAULT_ENTROPY_DELAY; - userConfig->sampleSize = TRNG_USER_CONFIG_DEFAULT_SAMPLE_SIZE; - userConfig->sparseBitLimit = TRNG_USER_CONFIG_DEFAULT_SPARSE_BIT_LIMIT; - - /* Statistical Check Parameters.*/ - userConfig->retryCount = TRNG_USER_CONFIG_DEFAULT_RETRY_COUNT; - userConfig->longRunMaxLimit = TRNG_USER_CONFIG_DEFAULT_RUN_MAX_LIMIT; - - userConfig->monobitLimit.maximum = TRNG_USER_CONFIG_DEFAULT_MONOBIT_MAXIMUM; - userConfig->monobitLimit.minimum = TRNG_USER_CONFIG_DEFAULT_MONOBIT_MINIMUM; - userConfig->runBit1Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MAXIMUM; - userConfig->runBit1Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT1_MINIMUM; - userConfig->runBit2Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MAXIMUM; - userConfig->runBit2Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT2_MINIMUM; - userConfig->runBit3Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MAXIMUM; - userConfig->runBit3Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT3_MINIMUM; - userConfig->runBit4Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MAXIMUM; - userConfig->runBit4Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT4_MINIMUM; - userConfig->runBit5Limit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MAXIMUM; - userConfig->runBit5Limit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT5_MINIMUM; - userConfig->runBit6PlusLimit.maximum = TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MAXIMUM; - userConfig->runBit6PlusLimit.minimum = TRNG_USER_CONFIG_DEFAULT_RUNBIT6PLUS_MINIMUM; - /* Limits for statistical check of "Poker Test". */ - userConfig->pokerLimit.maximum = TRNG_USER_CONFIG_DEFAULT_POKER_MAXIMUM; - userConfig->pokerLimit.minimum = TRNG_USER_CONFIG_DEFAULT_POKER_MINIMUM; - /* Limits for statistical check of entropy sample frequency count. */ - userConfig->frequencyCountLimit.maximum = TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MAXIMUM; - userConfig->frequencyCountLimit.minimum = TRNG_USER_CONFIG_DEFAULT_FREQUENCY_MINIMUM; - - result = kStatus_Success; - } - else - { - result = kStatus_InvalidArgument; - } - - return result; -} - -/*! - * @brief Sets the TRNG retry count. - * - * This function sets the retry counter which defines the number of times a - * statistical check may fails during the TRNG Entropy Generation before - * generating an error. - */ -static status_t trng_SetRetryCount(TRNG_Type *base, uint8_t retry_count) -{ - status_t status; - - if ((retry_count >= 1u) && (retry_count <= 15u)) - { - /* Set retry count.*/ - TRNG_WR_SCMISC_RTY_CT(base, retry_count); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Check Monobit Limit Register . - * - * This function set register TRNG_SCML - Statistical Check Monobit Limit Register - */ -static status_t trng_SetMonobitLimit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0xffffu) && (limit_maximum <= 0xffffu)) - - { - /* Set TRNG_SCML register */ - TRNG_WR_SCML_MONO_MAX(base, limit_maximum); - TRNG_WR_SCML_MONO_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 1 Limit Register . - * - * This function set register TRNG_SCR1L - Statistical Check Run Length 1 Limit Register - */ -static status_t trng_SetRunBit1Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0x7fffu) && (limit_maximum <= 0x7fffu)) - { - /* Set TRNG_SCR1L register */ - TRNG_WR_SCR1L_RUN1_MAX(base, limit_maximum); - TRNG_WR_SCR1L_RUN1_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 2 Limit Register . - * - * This function set register TRNG_SCR2L - Statistical Check Run Length 2 Limit Register - */ -static status_t trng_SetRunBit2Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0x3fffu) && (limit_maximum <= 0x3fffu)) - { - /* Set TRNG_SCR2L register */ - TRNG_WR_SCR2L_RUN2_MAX(base, limit_maximum); - TRNG_WR_SCR2L_RUN2_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 3 Limit Register . - * - * This function set register TRNG_SCR3L - Statistical Check Run Length 3 Limit Register - */ -static status_t trng_SetRunBit3Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0x1fffu) && (limit_maximum <= 0x1fffu)) - { - /* Set TRNG_SCR3L register */ - TRNG_WR_SCR3L_RUN3_MAX(base, limit_maximum); - TRNG_WR_SCR3L_RUN3_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 4 Limit Register . - * This function set register TRNG_SCR4L - Statistical Check Run Length 4 Limit Register - */ -static status_t trng_SetRunBit4Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0xfffu) && (limit_maximum <= 0xfffu)) - { - /* Set TRNG_SCR4L register */ - TRNG_WR_SCR4L_RUN4_MAX(base, limit_maximum); - TRNG_WR_SCR4L_RUN4_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 5 Limit Register . - * This function set register TRNG_SCR5L - Statistical Check Run Length 5 Limit Register - */ -static status_t trng_SetRunBit5Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0x7ffu) && (limit_maximum <= 0x7ffu)) - { - /* Set TRNG_SCR5L register */ - TRNG_WR_SCR5L_RUN5_MAX(base, limit_maximum); - TRNG_WR_SCR5L_RUN5_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Statistical Check Run Length 6 Limit Register . - * This function set register TRNG_SCR6L - Statistical Check Run Length 6 Limit Register - */ -static status_t trng_SetRunBit6Limit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0x7ffu) && (limit_maximum <= 0x7ffu)) - { - /* Set TRNG_SCR6L register */ - TRNG_WR_SCR6PL_RUN6P_MAX(base, limit_maximum); - TRNG_WR_SCR6PL_RUN6P_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Poker Maximum Limit Register. - * This function set register TRNG_PKRMAX - Poker Maximum Limit Register - */ -static status_t trng_SetPokerMaxLimit(TRNG_Type *base, uint32_t range, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((range <= 0xffffu) && (limit_maximum <= 0xffffffu)) - { - /* Set TRNG_PKRMAX register */ - TRNG_WR_PKRMAX_PKR_MAX(base, limit_maximum); - TRNG_WR_PKRRNG_PKR_RNG(base, range); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical Frequency Count Maximum Limit Register. - * This function set register TRNG_FRQMAX - Frequency Count Maximum Limit Register - */ -static status_t trng_SetFrequencyCountMaxLimit(TRNG_Type *base, uint32_t limit_minimum, uint32_t limit_maximum) -{ - status_t status; - - /* Check input parameters*/ - if ((limit_minimum <= 0x3fffffu) && (limit_maximum <= 0x3fffffu)) - { - /* Set FRQMAX register */ - TRNG_WR_FRQMAX_FRQ_MAX(base, limit_maximum); - TRNG_WR_FRQMIN_FRQ_MIN(base, limit_minimum); - status = kStatus_Success; - } - else - { - status = kStatus_InvalidArgument; - } - return status; -} - -/*! - * @brief Sets statistical check limits. - * - * This function is used to set minimum and maximum limits of statistical checks. - * - */ -static status_t trng_SetStatisticalCheckLimit(TRNG_Type *base, - trng_statistical_check_t statistical_check, - const trng_statistical_check_limit_t *limit) -{ - uint32_t range; - status_t status = kStatus_Success; - - if ((NULL != limit) && (limit->maximum > limit->minimum)) - { - range = limit->maximum - limit->minimum; /* Registers use range instead of minimum value.*/ - - if (statistical_check == kTRNG_StatisticalCheckMonobit) /* Allowable maximum and minimum number of ones/zero - detected during entropy generation. */ - { - status = trng_SetMonobitLimit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit1) /* Allowable maximum and minimum number of runs of - length 1 detected during entropy generation. */ - { - status = trng_SetRunBit1Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit2) /* Allowable maximum and minimum number of runs of - length 2 detected during entropy generation. */ - { - status = trng_SetRunBit2Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit3) /* Allowable maximum and minimum number of runs of - length 3 detected during entropy generation. */ - { - status = trng_SetRunBit3Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit4) /* Allowable maximum and minimum number of runs of - length 4 detected during entropy generation. */ - { - status = trng_SetRunBit4Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit5) /* Allowable maximum and minimum number of runs of - length 5 detected during entropy generation. */ - { - status = trng_SetRunBit5Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckRunBit6Plus) /* Allowable maximum and minimum number of - length 6 or more detected during entropy - generation */ - { - status = trng_SetRunBit6Limit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckPoker) /* Allowable maximum and minimum limit of "Poker - Test" detected during entropy generation . */ - { - status = trng_SetPokerMaxLimit(base, range, limit->maximum); - } - else if (statistical_check == kTRNG_StatisticalCheckFrequencyCount) /* Allowable maximum and minimum limit of - entropy sample frquency count during - entropy generation . */ - { - status = trng_SetFrequencyCountMaxLimit(base, limit->minimum, limit->maximum); - } - else - { - status = kStatus_InvalidArgument; - } - } - - return status; -} - -/*FUNCTION********************************************************************* - * - * Function Name : trng_ApplyUserConfig - * Description : Apply user configuration settings to TRNG module. - * - *END*************************************************************************/ -static status_t trng_ApplyUserConfig(TRNG_Type *base, const trng_config_t *userConfig) -{ - status_t status; - - /* Set retry count */ - status = trng_SetRetryCount(base, userConfig->retryCount); - - /* Set statistical check limit */ - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckMonobit, &userConfig->monobitLimit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit1, &userConfig->runBit1Limit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit2, &userConfig->runBit2Limit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit3, &userConfig->runBit3Limit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit4, &userConfig->runBit4Limit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit5, &userConfig->runBit5Limit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckRunBit6Plus, &userConfig->runBit6PlusLimit); - } - - if (kStatus_Success == status) - { - status = trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckPoker, &userConfig->pokerLimit); - } - - if (kStatus_Success == status) - { - status = - trng_SetStatisticalCheckLimit(base, kTRNG_StatisticalCheckFrequencyCount, &userConfig->frequencyCountLimit); - } - - if (kStatus_Success == status) - { - /* Set clock mode used to operate TRNG */ - TRNG_WR_MCTL_FOR_SCLK(base, userConfig->clockMode); - /* Set ring oscillator divider used by TRNG */ - TRNG_WR_MCTL_OSC_DIV(base, userConfig->ringOscDiv); - /* Set sample mode of the TRNG ring oscillator. */ - TRNG_WR_MCTL_SAMP_MODE(base, userConfig->sampleMode); - /* Set length of each Entropy sample taken */ - TRNG_WR_SDCTL_ENT_DLY(base, userConfig->entropyDelay); - /* Set number of entropy samples that will be taken during Entropy generation */ - TRNG_WR_SDCTL_SAMP_SIZE(base, userConfig->sampleSize); - /* Set Sparse Bit Limit */ - TRNG_WR_SBLIM_SB_LIM(base, userConfig->sparseBitLimit); - TRNG_WR_SCMISC_LRUN_MAX(base, userConfig->longRunMaxLimit); - } - - return status; -} - -/*! - * @brief Gets a entry data from the TRNG. - * - * This function gets an entropy data from TRNG. - * Entropy data is spread over TRNG_ENT_COUNT registers. - * Read register number is defined by index parameter. - */ -static uint32_t trng_ReadEntropy(TRNG_Type *base, uint32_t index) -{ - uint32_t data; - - index = index % TRNG_ENT_COUNT; /* This way we can use incremental index without limit control from application.*/ - - data = TRNG_RD_ENT(base, index); - - if (index == (TRNG_ENT_COUNT - 1u)) - { - /* Dummy read. Defect workaround. - * TRNG could not clear ENT_VAL flag automatically, application - * had to do a dummy reading operation for anyone TRNG register - * to clear it firstly, then to read the RTENT0 to RTENT15 again */ - index = TRNG_RD_ENT(base, 0); - } - - return data; -} - -/*! - * brief Initializes the TRNG. - * - * This function initializes the TRNG. - * When called, the TRNG entropy generation starts immediately. - * - * param base TRNG base address - * param userConfig Pointer to the initialization configuration structure. - * return If successful, returns the kStatus_TRNG_Success. Otherwise, it returns an error. - */ -status_t TRNG_Init(TRNG_Type *base, const trng_config_t *userConfig) -{ - status_t result; - - /* Check input parameters.*/ - if ((base != NULL) && (userConfig != NULL)) - { -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the clock gate. */ - CLOCK_EnableClock(s_trngClock[trng_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - - /* Reset the registers of TRNG module to reset state. */ - /* Must be in program mode.*/ - TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeProgram); - /* Reset Defaults.*/ - TRNG_WR_MCTL_RST_DEF(base, 1); - - /* Set configuration.*/ - if ((result = trng_ApplyUserConfig(base, userConfig)) == kStatus_Success) - { - /* Start entropy generation.*/ - /* Set to Run mode.*/ - TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeRun); -#if !(defined(FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC) && (FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC > 0)) - /* Enable TRNG Access Mode. To generate an Entropy - * value that can be read via the true0-true15 registers.*/ - TRNG_WR_MCTL_TRNG_ACC(base, 1); -#endif /* !FSL_FEATURE_TRNG_HAS_NO_TRNG_ACC */ - - (void)trng_ReadEntropy(base, (TRNG_ENT_COUNT - 1u)); - - if (true == userConfig->lock) /* Disable programmability of TRNG registers. */ - { - TRNG_WR_SEC_CFG_NO_PRGM(base, 1); - } - - result = kStatus_Success; - } - } - else - { - result = kStatus_InvalidArgument; - } - - return result; -} - -/*! - * brief Shuts down the TRNG. - * - * This function shuts down the TRNG. - * - * param base TRNG base address. - */ -void TRNG_Deinit(TRNG_Type *base) -{ - /* Check input parameters.*/ - if (NULL != base) - { - /* Move to program mode. Stop entropy generation.*/ - TRNG_WR_MCTL_PRGM(base, kTRNG_WorkModeProgram); - - /* Check before clock stop. - TRNG turns on the TRNG free-running ring oscillator whenever new entropy - is being generated and turns off the ring oscillator when entropy generation - is complete. If the TRNG clock is stopped while the TRNG ring oscillator - is running, the oscillator continues running though the RNG clock. - is stopped. */ - while (TRNG_RD_MCTL_TSTOP_OK(base) == 0u) - { - } - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable Clock*/ - CLOCK_DisableClock(s_trngClock[trng_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - } -} - -/*! - * brief Gets random data. - * - * This function gets random data from the TRNG. - * - * param base TRNG base address. - * param data Pointer address used to store random data. - * param dataSize Size of the buffer pointed by the data parameter. - * return random data - */ -status_t TRNG_GetRandomData(TRNG_Type *base, void *data, size_t dataSize) -{ - status_t result = kStatus_Success; - uint32_t random_32; - uint8_t *random_p; - uint32_t random_size; - uint8_t *data_p = (uint8_t *)data; - uint32_t i; - uint32_t tmpValidFlag; - uint32_t tmpErrorFlag; - - int index = 0; - - /* Check input parameters.*/ - if ((NULL != base) && (NULL != data) && (0U != dataSize)) - { - do - { - /* Wait for Valid or Error flag*/ - tmpValidFlag = TRNG_RD_MCTL_ENT_VAL(base); - tmpErrorFlag = TRNG_RD_MCTL_ERR(base); - while ((tmpValidFlag == 0u) && (tmpErrorFlag == 0u)) - { - tmpValidFlag = TRNG_RD_MCTL_ENT_VAL(base); - tmpErrorFlag = TRNG_RD_MCTL_ERR(base); - } - - /* Check HW error.*/ - if (0U != TRNG_RD_MCTL_ERR(base)) - { - result = kStatus_Fail; /* TRNG module error occurred */ - /* Clear error.*/ - TRNG_WR_MCTL_ERR(base, 1); - break; /* No sense stay here.*/ - } - - /* Read Entropy.*/ - random_32 = trng_ReadEntropy(base, (uint32_t)index++); - - random_p = (uint8_t *)&random_32; - - if (dataSize < sizeof(random_32)) - { - random_size = dataSize; - } - else - { - random_size = sizeof(random_32); - } - - for (i = 0U; i < random_size; i++) - { - *data_p++ = *random_p++; - } - - dataSize -= random_size; - } while (dataSize > 0u); - - /* Start a new entropy generation. - It is done by reading of the last entropy register.*/ - if (((unsigned)index % TRNG_ENT_COUNT) != (TRNG_ENT_COUNT - 1u)) - { - (void)trng_ReadEntropy(base, (TRNG_ENT_COUNT - 1u)); - } - } - else - { - result = kStatus_InvalidArgument; - } - - return result; -} - -#endif /* FSL_FEATURE_SOC_TRNG_COUNT */ diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tsc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tsc.c deleted file mode 100644 index 403f661fa6..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_tsc.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_tsc.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.tsc" -#endif - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get instance number for TSC module. - * - * @param base TSC peripheral base address - */ -static uint32_t TSC_GetInstance(TSC_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief Pointers to TSC bases for each instance. */ -static TSC_Type *const s_tscBases[] = TSC_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief Pointers to ADC clocks for each instance. */ -static const clock_ip_name_t s_tscClocks[] = TSC_CLOCKS; -#endif - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t TSC_GetInstance(TSC_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_tscBases); instance++) - { - if (s_tscBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_tscBases)); - - return instance; -} - -/*! - * brief Initialize the TSC module. - * - * param base TSC peripheral base address. - * param config Pointer to "tsc_config_t" structure. - */ -void TSC_Init(TSC_Type *base, const tsc_config_t *config) -{ - assert(NULL != config); - assert(config->measureDelayTime <= 0xFFFFFFU); - - uint32_t tmp32; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable the TSC clock. */ - CLOCK_EnableClock(s_tscClocks[TSC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - /* Configure TSC_BASIC_SETTING register. */ - tmp32 = TSC_BASIC_SETTING_MEASURE_DELAY_TIME(config->measureDelayTime) | - TSC_BASIC_SETTING__4_5_WIRE(config->detectionMode); - if (config->enableAutoMeasure) - { - tmp32 |= TSC_BASIC_SETTING_AUTO_MEASURE_MASK; - } - base->BASIC_SETTING = tmp32; - /* Configure TSC_PS_INPUT_BUFFER_ADDR register. */ - base->PRE_CHARGE_TIME = TSC_PRE_CHARGE_TIME_PRE_CHARGE_TIME(config->prechargeTime); -} - -/*! - * brief De-initializes the TSC module. - * - * param base TSC peripheral base address. - */ -void TSC_Deinit(TSC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable the TSC clcok. */ - CLOCK_DisableClock(s_tscClocks[TSC_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Gets an available pre-defined settings for the controller's configuration. - * - * This function initializes the converter configuration structure with available settings. - * The default values of measureDelayTime and prechargeTime is tested on LCD8000-43T screen and work normally. - * The default values are: - * code - * config->enableAutoMeausre = false; - * config->measureDelayTime = 0xFFFFU; - * config->prechargeTime = 0xFFFFU; - * config->detectionMode = kTSC_4WireDetectionMode; - * endCode - * param config Pointer to "tsc_config_t" structure. - */ -void TSC_GetDefaultConfig(tsc_config_t *config) -{ - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableAutoMeasure = false; - config->measureDelayTime = 0xFFFFU; - config->prechargeTime = 0xFFFFU; - config->detectionMode = kTSC_Detection4WireMode; -} - -/*! - * brief Get Y coordinate value or X coordinate value. The value is an ADC conversion value. - * - * param base TSC peripheral base address. - * param selection Select alternative measure value which is Y coordinate value or X coordinate value. - * See "tsc_corrdinate_value_selection_t". - * return If selection is "kTSC_XCoordinateValueSelection", the API returns x-coordinate vlaue. - * If selection is "kTSC_YCoordinateValueSelection", the API returns y-coordinate vlaue. - */ -uint32_t TSC_GetMeasureValue(TSC_Type *base, tsc_corrdinate_value_selection_t selection) -{ - uint32_t tmp32 = 0; - - if (selection == kTSC_XCoordinateValueSelection) - { - tmp32 = ((base->MEASEURE_VALUE) & TSC_MEASEURE_VALUE_X_VALUE_MASK) >> TSC_MEASEURE_VALUE_X_VALUE_SHIFT; - } - else if (selection == kTSC_YCoordinateValueSelection) - { - tmp32 = ((base->MEASEURE_VALUE) & TSC_MEASEURE_VALUE_Y_VALUE_MASK) >> TSC_MEASEURE_VALUE_Y_VALUE_SHIFT; - } - else - { - /* Intentional empty */ - } - - return tmp32; -} - -/*! - * brief Send hardware trigger signal to ADC in debug mode. The trigger signal must last at least 1 ips clock period. - * - * param base TSC peripheral base address. - * param hwts Hardware trigger select signal, select which channel to start conversion. See "tsc_trigger_signal_t". - * On ADC side, HWTS = 1 << x indicates the x logic channel is selected to start hardware ADC conversion. - * param enable Switcher of the trigger signal. "true" means generate trigger signal, "false" means don't generate - * trigger signal. - */ -void TSC_DebugTriggerSignalToADC(TSC_Type *base, tsc_trigger_signal_t hwts, bool enable) -{ - if (enable) - { - /* TSC_DEBUG_MODE_EXT_HWTS field should be writed before writing TSC_DEBUG_MODE_TRIGGER field. - If the two fields are writed at the same time, the trigger couldn't work as expect. */ - base->DEBUG_MODE &= ~TSC_DEBUG_MODE_EXT_HWTS_MASK; - base->DEBUG_MODE |= TSC_DEBUG_MODE_EXT_HWTS(hwts); - base->DEBUG_MODE |= TSC_DEBUG_MODE_TRIGGER_MASK; - } - else - { - base->DEBUG_MODE &= ~TSC_DEBUG_MODE_TRIGGER_MASK; - } -} - -/*! - * brief Enable/Disable detection in debug mode. - * - * param base TSC peripheral base address. - * param detectionMode Set detect mode. See "tsc_detection_mode_t" - * param enable Switcher of detect enable. "true" means enable detection, "false" means disable detection. - */ -void TSC_DebugEnableDetection(TSC_Type *base, tsc_detection_mode_t detectionMode, bool enable) -{ - if (detectionMode == kTSC_Detection4WireMode) - { - if (enable) - { - base->DEBUG_MODE2 |= TSC_DEBUG_MODE2_DETECT_ENABLE_FOUR_WIRE_MASK; - } - else - { - base->DEBUG_MODE2 &= ~TSC_DEBUG_MODE2_DETECT_ENABLE_FOUR_WIRE_MASK; - } - } - else if (detectionMode == kTSC_Detection5WireMode) - { - if (enable) - { - base->DEBUG_MODE2 |= TSC_DEBUG_MODE2_DETECT_ENABLE_FIVE_WIRE_MASK; - } - else - { - base->DEBUG_MODE2 &= ~TSC_DEBUG_MODE2_DETECT_ENABLE_FIVE_WIRE_MASK; - } - } - else - { - /* Intentional empty */ - } -} - -/*! - * brief Set TSC port mode in debug mode.(pull down, pull up and 200k-pull up) - * - * param base TSC peripheral base address. - * param port TSC controller ports. - * param mode TSC port mode.(pull down, pull up and 200k-pull up) - */ -void TSC_DebugSetPortMode(TSC_Type *base, tsc_port_source_t port, tsc_port_mode_t mode) -{ - uint32_t tmp32; - - tmp32 = base->DEBUG_MODE2; - switch (port) - { - case kTSC_WiperPortSource: - tmp32 &= ~(TSC_DEBUG_MODE2_WIPER_200K_PULL_UP_MASK | TSC_DEBUG_MODE2_WIPER_PULL_UP_MASK | - TSC_DEBUG_MODE2_WIPER_PULL_DOWN_MASK); - tmp32 |= ((uint32_t)mode << TSC_DEBUG_MODE2_WIPER_PULL_DOWN_SHIFT); - break; - case kTSC_YnlrPortSource: - tmp32 &= ~(TSC_DEBUG_MODE2_YNLR_200K_PULL_UP_MASK | TSC_DEBUG_MODE2_YNLR_PULL_UP_MASK | - TSC_DEBUG_MODE2_YNLR_PULL_DOWN_MASK); - tmp32 |= ((uint32_t)mode << TSC_DEBUG_MODE2_YNLR_PULL_DOWN_SHIFT); - break; - case kTSC_YpllPortSource: - tmp32 &= ~(TSC_DEBUG_MODE2_YPLL_200K_PULL_UP_MASK | TSC_DEBUG_MODE2_YPLL_PULL_UP_MASK | - TSC_DEBUG_MODE2_YPLL_PULL_DOWN_MASK); - tmp32 |= ((uint32_t)mode << TSC_DEBUG_MODE2_YPLL_PULL_DOWN_SHIFT); - break; - case kTSC_XnurPortSource: - tmp32 &= ~(TSC_DEBUG_MODE2_XNUR_200K_PULL_UP_MASK | TSC_DEBUG_MODE2_XNUR_PULL_UP_MASK | - TSC_DEBUG_MODE2_XNUR_PULL_DOWN_MASK); - tmp32 |= ((uint32_t)mode << TSC_DEBUG_MODE2_XNUR_PULL_DOWN_SHIFT); - break; - case kTSC_XpulPortSource: - tmp32 &= ~(TSC_DEBUG_MODE2_XPUL_200K_PULL_UP_MASK | TSC_DEBUG_MODE2_XPUL_PULL_UP_MASK | - TSC_DEBUG_MODE2_XPUL_PULL_DOWN_MASK); - tmp32 |= ((uint32_t)mode << TSC_DEBUG_MODE2_XPUL_PULL_DOWN_SHIFT); - break; - default: - assert(false); - break; - } - base->DEBUG_MODE2 = tmp32; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_usdhc.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_usdhc.c deleted file mode 100644 index 8dd37e6345..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_usdhc.c +++ /dev/null @@ -1,2126 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2020 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_usdhc.h" -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL -#include "fsl_cache.h" -#endif /* FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL */ - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.usdhc" -#endif - -/*! @brief Clock setting */ -/* Max SD clock divisor from base clock */ -#define USDHC_MAX_DVS ((USDHC_SYS_CTRL_DVS_MASK >> USDHC_SYS_CTRL_DVS_SHIFT) + 1U) -#define USDHC_MAX_CLKFS ((USDHC_SYS_CTRL_SDCLKFS_MASK >> USDHC_SYS_CTRL_SDCLKFS_SHIFT) + 1U) -#define USDHC_PREV_DVS(x) ((x) -= 1U) -#define USDHC_PREV_CLKFS(x, y) ((x) >>= (y)) -/*! @brief USDHC ADMA table address align size */ -#define USDHC_ADMA_TABLE_ADDRESS_ALIGN (4U) - -/* Typedef for interrupt handler. */ -typedef void (*usdhc_isr_t)(USDHC_Type *base, usdhc_handle_t *handle); -/*! @brief check flag avalibility */ -#define IS_USDHC_FLAG_SET(reg, flag) (((reg) & ((uint32_t)flag)) != 0UL) - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -/*! - * @brief Get the instance. - * - * @param base USDHC peripheral base address. - * @return Instance number. - */ -static uint32_t USDHC_GetInstance(USDHC_Type *base); - -/*! - * @brief Start transfer according to current transfer state - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @param flag data present flag - * @param enDMA DMA enable flag - */ -static status_t USDHC_SetDataTransferConfig(USDHC_Type *base, - usdhc_data_t *data, - uint32_t *dataPresentFlag, - bool enDMA); - -/*! - * @brief Receive command response - * - * @param base USDHC peripheral base address. - * @param command Command to be sent. - */ -static status_t USDHC_ReceiveCommandResponse(USDHC_Type *base, usdhc_command_t *command); - -/*! - * @brief Read DATAPORT when buffer enable bit is set. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @param transferredWords The number of data words have been transferred last time transaction. - * @return The number of total data words have been transferred after this time transaction. - */ -static uint32_t USDHC_ReadDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords); - -/*! - * @brief Read data by using DATAPORT polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @retval kStatus_Fail Read DATAPORT failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_ReadByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data); - -/*! - * @brief Write DATAPORT when buffer enable bit is set. - * - * @param base USDHC peripheral base address. - * @param data Data to be read. - * @param transferredWords The number of data words have been transferred last time. - * @return The number of total data words have been transferred after this time transaction. - */ -static uint32_t USDHC_WriteDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords); - -/*! - * @brief Write data by using DATAPORT polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @retval kStatus_Fail Write DATAPORT failed. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_WriteByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data); - -/*! - * @brief Transfer data by polling way. - * - * @param base USDHC peripheral base address. - * @param data Data to be transferred. - * @param use DMA flag. - * @retval kStatus_Fail Transfer data failed. - * @retval kStatus_InvalidArgument Argument is invalid. - * @retval kStatus_Success Operate successfully. - */ -static status_t USDHC_TransferDataBlocking(USDHC_Type *base, usdhc_data_t *data, bool enDMA); - -/*! - * @brief Handle card detect interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Card detect related interrupt flags. - */ -static void USDHC_TransferHandleCardDetect(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle command interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Command related interrupt flags. - */ -static void USDHC_TransferHandleCommand(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle data interrupt. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interruptFlags Data related interrupt flags. - */ -static void USDHC_TransferHandleData(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); - -/*! - * @brief Handle SDIO card interrupt signal. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - */ -static void USDHC_TransferHandleSdioInterrupt(USDHC_Type *base, usdhc_handle_t *handle); - -/*! - * @brief Handle SDIO block gap event. - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - */ -static void USDHC_TransferHandleBlockGap(USDHC_Type *base, usdhc_handle_t *handle); - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) -/*! - * @brief Handle retuning - * - * @param base USDHC peripheral base address. - * @param handle USDHC handle. - * @param interrupt flags - */ -static void USDHC_TransferHandleReTuning(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags); -#endif - -/*! - * @brief wait command done - * - * @param base USDHC peripheral base address. - * @param command configuration - * @param pollingCmdDone polling command done flag - */ -static status_t USDHC_WaitCommandDone(USDHC_Type *base, usdhc_command_t *command, bool pollingCmdDone); - -/******************************************************************************* - * Variables - ******************************************************************************/ -/*! @brief USDHC base pointer array */ -static USDHC_Type *const s_usdhcBase[] = USDHC_BASE_PTRS; - -/*! @brief USDHC internal handle pointer array */ -static usdhc_handle_t *s_usdhcHandle[ARRAY_SIZE(s_usdhcBase)] = {NULL}; - -/*! @brief USDHC IRQ name array */ -static const IRQn_Type s_usdhcIRQ[] = USDHC_IRQS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/*! @brief USDHC clock array name */ -static const clock_ip_name_t s_usdhcClock[] = USDHC_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -#if (defined(FSL_FEATURE_USDHC_HAS_RESET) && FSL_FEATURE_USDHC_HAS_RESET) -/*! @brief Pointers to USDHC resets for each instance. */ -static const reset_ip_name_t s_usdhcResets[] = USDHC_RSTS; -#endif - -/* USDHC ISR for transactional APIs. */ -#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) -static usdhc_isr_t s_usdhcIsr = (usdhc_isr_t)DefaultISR; -#else -static usdhc_isr_t s_usdhcIsr; -#endif -/*! @brief Dummy data buffer for mmc boot mode */ -AT_NONCACHEABLE_SECTION_ALIGN(uint32_t s_usdhcBootDummy, USDHC_ADMA2_ADDRESS_ALIGN); - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t USDHC_GetInstance(USDHC_Type *base) -{ - uint8_t instance = 0; - - while ((instance < ARRAY_SIZE(s_usdhcBase)) && (s_usdhcBase[instance] != base)) - { - instance++; - } - - assert(instance < ARRAY_SIZE(s_usdhcBase)); - - return instance; -} - -static status_t USDHC_SetDataTransferConfig(USDHC_Type *base, usdhc_data_t *data, uint32_t *dataPresentFlag, bool enDMA) -{ - uint32_t mixCtrl = base->MIX_CTRL; - - if (data != NULL) - { - /* if transfer boot continous, only need set the CREQ bit, leave others as it is */ - if (data->dataType == (uint32_t)kUSDHC_TransferDataBootcontinous) - { - /* clear stop at block gap request */ - base->PROT_CTRL &= ~USDHC_PROT_CTRL_SABGREQ_MASK; - /* continous transfer data */ - base->PROT_CTRL |= USDHC_PROT_CTRL_CREQ_MASK; - return kStatus_Success; - } - - /* check data inhibit flag */ - if (IS_USDHC_FLAG_SET(base->PRES_STATE, kUSDHC_DataInhibitFlag)) - { - return kStatus_USDHC_BusyTransferring; - } - /* check transfer block count */ - if ((data->blockCount > USDHC_MAX_BLOCK_COUNT) || ((data->txData == NULL) && (data->rxData == NULL))) - { - return kStatus_InvalidArgument; - } - - /* config mix parameter */ - mixCtrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK | USDHC_MIX_CTRL_DTDSEL_MASK | - USDHC_MIX_CTRL_AC12EN_MASK); - - if (data->rxData != NULL) - { - mixCtrl |= USDHC_MIX_CTRL_DTDSEL_MASK; - } - - if (data->blockCount > 1U) - { - mixCtrl |= USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK; - /* auto command 12 */ - if (data->enableAutoCommand12) - { - mixCtrl |= USDHC_MIX_CTRL_AC12EN_MASK; - } - } - - /* auto command 23, auto send set block count cmd before multiple read/write */ - if ((data->enableAutoCommand23)) - { - mixCtrl |= USDHC_MIX_CTRL_AC23EN_MASK; - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK; - /* config the block count to DS_ADDR */ - base->DS_ADDR = data->blockCount; - } - else - { - mixCtrl &= ~USDHC_MIX_CTRL_AC23EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_ACMD23_ARGU2_EN_MASK; - } - - /* if transfer boot data, leave the block count to USDHC_SetMmcBootConfig function */ - if (data->dataType != (uint32_t)kUSDHC_TransferDataBoot) - { - /* config data block size/block count */ - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(data->blockSize) | USDHC_BLK_ATT_BLKCNT(data->blockCount))); - } - else - { - mixCtrl |= USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK; - base->PROT_CTRL |= USDHC_PROT_CTRL_RD_DONE_NO_8CLK_MASK; - } - - /* data present flag */ - *dataPresentFlag |= (uint32_t)kUSDHC_DataPresentFlag; - } - else - { - /* clear data flags */ - mixCtrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK | USDHC_MIX_CTRL_DTDSEL_MASK | - USDHC_MIX_CTRL_AC12EN_MASK | USDHC_MIX_CTRL_AC23EN_MASK); - - if (IS_USDHC_FLAG_SET(base->PRES_STATE, kUSDHC_CommandInhibitFlag)) - { - return kStatus_USDHC_BusyTransferring; - } - } - - /* config the mix parameter */ - base->MIX_CTRL = mixCtrl; - - return kStatus_Success; -} - -void USDHC_SetDataConfig(USDHC_Type *base, - usdhc_transfer_direction_t dataDirection, - uint32_t blockCount, - uint32_t blockSize) -{ - assert(blockCount <= USDHC_MAX_BLOCK_COUNT); - - uint32_t mixCtrl = base->MIX_CTRL; - - /* block attribute configuration */ - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(blockSize) | USDHC_BLK_ATT_BLKCNT(blockCount))); - - /* config mix parameter */ - mixCtrl &= ~(USDHC_MIX_CTRL_MSBSEL_MASK | USDHC_MIX_CTRL_BCEN_MASK | USDHC_MIX_CTRL_DTDSEL_MASK); - - mixCtrl |= USDHC_MIX_CTRL_DTDSEL(dataDirection) | (blockCount > 1U ? USDHC_MIX_CTRL_MSBSEL_MASK : 0U); - - base->MIX_CTRL = mixCtrl; -} - -static status_t USDHC_ReceiveCommandResponse(USDHC_Type *base, usdhc_command_t *command) -{ - assert(command != NULL); - - uint32_t response0 = base->CMD_RSP0; - uint32_t response1 = base->CMD_RSP1; - uint32_t response2 = base->CMD_RSP2; - - if (command->responseType != kCARD_ResponseTypeNone) - { - command->response[0U] = response0; - if (command->responseType == kCARD_ResponseTypeR2) - { - /* R3-R2-R1-R0(lowest 8 bit is invalid bit) has the same format as R2 format in SD specification document - after removed internal CRC7 and end bit. */ - command->response[0U] <<= 8U; - command->response[1U] = (response1 << 8U) | ((response0 & 0xFF000000U) >> 24U); - command->response[2U] = (response2 << 8U) | ((response1 & 0xFF000000U) >> 24U); - command->response[3U] = (base->CMD_RSP3 << 8U) | ((response2 & 0xFF000000U) >> 24U); - } - } - - /* check response error flag */ - if ((command->responseErrorFlags != 0U) && - ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR1b) || - (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR5))) - { - if (((command->responseErrorFlags) & (command->response[0U])) != 0U) - { - return kStatus_USDHC_SendCommandFailed; - } - } - - return kStatus_Success; -} - -static uint32_t USDHC_ReadDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords) -{ - uint32_t i; - uint32_t totalWords; - uint32_t wordsCanBeRead; /* The words can be read at this time. */ - uint32_t readWatermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_RD_WML_MASK) >> USDHC_WTMK_LVL_RD_WML_SHIFT); - - /* If DMA is enable, do not need to polling data port */ - if ((base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK) == 0U) - { - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */ - if (readWatermark >= totalWords) - { - wordsCanBeRead = totalWords; - } - /* If watermark level is less than totalWords and left words to be sent is equal or bigger than readWatermark, - transfers watermark level words. */ - else if ((readWatermark < totalWords) && ((totalWords - transferredWords) >= readWatermark)) - { - wordsCanBeRead = readWatermark; - } - /* If watermark level is less than totalWords and left words to be sent is less than readWatermark, transfers - left - words. */ - else - { - wordsCanBeRead = (totalWords - transferredWords); - } - - i = 0U; - while (i < wordsCanBeRead) - { - data->rxData[transferredWords++] = USDHC_ReadData(base); - i++; - } - } - - return transferredWords; -} - -static status_t USDHC_ReadByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data) -{ - uint32_t totalWords; - uint32_t transferredWords = 0U, interruptStatus = 0U; - status_t error = kStatus_Success; - - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - while ((error == kStatus_Success) && (transferredWords < totalWords)) - { - while ( - !(IS_USDHC_FLAG_SET(interruptStatus, ((uint32_t)kUSDHC_BufferReadReadyFlag | - (uint32_t)kUSDHC_DataErrorFlag | (uint32_t)kUSDHC_TuningErrorFlag)))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - /* during std tuning process, software do not need to read data, but wait BRR is enough */ - if ((data->dataType == (uint32_t)kUSDHC_TransferDataTuning) && - (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_BufferReadReadyFlag))) - { - USDHC_ClearInterruptStatusFlags(base, - (uint32_t)kUSDHC_BufferReadReadyFlag | (uint32_t)kUSDHC_TuningPassFlag); - - return kStatus_Success; - } -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - else if (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_TuningErrorFlag)) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_TuningErrorFlag); - /* if tuning error occur ,return directly */ - error = kStatus_USDHC_TuningError; - } -#endif - else if (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_DataErrorFlag)) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - /* clear data error flag */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataErrorFlag); - } - else - { - /* Intentional empty */ - } - - if (error == kStatus_Success) - { - transferredWords = USDHC_ReadDataPort(base, data, transferredWords); - /* clear buffer read ready */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_BufferReadReadyFlag); - interruptStatus = 0U; - } - } - - /* Clear data complete flag after the last read operation. */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataCompleteFlag); - - return error; -} - -static uint32_t USDHC_WriteDataPort(USDHC_Type *base, usdhc_data_t *data, uint32_t transferredWords) -{ - uint32_t i; - uint32_t totalWords; - uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */ - uint32_t writeWatermark = ((base->WTMK_LVL & USDHC_WTMK_LVL_WR_WML_MASK) >> USDHC_WTMK_LVL_WR_WML_SHIFT); - - /* If DMA is enable, do not need to polling data port */ - if ((base->MIX_CTRL & USDHC_MIX_CTRL_DMAEN_MASK) == 0U) - { - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t)); - - /* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/ - if (writeWatermark >= totalWords) - { - wordsCanBeWrote = totalWords; - } - /* If watermark level is less than totalWords and left words to be sent is equal or bigger than watermark, - transfers watermark level words. */ - else if ((writeWatermark < totalWords) && ((totalWords - transferredWords) >= writeWatermark)) - { - wordsCanBeWrote = writeWatermark; - } - /* If watermark level is less than totalWords and left words to be sent is less than watermark, transfers left - words. */ - else - { - wordsCanBeWrote = (totalWords - transferredWords); - } - - i = 0U; - while (i < wordsCanBeWrote) - { - USDHC_WriteData(base, data->txData[transferredWords++]); - i++; - } - } - - return transferredWords; -} - -static status_t USDHC_WriteByDataPortBlocking(USDHC_Type *base, usdhc_data_t *data) -{ - uint32_t totalWords; - - uint32_t transferredWords = 0U, interruptStatus = 0U; - status_t error = kStatus_Success; - - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (data->blockSize % sizeof(uint32_t) != 0U) - { - data->blockSize += - sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */ - } - - totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t); - - while ((error == kStatus_Success) && (transferredWords < totalWords)) - { - while (!(IS_USDHC_FLAG_SET(interruptStatus, (uint32_t)kUSDHC_BufferWriteReadyFlag | - (uint32_t)kUSDHC_DataErrorFlag | - (uint32_t)kUSDHC_TuningErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - if (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_TuningErrorFlag)) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_TuningErrorFlag); - /* if tuning error occur ,return directly */ - return kStatus_USDHC_TuningError; - } - else -#endif - if (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_DataErrorFlag)) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - /* clear data error flag */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_DataErrorFlag); - } - else - { - /* Intentional empty */ - } - - if (error == kStatus_Success) - { - transferredWords = USDHC_WriteDataPort(base, data, transferredWords); - /* clear buffer write ready */ - USDHC_ClearInterruptStatusFlags(base, kUSDHC_BufferWriteReadyFlag); - interruptStatus = 0U; - } - } - - /* Wait write data complete or data transfer error after the last writing operation. */ - while (!(IS_USDHC_FLAG_SET(interruptStatus, (uint32_t)kUSDHC_DataCompleteFlag | (uint32_t)kUSDHC_DataErrorFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & (uint32_t)kUSDHC_DataErrorFlag) != 0UL) - { - if (!(data->enableIgnoreError)) - { - error = kStatus_Fail; - } - } - USDHC_ClearInterruptStatusFlags(base, ((uint32_t)kUSDHC_DataCompleteFlag | (uint32_t)kUSDHC_DataErrorFlag)); - - return error; -} - -/*! - * brief send command function - * - * param base USDHC peripheral base address. - * param command configuration - */ -void USDHC_SendCommand(USDHC_Type *base, usdhc_command_t *command) -{ - assert(NULL != command); - - uint32_t xferType = base->CMD_XFR_TYP, flags = command->flags; - - if (((base->PRES_STATE & (uint32_t)kUSDHC_CommandInhibitFlag) == 0U) && (command->type != kCARD_CommandTypeEmpty)) - { - if ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR5) || - (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR7)) - { - flags |= ((uint32_t)kUSDHC_ResponseLength48Flag | (uint32_t)kUSDHC_EnableCrcCheckFlag | - (uint32_t)kUSDHC_EnableIndexCheckFlag); - } - else if ((command->responseType == kCARD_ResponseTypeR1b) || (command->responseType == kCARD_ResponseTypeR5b)) - { - flags |= ((uint32_t)kUSDHC_ResponseLength48BusyFlag | (uint32_t)kUSDHC_EnableCrcCheckFlag | - (uint32_t)kUSDHC_EnableIndexCheckFlag); - } - else if (command->responseType == kCARD_ResponseTypeR2) - { - flags |= ((uint32_t)kUSDHC_ResponseLength136Flag | (uint32_t)kUSDHC_EnableCrcCheckFlag); - } - else if ((command->responseType == kCARD_ResponseTypeR3) || (command->responseType == kCARD_ResponseTypeR4)) - { - flags |= ((uint32_t)kUSDHC_ResponseLength48Flag); - } - else - { - /* Intentional empty */ - } - - if (command->type == kCARD_CommandTypeAbort) - { - flags |= (uint32_t)kUSDHC_CommandTypeAbortFlag; - } - - /* config cmd index */ - xferType &= ~(USDHC_CMD_XFR_TYP_CMDINX_MASK | USDHC_CMD_XFR_TYP_CMDTYP_MASK | USDHC_CMD_XFR_TYP_CICEN_MASK | - USDHC_CMD_XFR_TYP_CCCEN_MASK | USDHC_CMD_XFR_TYP_RSPTYP_MASK | USDHC_CMD_XFR_TYP_DPSEL_MASK); - - xferType |= - (((command->index << USDHC_CMD_XFR_TYP_CMDINX_SHIFT) & USDHC_CMD_XFR_TYP_CMDINX_MASK) | - ((flags) & (USDHC_CMD_XFR_TYP_CMDTYP_MASK | USDHC_CMD_XFR_TYP_CICEN_MASK | USDHC_CMD_XFR_TYP_CCCEN_MASK | - USDHC_CMD_XFR_TYP_RSPTYP_MASK | USDHC_CMD_XFR_TYP_DPSEL_MASK))); - - /* config the command xfertype and argument */ - base->CMD_ARG = command->argument; - base->CMD_XFR_TYP = xferType; - } - - if (command->type == kCARD_CommandTypeEmpty) - { - /* disable CMD done interrupt for empty command */ - base->INT_SIGNAL_EN &= ~USDHC_INT_SIGNAL_EN_CCIEN_MASK; - } -} - -static status_t USDHC_WaitCommandDone(USDHC_Type *base, usdhc_command_t *command, bool pollingCmdDone) -{ - assert(NULL != command); - - status_t error = kStatus_Success; - uint32_t interruptStatus = 0U; - /* check if need polling command done or not */ - if (pollingCmdDone) - { - /* Wait command complete or USDHC encounters error. */ - while (!(IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_CommandFlag))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - - if ((interruptStatus & (uint32_t)kUSDHC_CommandErrorFlag) != 0UL) - { - error = kStatus_Fail; - } - - /* Receive response when command completes successfully. */ - if (error == kStatus_Success) - { - error = USDHC_ReceiveCommandResponse(base, command); - } - - USDHC_ClearInterruptStatusFlags(base, kUSDHC_CommandFlag); - } - - return error; -} - -static status_t USDHC_TransferDataBlocking(USDHC_Type *base, usdhc_data_t *data, bool enDMA) -{ - status_t error = kStatus_Success; - uint32_t interruptStatus = 0U; - - if (enDMA) - { - /* Wait data complete or USDHC encounters error. */ - while (!(IS_USDHC_FLAG_SET(interruptStatus, ((uint32_t)kUSDHC_DataDMAFlag | (uint32_t)kUSDHC_TuningErrorFlag)))) - { - interruptStatus = USDHC_GetInterruptStatusFlags(base); - } - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - if (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_TuningErrorFlag)) - { - error = kStatus_USDHC_TuningError; - } - else -#endif - if (IS_USDHC_FLAG_SET(interruptStatus, ((uint32_t)kUSDHC_DataErrorFlag | (uint32_t)kUSDHC_DmaErrorFlag))) - { - if ((!(data->enableIgnoreError)) || (IS_USDHC_FLAG_SET(interruptStatus, kUSDHC_DataTimeoutFlag))) - { - error = kStatus_USDHC_TransferDataFailed; - } - } - else - { - /* Intentional empty */ - } - /* load dummy data */ - if ((data->dataType == (uint32_t)kUSDHC_TransferDataBootcontinous) && (error == kStatus_Success)) - { - *(data->rxData) = s_usdhcBootDummy; - } - - USDHC_ClearInterruptStatusFlags( - base, ((uint32_t)kUSDHC_DataDMAFlag | (uint32_t)kUSDHC_TuningPassFlag | (uint32_t)kUSDHC_TuningErrorFlag)); - } - else - { - if (data->rxData != NULL) - { - error = USDHC_ReadByDataPortBlocking(base, data); - if (error != kStatus_Success) - { - return error; - } - } - else - { - error = USDHC_WriteByDataPortBlocking(base, data); - if (error != kStatus_Success) - { - return error; - } - } - } - - return error; -} - -/*! - * brief USDHC module initialization function. - * - * Configures the USDHC according to the user configuration. - * - * Example: - code - usdhc_config_t config; - config.cardDetectDat3 = false; - config.endianMode = kUSDHC_EndianModeLittle; - config.dmaMode = kUSDHC_DmaModeAdma2; - config.readWatermarkLevel = 128U; - config.writeWatermarkLevel = 128U; - USDHC_Init(USDHC, &config); - endcode - * - * param base USDHC peripheral base address. - * param config USDHC configuration information. - * retval kStatus_Success Operate successfully. - */ -void USDHC_Init(USDHC_Type *base, const usdhc_config_t *config) -{ - assert(config != NULL); - assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U)); - assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U)); -#if !(defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) - assert(config->writeBurstLen <= 16U); -#endif - uint32_t proctl, sysctl, wml; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable USDHC clock. */ - CLOCK_EnableClock(s_usdhcClock[USDHC_GetInstance(base)]); -#endif - -#if (defined(FSL_FEATURE_USDHC_HAS_RESET) && FSL_FEATURE_USDHC_HAS_RESET) - /* Reset the USDHC module */ - RESET_PeripheralReset(s_usdhcResets[USDHC_GetInstance(base)]); -#endif - - /* Reset ALL USDHC. */ - base->SYS_CTRL |= USDHC_SYS_CTRL_RSTA_MASK | USDHC_SYS_CTRL_RSTC_MASK | USDHC_SYS_CTRL_RSTD_MASK; - - proctl = base->PROT_CTRL; - wml = base->WTMK_LVL; - sysctl = base->SYS_CTRL; - - proctl &= ~(USDHC_PROT_CTRL_EMODE_MASK | USDHC_PROT_CTRL_DMASEL_MASK); - /* Endian mode*/ - proctl |= USDHC_PROT_CTRL_EMODE(config->endianMode); - -#if (defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) - /* Watermark level */ - wml &= ~(USDHC_WTMK_LVL_RD_WML_MASK | USDHC_WTMK_LVL_WR_WML_MASK); - wml |= (USDHC_WTMK_LVL_RD_WML(config->readWatermarkLevel) | USDHC_WTMK_LVL_WR_WML(config->writeWatermarkLevel)); -#else - /* Watermark level */ - wml &= ~(USDHC_WTMK_LVL_RD_WML_MASK | USDHC_WTMK_LVL_WR_WML_MASK | USDHC_WTMK_LVL_RD_BRST_LEN_MASK | - USDHC_WTMK_LVL_WR_BRST_LEN_MASK); - wml |= (USDHC_WTMK_LVL_RD_WML(config->readWatermarkLevel) | USDHC_WTMK_LVL_WR_WML(config->writeWatermarkLevel) | - USDHC_WTMK_LVL_RD_BRST_LEN(config->readBurstLen) | USDHC_WTMK_LVL_WR_BRST_LEN(config->writeBurstLen)); -#endif - - /* config the data timeout value */ - sysctl &= ~USDHC_SYS_CTRL_DTOCV_MASK; - sysctl |= USDHC_SYS_CTRL_DTOCV(config->dataTimeout); - - base->SYS_CTRL = sysctl; - base->WTMK_LVL = wml; - base->PROT_CTRL = proctl; - -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - /* disable external DMA */ - base->VEND_SPEC &= ~USDHC_VEND_SPEC_EXT_DMA_EN_MASK; -#endif - /* disable internal DMA and DDR mode */ - base->MIX_CTRL &= ~(USDHC_MIX_CTRL_DMAEN_MASK | USDHC_MIX_CTRL_DDR_EN_MASK); - /* disable interrupt, enable all the interrupt status, clear status. */ - base->INT_STATUS_EN = kUSDHC_AllInterruptFlags; - base->INT_SIGNAL_EN = 0UL; - base->INT_STATUS = kUSDHC_AllInterruptFlags; -} - -/*! - * brief Deinitializes the USDHC. - * - * param base USDHC peripheral base address. - */ -void USDHC_Deinit(USDHC_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable clock. */ - CLOCK_DisableClock(s_usdhcClock[USDHC_GetInstance(base)]); -#endif -} - -/*! - * brief Resets the USDHC. - * - * param base USDHC peripheral base address. - * param mask The reset type mask(_usdhc_reset). - * param timeout Timeout for reset. - * retval true Reset successfully. - * retval false Reset failed. - */ -bool USDHC_Reset(USDHC_Type *base, uint32_t mask, uint32_t timeout) -{ - base->SYS_CTRL |= (mask & (USDHC_SYS_CTRL_RSTA_MASK | USDHC_SYS_CTRL_RSTC_MASK | USDHC_SYS_CTRL_RSTD_MASK -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - | USDHC_SYS_CTRL_RSTT_MASK -#endif - )); - /* Delay some time to wait reset success. */ - while (IS_USDHC_FLAG_SET(base->SYS_CTRL, mask)) - { - if (timeout == 0UL) - { - break; - } - timeout--; - } - - return ((0UL == timeout) ? false : true); -} - -/*! - * brief Gets the capability information. - * - * param base USDHC peripheral base address. - * param capability Structure to save capability information. - */ -void USDHC_GetCapability(USDHC_Type *base, usdhc_capability_t *capability) -{ - assert(capability != NULL); - - uint32_t htCapability; - uint32_t maxBlockLength; - - htCapability = base->HOST_CTRL_CAP; - - /* Get the capability of USDHC. */ - maxBlockLength = ((htCapability & USDHC_HOST_CTRL_CAP_MBL_MASK) >> USDHC_HOST_CTRL_CAP_MBL_SHIFT); - capability->maxBlockLength = (512UL << maxBlockLength); - /* Other attributes not in HTCAPBLT register. */ - capability->maxBlockCount = USDHC_MAX_BLOCK_COUNT; - capability->flags = - (htCapability & (USDHC_HOST_CTRL_CAP_ADMAS_MASK | USDHC_HOST_CTRL_CAP_HSS_MASK | USDHC_HOST_CTRL_CAP_DMAS_MASK | - USDHC_HOST_CTRL_CAP_SRS_MASK | USDHC_HOST_CTRL_CAP_VS33_MASK)); - capability->flags |= htCapability & USDHC_HOST_CTRL_CAP_VS30_MASK; - capability->flags |= htCapability & USDHC_HOST_CTRL_CAP_VS18_MASK; - capability->flags |= htCapability & USDHC_HOST_CTRL_CAP_DDR50_SUPPORT_MASK; -#if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && FSL_FEATURE_USDHC_HAS_SDR104_MODE - capability->flags |= USDHC_HOST_CTRL_CAP_SDR104_SUPPORT_MASK; -#endif - -#if defined(FSL_FEATURE_USDHC_HAS_SDR104_MODE) && FSL_FEATURE_USDHC_HAS_SDR50_MODE - capability->flags |= USDHC_HOST_CTRL_CAP_SDR50_SUPPORT_MASK; -#endif - /* USDHC support 4/8 bit data bus width. */ - capability->flags |= (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 0UL) | (USDHC_HOST_CTRL_CAP_MBL_SHIFT << 1UL); -} - -/*! - * brief Sets the SD bus clock frequency. - * - * param base USDHC peripheral base address. - * param srcClock_Hz USDHC source clock frequency united in Hz. - * param busClock_Hz SD bus clock frequency united in Hz. - * - * return The nearest frequency of busClock_Hz configured to SD bus. - */ -uint32_t USDHC_SetSdClock(USDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz) -{ - assert(srcClock_Hz != 0U); - assert(busClock_Hz != 0U); - - uint32_t totalDiv = 0UL; - uint32_t divisor = 0UL; - uint32_t prescaler = 0UL; - uint32_t sysctl = 0UL; - uint32_t nearestFrequency = 0UL; - - if (busClock_Hz > srcClock_Hz) - { - busClock_Hz = srcClock_Hz; - } - - /* calucate total divisor first */ - if ((totalDiv = srcClock_Hz / busClock_Hz) > (USDHC_MAX_CLKFS * USDHC_MAX_DVS)) - { - return 0UL; - } - - if (totalDiv != 0UL) - { - /* calucate the divisor (srcClock_Hz / divisor) <= busClock_Hz */ - if ((srcClock_Hz / totalDiv) > busClock_Hz) - { - totalDiv++; - } - - /* divide the total divisor to div and prescaler */ - if (totalDiv > USDHC_MAX_DVS) - { - prescaler = totalDiv / USDHC_MAX_DVS; - /* prescaler must be a value which equal 2^n and smaller than SDHC_MAX_CLKFS */ - while (((USDHC_MAX_CLKFS % prescaler) != 0UL) || (prescaler == 1UL)) - { - prescaler++; - } - /* calucate the divisor */ - divisor = totalDiv / prescaler; - /* fine tuning the divisor until divisor * prescaler >= totalDiv */ - while ((divisor * prescaler) < totalDiv) - { - divisor++; - if (divisor > USDHC_MAX_DVS) - { - if ((prescaler <<= 1UL) > USDHC_MAX_CLKFS) - { - return 0UL; - } - divisor = totalDiv / prescaler; - } - } - } - else - { - /* in this situation , divsior and SDCLKFS can generate same clock - use SDCLKFS*/ - if (((totalDiv % 2UL) != 0UL) && (totalDiv != 1UL)) - { - divisor = totalDiv; - prescaler = 1UL; - } - else - { - divisor = 1UL; - prescaler = totalDiv; - } - } - nearestFrequency = srcClock_Hz / (divisor == 0UL ? 1UL : divisor) / prescaler; - } - /* in this condition , srcClock_Hz = busClock_Hz, */ - else - { - /* in DDR mode , set SDCLKFS to 0, divisor = 0, actually the - totoal divider = 2U */ - divisor = 0UL; - prescaler = 0UL; - nearestFrequency = srcClock_Hz; - } - - /* calucate the value write to register */ - if (divisor != 0UL) - { - USDHC_PREV_DVS(divisor); - } - /* calucate the value write to register */ - if (prescaler != 0UL) - { - USDHC_PREV_CLKFS(prescaler, 1UL); - } - - /* Set the SD clock frequency divisor, SD clock frequency select, data timeout counter value. */ - sysctl = base->SYS_CTRL; - sysctl &= ~(USDHC_SYS_CTRL_DVS_MASK | USDHC_SYS_CTRL_SDCLKFS_MASK); - sysctl |= (USDHC_SYS_CTRL_DVS(divisor) | USDHC_SYS_CTRL_SDCLKFS(prescaler)); - base->SYS_CTRL = sysctl; - - /* Wait until the SD clock is stable. */ - while (!IS_USDHC_FLAG_SET(base->PRES_STATE, USDHC_PRES_STATE_SDSTB_MASK)) - { - } - - return nearestFrequency; -} - -/*! - * brief Sends 80 clocks to the card to set it to the active state. - * - * This function must be called each time the card is inserted to ensure that the card can receive the command - * correctly. - * - * param base USDHC peripheral base address. - * param timeout Timeout to initialize card. - * retval true Set card active successfully. - * retval false Set card active failed. - */ -bool USDHC_SetCardActive(USDHC_Type *base, uint32_t timeout) -{ - base->SYS_CTRL |= USDHC_SYS_CTRL_INITA_MASK; - /* Delay some time to wait card become active state. */ - while (IS_USDHC_FLAG_SET(base->SYS_CTRL, USDHC_SYS_CTRL_INITA_MASK)) - { - if (0UL == timeout) - { - break; - } - timeout--; - } - - return ((0UL == timeout) ? false : true); -} - -/*! - * brief the enable/disable DDR mode - * - * param base USDHC peripheral base address. - * param enable/disable flag - * param nibble position - */ -void USDHC_EnableDDRMode(USDHC_Type *base, bool enable, uint32_t nibblePos) -{ - uint32_t prescaler = (base->SYS_CTRL & USDHC_SYS_CTRL_SDCLKFS_MASK) >> USDHC_SYS_CTRL_SDCLKFS_SHIFT; - - if (enable) - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_NIBBLE_POS_MASK; - base->MIX_CTRL |= (USDHC_MIX_CTRL_DDR_EN_MASK | USDHC_MIX_CTRL_NIBBLE_POS(nibblePos)); - prescaler >>= 1UL; - } - else - { - base->MIX_CTRL &= ~USDHC_MIX_CTRL_DDR_EN_MASK; - - if (prescaler == 0UL) - { - prescaler += 1UL; - } - else - { - prescaler <<= 1UL; - } - } - - base->SYS_CTRL = (base->SYS_CTRL & (~USDHC_SYS_CTRL_SDCLKFS_MASK)) | USDHC_SYS_CTRL_SDCLKFS(prescaler); -} - -/*! - * brief Configures the MMC boot feature. - * - * Example: - code - usdhc_boot_config_t config; - config.ackTimeoutCount = 4; - config.bootMode = kUSDHC_BootModeNormal; - config.blockCount = 5; - config.enableBootAck = true; - config.enableBoot = true; - config.enableAutoStopAtBlockGap = true; - USDHC_SetMmcBootConfig(USDHC, &config); - endcode - * - * param base USDHC peripheral base address. - * param config The MMC boot configuration information. - */ -void USDHC_SetMmcBootConfig(USDHC_Type *base, const usdhc_boot_config_t *config) -{ - assert(config != NULL); - assert(config->ackTimeoutCount <= (USDHC_MMC_BOOT_DTOCV_ACK_MASK >> USDHC_MMC_BOOT_DTOCV_ACK_SHIFT)); - assert(config->blockCount <= (USDHC_MMC_BOOT_BOOT_BLK_CNT_MASK >> USDHC_MMC_BOOT_BOOT_BLK_CNT_SHIFT)); - - uint32_t mmcboot = base->MMC_BOOT; - - mmcboot &= ~(USDHC_MMC_BOOT_DTOCV_ACK_MASK | USDHC_MMC_BOOT_BOOT_MODE_MASK | USDHC_MMC_BOOT_BOOT_BLK_CNT_MASK); - mmcboot |= USDHC_MMC_BOOT_DTOCV_ACK(config->ackTimeoutCount) | USDHC_MMC_BOOT_BOOT_MODE(config->bootMode); - - if (config->enableBootAck) - { - mmcboot |= USDHC_MMC_BOOT_BOOT_ACK_MASK; - } - if (config->enableAutoStopAtBlockGap) - { - mmcboot |= - USDHC_MMC_BOOT_AUTO_SABG_EN_MASK | USDHC_MMC_BOOT_BOOT_BLK_CNT(USDHC_MAX_BLOCK_COUNT - config->blockCount); - /* always set the block count to USDHC_MAX_BLOCK_COUNT to use auto stop at block gap feature */ - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(config->blockSize) | USDHC_BLK_ATT_BLKCNT(USDHC_MAX_BLOCK_COUNT))); - } - else - { - base->BLK_ATT = ((base->BLK_ATT & ~(USDHC_BLK_ATT_BLKSIZE_MASK | USDHC_BLK_ATT_BLKCNT_MASK)) | - (USDHC_BLK_ATT_BLKSIZE(config->blockSize) | USDHC_BLK_ATT_BLKCNT(config->blockCount))); - } - - base->MMC_BOOT = mmcboot; -} - -/*! - * brief Sets the ADMA1 descriptor table configuration. - * - * param admaTable Adma table address. - * param admaTableWords Adma table length. - * param dataBufferAddr Data buffer address. - * param dataBytes Data length. - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA1Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags) -{ - assert(NULL != admaTable); - assert(NULL != dataBufferAddr); - - uint32_t miniEntries, startEntries = 0UL, - maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma1_descriptor_t); - usdhc_adma1_descriptor_t *adma1EntryAddress = (usdhc_adma1_descriptor_t *)(uint32_t)(admaTable); - uint32_t i, dmaBufferLen = 0UL; - const uint32_t *data = dataBufferAddr; - - if (((uint32_t)data % USDHC_ADMA1_ADDRESS_ALIGN) != 0UL) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - - if (flags == (uint32_t)kUSDHC_AdmaDescriptorMultipleFlag) - { - return kStatus_USDHC_NotSupport; - } - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (dataBytes % sizeof(uint32_t) != 0UL) - { - /* make the data length as word-aligned */ - dataBytes += sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); - } - - /* Check if ADMA descriptor's number is enough. */ - if ((dataBytes % USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0UL) - { - miniEntries = dataBytes / USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - miniEntries = ((dataBytes / USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1UL); - } - - /* ADMA1 needs two descriptors to finish a transfer */ - miniEntries <<= 1UL; - - if (miniEntries + startEntries > maxEntries) - { - return kStatus_OutOfRange; - } - - for (i = startEntries; i < (miniEntries + startEntries); i += 2UL) - { - if (dataBytes > USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) - { - dmaBufferLen = USDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - dmaBufferLen = dataBytes; - } - - adma1EntryAddress[i] = (dmaBufferLen << USDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT); - adma1EntryAddress[i] |= (uint32_t)kUSDHC_Adma1DescriptorTypeSetLength; - adma1EntryAddress[i + 1UL] = (uint32_t)(data); - adma1EntryAddress[i + 1UL] |= (uint32_t)kUSDHC_Adma1DescriptorTypeTransfer; - data += dmaBufferLen / sizeof(uint32_t); - dataBytes -= dmaBufferLen; - } - /* the end of the descriptor */ - adma1EntryAddress[i - 1UL] |= (uint32_t)kUSDHC_Adma1DescriptorEndFlag; - - return kStatus_Success; -} - -/*! - * brief Sets the ADMA2 descriptor table configuration. - * - * param admaTable Adma table address. - * param admaTableWords Adma table length. - * param dataBufferAddr Data buffer address. - * param dataBytes Data Data length. - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetADMA2Descriptor( - uint32_t *admaTable, uint32_t admaTableWords, const uint32_t *dataBufferAddr, uint32_t dataBytes, uint32_t flags) -{ - assert(NULL != admaTable); - assert(NULL != dataBufferAddr); - - uint32_t miniEntries, startEntries = 0UL, - maxEntries = (admaTableWords * sizeof(uint32_t)) / sizeof(usdhc_adma2_descriptor_t); - usdhc_adma2_descriptor_t *adma2EntryAddress = (usdhc_adma2_descriptor_t *)(uint32_t)(admaTable); - uint32_t i, dmaBufferLen = 0UL; - const uint32_t *data = dataBufferAddr; - - if (((uint32_t)data % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - /* - * Add non aligned access support ,user need make sure your buffer size is big - * enough to hold the data,in other words,user need make sure the buffer size - * is 4 byte aligned - */ - if (dataBytes % sizeof(uint32_t) != 0UL) - { - /* make the data length as word-aligned */ - dataBytes += sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); - } - - /* Check if ADMA descriptor's number is enough. */ - if ((dataBytes % USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0UL) - { - miniEntries = dataBytes / USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - miniEntries = ((dataBytes / USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1UL); - } - /* calucate the start entry for multiple descriptor mode, ADMA engine is not stop, so update the descriptor - data adress and data size is enough */ - if (flags == (uint32_t)kUSDHC_AdmaDescriptorMultipleFlag) - { - for (i = 0UL; i < maxEntries; i++) - { - if ((adma2EntryAddress[i].attribute & (uint32_t)kUSDHC_Adma2DescriptorValidFlag) == 0UL) - { - break; - } - } - startEntries = i; - /* add one entry for dummy entry */ - miniEntries += 1UL; - } - - if ((miniEntries + startEntries) > maxEntries) - { - return kStatus_OutOfRange; - } - - for (i = startEntries; i < (miniEntries + startEntries); i++) - { - if (dataBytes > USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) - { - dmaBufferLen = USDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; - } - else - { - dmaBufferLen = (dataBytes == 0UL ? sizeof(uint32_t) : - dataBytes); /* adma don't support 0 data length transfer descriptor */ - } - - /* Each descriptor for ADMA2 is 64-bit in length */ - adma2EntryAddress[i].address = (dataBytes == 0UL) ? &s_usdhcBootDummy : data; - adma2EntryAddress[i].attribute = (dmaBufferLen << USDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT); - adma2EntryAddress[i].attribute |= - (dataBytes == 0UL) ? - 0UL : - ((uint32_t)kUSDHC_Adma2DescriptorTypeTransfer | (uint32_t)kUSDHC_Adma2DescriptorInterruptFlag); - data += (dmaBufferLen / sizeof(uint32_t)); - - if (dataBytes != 0UL) - { - dataBytes -= dmaBufferLen; - } - } - - /* add a dummy valid ADMA descriptor for multiple descriptor mode, this is useful when transfer boot data, the ADMA - engine - will not stop at block gap */ - if (flags == (uint32_t)kUSDHC_AdmaDescriptorMultipleFlag) - { - adma2EntryAddress[startEntries + 1UL].attribute |= (uint32_t)kUSDHC_Adma2DescriptorTypeTransfer; - } - else - { - /* set the end bit */ - adma2EntryAddress[i - 1UL].attribute |= (uint32_t)kUSDHC_Adma2DescriptorEndFlag; - } - - return kStatus_Success; -} - -/*! - * brief Internal DMA configuration. - * This function is used to config the USDHC DMA related registers. - * param base USDHC peripheral base address. - * param adma configuration - * param dataAddr transfer data address, a simple DMA parameter, if ADMA is used, leave it to NULL. - * param enAutoCmd23 flag to indicate Auto CMD23 is enable or not, a simple DMA parameter,if ADMA is used, leave it to - * false. - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetInternalDmaConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - const uint32_t *dataAddr, - bool enAutoCmd23) -{ - assert(dmaConfig != NULL); - assert(dataAddr != NULL); - assert((NULL != dmaConfig->admaTable) && - (((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uint32_t)dmaConfig->admaTable) == 0UL)); - -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - /* disable the external DMA if support */ - base->VEND_SPEC &= ~USDHC_VEND_SPEC_EXT_DMA_EN_MASK; -#endif - - if (dmaConfig->dmaMode == kUSDHC_DmaModeSimple) - { - /* check DMA data buffer address align or not */ - if (((uint32_t)dataAddr % USDHC_ADMA2_ADDRESS_ALIGN) != 0UL) - { - return kStatus_USDHC_DMADataAddrNotAlign; - } - /* in simple DMA mode if use auto CMD23, address should load to ADMA addr, - and block count should load to DS_ADDR*/ - if (enAutoCmd23) - { - base->ADMA_SYS_ADDR = (uint32_t)dataAddr; - } - else - { - base->DS_ADDR = (uint32_t)dataAddr; - } - } - else - { - /* When use ADMA, disable simple DMA */ - base->DS_ADDR = 0UL; - base->ADMA_SYS_ADDR = (uint32_t)(dmaConfig->admaTable); - } - -#if (defined(FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) && FSL_FEATURE_USDHC_HAS_NO_RW_BURST_LEN) - /* select DMA mode and config the burst length */ - base->PROT_CTRL &= ~(USDHC_PROT_CTRL_DMASEL_MASK); - base->PROT_CTRL |= USDHC_PROT_CTRL_DMASEL(dmaConfig->dmaMode); -#else - /* select DMA mode and config the burst length */ - base->PROT_CTRL &= ~(USDHC_PROT_CTRL_DMASEL_MASK | USDHC_PROT_CTRL_BURST_LEN_EN_MASK); - base->PROT_CTRL |= USDHC_PROT_CTRL_DMASEL(dmaConfig->dmaMode) | USDHC_PROT_CTRL_BURST_LEN_EN(dmaConfig->burstLen); -#endif - /* enable DMA */ - base->MIX_CTRL |= USDHC_MIX_CTRL_DMAEN_MASK; - - return kStatus_Success; -} - -/*! - * brief Sets the DMA descriptor table configuration. - * A high level DMA descriptor configuration function. - * param base USDHC peripheral base address. - * param adma configuration - * param data Data descriptor - * param flags ADAM descriptor flag, used to indicate to create multiple or single descriptor, please - * reference _usdhc_adma_flag - * retval kStatus_OutOfRange ADMA descriptor table length isn't enough to describe data. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_SetAdmaTableConfig(USDHC_Type *base, - usdhc_adma_config_t *dmaConfig, - usdhc_data_t *dataConfig, - uint32_t flags) -{ - assert(NULL != dmaConfig); - assert((NULL != dmaConfig->admaTable) && - (((USDHC_ADMA_TABLE_ADDRESS_ALIGN - 1U) & (uint32_t)dmaConfig->admaTable) == 0UL)); - assert(NULL != dataConfig); - - status_t error = kStatus_Fail; - uint32_t bootDummyOffset = - dataConfig->dataType == (uint32_t)kUSDHC_TransferDataBootcontinous ? sizeof(uint32_t) : 0UL; - const uint32_t *data = - (const uint32_t *)((uint32_t)((dataConfig->rxData == NULL) ? dataConfig->txData : dataConfig->rxData) + - bootDummyOffset); - uint32_t blockSize = dataConfig->blockSize * dataConfig->blockCount - bootDummyOffset; - -#if FSL_FEATURE_USDHC_HAS_EXT_DMA - if (dmaConfig->dmaMode == kUSDHC_ExternalDMA) - { - /* enable the external DMA */ - base->VEND_SPEC |= USDHC_VEND_SPEC_EXT_DMA_EN_MASK; - } - else -#endif - if (dmaConfig->dmaMode == kUSDHC_DmaModeSimple) - { - error = kStatus_Success; - } - else if (dmaConfig->dmaMode == kUSDHC_DmaModeAdma1) - { - error = USDHC_SetADMA1Descriptor(dmaConfig->admaTable, dmaConfig->admaTableWords, data, blockSize, flags); - } - /* ADMA2 */ - else - { - error = USDHC_SetADMA2Descriptor(dmaConfig->admaTable, dmaConfig->admaTableWords, data, blockSize, flags); - } - - /* for internal dma, internal DMA configurations should not update the configurations when continous transfer the - * boot data, only the DMA descriptor need update */ - if ((dmaConfig->dmaMode != kUSDHC_ExternalDMA) && (error == kStatus_Success) && - (dataConfig->dataType != (uint32_t)kUSDHC_TransferDataBootcontinous)) - { - error = USDHC_SetInternalDmaConfig(base, dmaConfig, data, dataConfig->enableAutoCommand23); - } - - return error; -} - -/*! - * brief Transfers the command/data using a blocking method. - * - * This function waits until the command response/data is received or the USDHC encounters an error by polling the - * status - * flag. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * note There is no need to call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * param base USDHC peripheral base address. - * param adma configuration - * param transfer Transfer content. - * retval kStatus_InvalidArgument Argument is invalid. - * retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * retval kStatus_USDHC_SendCommandFailed Send command failed. - * retval kStatus_USDHC_TransferDataFailed Transfer data failed. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferBlocking(USDHC_Type *base, usdhc_adma_config_t *dmaConfig, usdhc_transfer_t *transfer) -{ - assert(transfer != NULL); - - status_t error = kStatus_Fail; - usdhc_command_t *command = transfer->command; - usdhc_data_t *data = transfer->data; - bool enDMA = true; - bool executeTuning = ((data == NULL) ? false : data->dataType == (uint32_t)kUSDHC_TransferDataTuning); - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - /*check re-tuning request*/ - if ((USDHC_GetInterruptStatusFlags(base) & (uint32_t)kUSDHC_ReTuningEventFlag) != 0UL) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_ReTuningEventFlag); - return kStatus_USDHC_ReTuningRequest; - } -#endif - - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if ((data != NULL) && (dmaConfig != NULL) && (!executeTuning)) - { - error = USDHC_SetAdmaTableConfig( - base, dmaConfig, data, - (uint32_t)(IS_USDHC_FLAG_SET(data->dataType, kUSDHC_TransferDataBoot) ? kUSDHC_AdmaDescriptorMultipleFlag : - kUSDHC_AdmaDescriptorSingleFlag)); - } - - /* if the DMA desciptor configure fail or not needed , disable it */ - if (error != kStatus_Success) - { - enDMA = false; - /* disable DMA, using polling mode in this situation */ - USDHC_EnableInternalDMA(base, false); - } -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - else - { - if (data->txData != NULL) - { - /* clear the DCACHE */ - DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount)); - } - else - { - /* clear the DCACHE */ - DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount)); - } - } -#endif - - /* config the data transfer parameter */ - error = USDHC_SetDataTransferConfig(base, data, &(command->flags), enDMA); - if (kStatus_Success != error) - { - return error; - } - /* send command first */ - USDHC_SendCommand(base, command); - /* wait command done */ - error = - USDHC_WaitCommandDone(base, command, (data == NULL) || (data->dataType == (uint32_t)kUSDHC_TransferDataNormal)); - if (kStatus_Success != error) - { - return kStatus_USDHC_SendCommandFailed; - } - - /* wait transfer data finsih */ - if (data != NULL) - { - error = USDHC_TransferDataBlocking(base, data, enDMA); - if (kStatus_Success != error) - { - return error; - } - } - - return kStatus_Success; -} - -/*! - * brief Transfers the command/data using an interrupt and an asynchronous method. - * - * This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an - * error. - * The application must not call this API in multiple threads at the same time. Because of that this API doesn't support - * the re-entry mechanism. - * - * note Call the API 'USDHC_TransferCreateHandle' when calling this API. - * - * param base USDHC peripheral base address. - * param handle USDHC handle. - * param adma configuration. - * param transfer Transfer content. - * retval kStatus_InvalidArgument Argument is invalid. - * retval kStatus_USDHC_BusyTransferring Busy transferring. - * retval kStatus_USDHC_PrepareAdmaDescriptorFailed Prepare ADMA descriptor failed. - * retval kStatus_Success Operate successfully. - */ -status_t USDHC_TransferNonBlocking(USDHC_Type *base, - usdhc_handle_t *handle, - usdhc_adma_config_t *dmaConfig, - usdhc_transfer_t *transfer) -{ - assert(handle != NULL); - assert(transfer != NULL); - - status_t error = kStatus_Fail; - usdhc_command_t *command = transfer->command; - usdhc_data_t *data = transfer->data; - bool executeTuning = ((data == NULL) ? false : data->dataType == (uint32_t)kUSDHC_TransferDataTuning); - bool enDMA = true; - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - /*check re-tuning request*/ - if ((USDHC_GetInterruptStatusFlags(base) & ((uint32_t)kUSDHC_ReTuningEventFlag)) != 0UL) - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_ReTuningEventFlag); - return kStatus_USDHC_ReTuningRequest; - } -#endif - /* Save command and data into handle before transferring. */ - - handle->command = command; - handle->data = data; - /* transferredWords will only be updated in ISR when transfer way is DATAPORT. */ - handle->transferredWords = 0UL; - - /* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/ - if ((data != NULL) && (dmaConfig != NULL) && (!executeTuning)) - { - error = - USDHC_SetAdmaTableConfig(base, dmaConfig, data, - (uint32_t)(IS_USDHC_FLAG_SET(data->dataType, (uint32_t)kUSDHC_TransferDataBoot) ? - kUSDHC_AdmaDescriptorMultipleFlag : - kUSDHC_AdmaDescriptorSingleFlag)); - } - - /* if the DMA desciptor configure fail or not needed , disable it */ - if (error != kStatus_Success) - { - /* disable DMA, using polling mode in this situation */ - USDHC_EnableInternalDMA(base, false); - enDMA = false; - } -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - else - { - if (data->txData != NULL) - { - /* clear the DCACHE */ - DCACHE_CleanByRange((uint32_t)data->txData, (data->blockSize) * (data->blockCount)); - } - else - { - /* clear the DCACHE */ - DCACHE_CleanInvalidateByRange((uint32_t)data->rxData, (data->blockSize) * (data->blockCount)); - } - } -#endif - - error = USDHC_SetDataTransferConfig(base, data, &(command->flags), enDMA); - if (kStatus_Success != error) - { - return error; - } - - /* enable interrupt per transfer request */ - if (handle->data != NULL) - { - USDHC_ClearInterruptStatusFlags( - base, (uint32_t)(enDMA == false ? kUSDHC_DataFlag : kUSDHC_DataDMAFlag) | (uint32_t)kUSDHC_CommandFlag); - USDHC_EnableInterruptSignal( - base, (uint32_t)(enDMA == false ? kUSDHC_DataFlag : kUSDHC_DataDMAFlag) | (uint32_t)kUSDHC_CommandFlag); - } - else - { - USDHC_ClearInterruptStatusFlags(base, kUSDHC_CommandFlag); - USDHC_EnableInterruptSignal(base, kUSDHC_CommandFlag); - } - - /* send command first */ - USDHC_SendCommand(base, command); - - return kStatus_Success; -} - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) -/*! - * brief manual tuning trigger or abort - * User should handle the tuning cmd and find the boundary of the delay - * then calucate a average value which will be config to the CLK_TUNE_CTRL_STATUS - * This function should called before USDHC_AdjustDelayforSDR104 function - * param base USDHC peripheral base address. - * param tuning enable flag - */ -void USDHC_EnableManualTuning(USDHC_Type *base, bool enable) -{ - if (enable) - { - /* make sure std_tun_en bit is clear */ - base->TUNING_CTRL &= ~USDHC_TUNING_CTRL_STD_TUNING_EN_MASK; - /* disable auto tuning here */ - base->MIX_CTRL &= ~USDHC_MIX_CTRL_AUTO_TUNE_EN_MASK; - /* execute tuning for SDR104 mode */ - base->MIX_CTRL |= - USDHC_MIX_CTRL_EXE_TUNE_MASK | USDHC_MIX_CTRL_SMP_CLK_SEL_MASK | USDHC_MIX_CTRL_FBCLK_SEL_MASK; - } - else - { /* abort the tuning */ - base->MIX_CTRL &= ~USDHC_MIX_CTRL_EXE_TUNE_MASK; - } -} - -/*! - * brief the SDR104 mode delay setting adjust - * This function should called after USDHC_ManualTuningForSDR104 - * param base USDHC peripheral base address. - * param delay setting configuration - * retval kStatus_Fail config the delay setting fail - * retval kStatus_Success config the delay setting success - */ -status_t USDHC_AdjustDelayForManualTuning(USDHC_Type *base, uint32_t delay) -{ - uint32_t clkTuneCtrl = 0UL; - - clkTuneCtrl = base->CLK_TUNE_CTRL_STATUS; - - clkTuneCtrl &= ~USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE_MASK; - - clkTuneCtrl |= USDHC_CLK_TUNE_CTRL_STATUS_DLY_CELL_SET_PRE(delay); - - /* load the delay setting */ - base->CLK_TUNE_CTRL_STATUS = clkTuneCtrl; - /* check delat setting error */ - if (IS_USDHC_FLAG_SET(base->CLK_TUNE_CTRL_STATUS, - USDHC_CLK_TUNE_CTRL_STATUS_PRE_ERR_MASK | USDHC_CLK_TUNE_CTRL_STATUS_NXT_ERR_MASK)) - { - return kStatus_Fail; - } - - return kStatus_Success; -} - -/*! - * brief the enable standard tuning function - * The standard tuning window and tuning counter use the default config - * tuning cmd is send by the software, user need to check the tuning result - * can be used for SDR50,SDR104,HS200 mode tuning - * param base USDHC peripheral base address. - * param tuning start tap - * param tuning step - * param enable/disable flag - */ -void USDHC_EnableStandardTuning(USDHC_Type *base, uint32_t tuningStartTap, uint32_t step, bool enable) -{ - uint32_t tuningCtrl = 0UL; - - if (enable) - { - /* feedback clock */ - base->MIX_CTRL |= USDHC_MIX_CTRL_FBCLK_SEL_MASK; - /* config tuning start and step */ - tuningCtrl = base->TUNING_CTRL; - tuningCtrl &= ~(USDHC_TUNING_CTRL_TUNING_START_TAP_MASK | USDHC_TUNING_CTRL_TUNING_STEP_MASK); - tuningCtrl |= (USDHC_TUNING_CTRL_TUNING_START_TAP(tuningStartTap) | USDHC_TUNING_CTRL_TUNING_STEP(step) | - USDHC_TUNING_CTRL_STD_TUNING_EN_MASK); - base->TUNING_CTRL = tuningCtrl; - - /* excute tuning */ - base->AUTOCMD12_ERR_STATUS |= - (USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK | USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK); - } - else - { - /* disable the standard tuning */ - base->TUNING_CTRL &= ~USDHC_TUNING_CTRL_STD_TUNING_EN_MASK; - /* clear excute tuning */ - base->AUTOCMD12_ERR_STATUS &= - ~(USDHC_AUTOCMD12_ERR_STATUS_EXECUTE_TUNING_MASK | USDHC_AUTOCMD12_ERR_STATUS_SMP_CLK_SEL_MASK); - } -} - -#if FSL_FEATURE_USDHC_HAS_HS400_MODE -/*! - * brief config the strobe DLL delay target and update interval - * - * param base USDHC peripheral base address. - * param delayTarget delay target - * param updateInterval update interval - */ -void USDHC_ConfigStrobeDLL(USDHC_Type *base, uint32_t delayTarget, uint32_t updateInterval) -{ - assert(delayTarget <= (USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET_MASK >> - USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT)); - - /* reset strobe dll firstly */ - base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_RESET_MASK; - /* clear reset and other register fields */ - base->STROBE_DLL_CTRL = 0; - /* configure the DELAY target and update interval */ - base->STROBE_DLL_CTRL |= USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_ENABLE_MASK | - USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_UPDATE_INT(updateInterval) | - USDHC_STROBE_DLL_CTRL_STROBE_DLL_CTRL_SLV_DLY_TARGET(delayTarget); - - while ( - (USDHC_GetStrobeDLLStatus(base) & (USDHC_STROBE_DLL_STATUS_STROBE_DLL_STS_SLV_LOCK_MASK | - USDHC_STROBE_DLL_STATUS_STROBE_DLL_STS_REF_LOCK_MASK)) != - ((USDHC_STROBE_DLL_STATUS_STROBE_DLL_STS_SLV_LOCK_MASK | USDHC_STROBE_DLL_STATUS_STROBE_DLL_STS_REF_LOCK_MASK))) - { - } -} -#endif - -/*! - * brief the auto tuning enbale for CMD/DATA line - * - * param base USDHC peripheral base address. - */ -void USDHC_EnableAutoTuningForCmdAndData(USDHC_Type *base) -{ - uint32_t busWidth = (base->PROT_CTRL & USDHC_PROT_CTRL_DTW_MASK) >> USDHC_PROT_CTRL_DTW_SHIFT; - - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_CMD_EN_MASK; - - /* 1bit data width */ - if (busWidth == 0UL) - { - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } - /* 4bit data width */ - else if (busWidth == 1UL) - { - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } - /* 8bit data width */ - else - { - base->VEND_SPEC2 |= USDHC_VEND_SPEC2_TUNING_8bit_EN_MASK; - base->VEND_SPEC2 &= ~USDHC_VEND_SPEC2_TUNING_1bit_EN_MASK; - } -} -#endif /* FSL_FEATURE_USDHC_HAS_SDR50_MODE */ - -static void USDHC_TransferHandleCardDetect(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_CardInsertionFlag)) - { - if (handle->callback.CardInserted != NULL) - { - handle->callback.CardInserted(base, handle->userData); - } - } - else - { - if (handle->callback.CardRemoved != NULL) - { - handle->callback.CardRemoved(base, handle->userData); - } - } -} - -static void USDHC_TransferHandleCommand(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->command != NULL); - - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_CommandErrorFlag)) - { - if (handle->callback.TransferComplete != NULL) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_SendCommandFailed, handle->userData); - } - } - else - { - /* Receive response */ - if (kStatus_Success != USDHC_ReceiveCommandResponse(base, handle->command)) - { - if (handle->callback.TransferComplete != NULL) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_SendCommandFailed, handle->userData); - } - } - else - { - if (handle->callback.TransferComplete != NULL) - { - handle->callback.TransferComplete(base, handle, kStatus_USDHC_SendCommandSuccess, handle->userData); - } - } - } - /* disable interrupt signal and reset command pointer */ - USDHC_DisableInterruptSignal(base, kUSDHC_CommandFlag); - handle->command = NULL; -} - -static void USDHC_TransferHandleData(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->data != NULL); - - status_t transferStatus = kStatus_USDHC_BusyTransferring; - uint32_t transferredWords = handle->transferredWords; - - if ((!(handle->data->enableIgnoreError)) && - (IS_USDHC_FLAG_SET(interruptFlags, (uint32_t)kUSDHC_DataErrorFlag | (uint32_t)kUSDHC_DmaErrorFlag))) - { - transferStatus = kStatus_USDHC_TransferDataFailed; - } - else - { - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_BufferReadReadyFlag)) - { - /* std tuning process only need to wait BRR */ - if (handle->data->dataType == (uint32_t)kUSDHC_TransferDataTuning) - { - transferStatus = kStatus_USDHC_TransferDataComplete; - } - else - { - handle->transferredWords = USDHC_ReadDataPort(base, handle->data, transferredWords); - } - } - else if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_BufferWriteReadyFlag)) - { - handle->transferredWords = USDHC_WriteDataPort(base, handle->data, transferredWords); - } - else - { - if ((IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_DmaCompleteFlag)) && - (handle->data->dataType == (uint32_t)kUSDHC_TransferDataBootcontinous)) - { - *(handle->data->rxData) = s_usdhcBootDummy; - } - - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_DataCompleteFlag)) - { - transferStatus = kStatus_USDHC_TransferDataComplete; - -#if defined(FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL) && FSL_SDK_ENABLE_DRIVER_CACHE_CONTROL - if (handle->data->rxData != NULL) - { - DCACHE_InvalidateByRange((uint32_t)(handle->data->rxData), - (handle->data->blockSize) * (handle->data->blockCount)); - } -#endif - } - } - } - - if ((handle->callback.TransferComplete != NULL) && (transferStatus != kStatus_USDHC_BusyTransferring)) - { - handle->callback.TransferComplete(base, handle, transferStatus, handle->userData); - USDHC_DisableInterruptSignal(base, (uint32_t)kUSDHC_DataFlag | (uint32_t)kUSDHC_DataDMAFlag); - handle->data = NULL; - } -} - -static void USDHC_TransferHandleSdioInterrupt(USDHC_Type *base, usdhc_handle_t *handle) -{ - if (handle->callback.SdioInterrupt != NULL) - { - handle->callback.SdioInterrupt(base, handle->userData); - } -} - -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) -static void USDHC_TransferHandleReTuning(USDHC_Type *base, usdhc_handle_t *handle, uint32_t interruptFlags) -{ - assert(handle->callback.ReTuning != NULL); - /* retuning request */ - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_TuningErrorFlag)) - { - handle->callback.ReTuning(base, handle->userData); /* retuning fail */ - } -} -#endif - -static void USDHC_TransferHandleBlockGap(USDHC_Type *base, usdhc_handle_t *handle) -{ - if (handle->callback.BlockGap != NULL) - { - handle->callback.BlockGap(base, handle->userData); - } -} - -/*! - * brief Creates the USDHC handle. - * - * param base USDHC peripheral base address. - * param handle USDHC handle pointer. - * param callback Structure pointer to contain all callback functions. - * param userData Callback function parameter. - */ -void USDHC_TransferCreateHandle(USDHC_Type *base, - usdhc_handle_t *handle, - const usdhc_transfer_callback_t *callback, - void *userData) -{ - assert(handle != NULL); - assert(callback != NULL); - - /* Zero the handle. */ - (void)memset(handle, 0, sizeof(*handle)); - - /* Set the callback. */ - handle->callback.CardInserted = callback->CardInserted; - handle->callback.CardRemoved = callback->CardRemoved; - handle->callback.SdioInterrupt = callback->SdioInterrupt; - handle->callback.BlockGap = callback->BlockGap; - handle->callback.TransferComplete = callback->TransferComplete; - handle->callback.ReTuning = callback->ReTuning; - handle->userData = userData; - - /* Save the handle in global variables to support the double weak mechanism. */ - s_usdhcHandle[USDHC_GetInstance(base)] = handle; - - /* save IRQ handler */ - s_usdhcIsr = USDHC_TransferHandleIRQ; - - (void)EnableIRQ(s_usdhcIRQ[USDHC_GetInstance(base)]); -} - -/*! - * brief IRQ handler for the USDHC. - * - * This function deals with the IRQs on the given host controller. - * - * param base USDHC peripheral base address. - * param handle USDHC handle. - */ -void USDHC_TransferHandleIRQ(USDHC_Type *base, usdhc_handle_t *handle) -{ - assert(handle != NULL); - - uint32_t interruptFlags; - - interruptFlags = USDHC_GetEnabledInterruptStatusFlags(base); - - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_CardDetectFlag)) - { - USDHC_TransferHandleCardDetect(base, handle, interruptFlags); - } - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_CommandFlag)) - { - USDHC_TransferHandleCommand(base, handle, interruptFlags); - } - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_DataFlag)) - { - USDHC_TransferHandleData(base, handle, interruptFlags); - } - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_CardInterruptFlag)) - { - USDHC_TransferHandleSdioInterrupt(base, handle); - } - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_BlockGapEventFlag)) - { - USDHC_TransferHandleBlockGap(base, handle); - } -#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE) - if (IS_USDHC_FLAG_SET(interruptFlags, kUSDHC_SDR104TuningFlag)) - { - USDHC_TransferHandleReTuning(base, handle, interruptFlags); - } -#endif - USDHC_ClearInterruptStatusFlags(base, interruptFlags); -} - -#ifdef USDHC0 -void USDHC0_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[0U], s_usdhcHandle[0U]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#ifdef USDHC1 -void USDHC1_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[1U], s_usdhcHandle[1U]); - SDK_ISR_EXIT_BARRIER; -} -#endif - -#ifdef USDHC2 -void USDHC2_DriverIRQHandler(void) -{ - s_usdhcIsr(s_usdhcBase[2U], s_usdhcHandle[2U]); - SDK_ISR_EXIT_BARRIER; -} - -#endif diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_wdog.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_wdog.c deleted file mode 100644 index ea6c970b33..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_wdog.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2016, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_wdog.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.wdog01" -#endif - -/******************************************************************************* - * Variables - ******************************************************************************/ -static WDOG_Type *const s_wdogBases[] = WDOG_BASE_PTRS; -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of WDOG clock name. */ -static const clock_ip_name_t s_wdogClock[] = WDOG_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -static const IRQn_Type s_wdogIRQ[] = WDOG_IRQS; - -/******************************************************************************* - * Code - ******************************************************************************/ -static uint32_t WDOG_GetInstance(WDOG_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_wdogBases); instance++) - { - if (s_wdogBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_wdogBases)); - - return instance; -} - -/*! - * brief Initializes the WDOG configuration structure. - * - * This function initializes the WDOG configuration structure to default values. The default - * values are as follows. - * code - * wdogConfig->enableWdog = true; - * wdogConfig->workMode.enableWait = true; - * wdogConfig->workMode.enableStop = false; - * wdogConfig->workMode.enableDebug = false; - * wdogConfig->enableInterrupt = false; - * wdogConfig->enablePowerdown = false; - * wdogConfig->resetExtension = flase; - * wdogConfig->timeoutValue = 0xFFU; - * wdogConfig->interruptTimeValue = 0x04u; - * endcode - * - * param config Pointer to the WDOG configuration structure. - * see wdog_config_t - */ -void WDOG_GetDefaultConfig(wdog_config_t *config) -{ - assert(NULL != config); - - /* Initializes the configure structure to zero. */ - (void)memset(config, 0, sizeof(*config)); - - config->enableWdog = true; - config->workMode.enableWait = false; - config->workMode.enableStop = false; - config->workMode.enableDebug = false; - config->enableInterrupt = false; - config->softwareResetExtension = false; - config->enablePowerDown = false; - config->timeoutValue = 0xffu; - config->interruptTimeValue = 0x04u; - config->enableTimeOutAssert = false; -} - -/*! - * brief Initializes the WDOG. - * - * This function initializes the WDOG. When called, the WDOG runs according to the configuration. - * - * This is an example. - * code - * wdog_config_t config; - * WDOG_GetDefaultConfig(&config); - * config.timeoutValue = 0xffU; - * config->interruptTimeValue = 0x04u; - * WDOG_Init(wdog_base,&config); - * endcode - * - * param base WDOG peripheral base address - * param config The configuration of WDOG - */ -void WDOG_Init(WDOG_Type *base, const wdog_config_t *config) -{ - assert(NULL != config); - - uint16_t value = 0u; - uint32_t primaskValue = 0U; - - value = WDOG_WCR_WDE(config->enableWdog) | WDOG_WCR_WDW(config->workMode.enableWait) | - WDOG_WCR_WDZST(config->workMode.enableStop) | WDOG_WCR_WDBG(config->workMode.enableDebug) | - WDOG_WCR_SRE(config->softwareResetExtension) | WDOG_WCR_WT(config->timeoutValue) | - WDOG_WCR_WDT(config->enableTimeOutAssert) | WDOG_WCR_SRS_MASK | WDOG_WCR_WDA_MASK; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Set configuration */ - CLOCK_EnableClock(s_wdogClock[WDOG_GetInstance(base)]); -#endif - - primaskValue = DisableGlobalIRQ(); - base->WICR = WDOG_WICR_WICT(config->interruptTimeValue) | WDOG_WICR_WIE(config->enableInterrupt); - base->WMCR = WDOG_WMCR_PDE(config->enablePowerDown); - base->WCR = value; - EnableGlobalIRQ(primaskValue); - if (config->enableInterrupt) - { - (void)EnableIRQ(s_wdogIRQ[WDOG_GetInstance(base)]); - } -} - -/*! - * brief Shuts down the WDOG. - * - * This function shuts down the WDOG. - * Watchdog Enable bit is a write one once only bit. It is not - * possible to clear this bit by a software write, once the bit is set. - * This bit(WDE) can be set/reset only in debug mode(exception). - */ -void WDOG_Deinit(WDOG_Type *base) -{ - if (0U != (base->WCR & WDOG_WCR_WDBG_MASK)) - { - WDOG_Disable(base); - } -} - -/*! - * brief Gets the WDOG all reset status flags. - * - * This function gets all reset status flags. - * - * code - * uint16_t status; - * status = WDOG_GetStatusFlags (wdog_base); - * endcode - * param base WDOG peripheral base address - * return State of the status flag: asserted (true) or not-asserted (false).see _wdog_status_flags - * - true: a related status flag has been set. - * - false: a related status flag is not set. - */ -uint16_t WDOG_GetStatusFlags(WDOG_Type *base) -{ - uint16_t status_flag = 0U; - - status_flag |= (base->WCR & WDOG_WCR_WDE_MASK); - status_flag |= (base->WRSR & WDOG_WRSR_POR_MASK); - status_flag |= (base->WRSR & WDOG_WRSR_TOUT_MASK); - status_flag |= (base->WRSR & WDOG_WRSR_SFTW_MASK); - status_flag |= (base->WICR & WDOG_WICR_WTIS_MASK); - - return status_flag; -} - -/*! - * brief Clears the WDOG flag. - * - * This function clears the WDOG status flag. - * - * This is an example for clearing the interrupt flag. - * code - * WDOG_ClearStatusFlags(wdog_base,KWDOG_InterruptFlag); - * endcode - * param base WDOG peripheral base address - * param mask The status flags to clear. - * The parameter could be any combination of the following values. - * kWDOG_TimeoutFlag - */ -void WDOG_ClearInterruptStatus(WDOG_Type *base, uint16_t mask) -{ - if (0U != (mask & (uint16_t)kWDOG_InterruptFlag)) - { - base->WICR |= WDOG_WICR_WTIS_MASK; - } -} - -/*! - * brief Refreshes the WDOG timer. - * - * This function feeds the WDOG. - * This function should be called before the WDOG timer is in timeout. Otherwise, a reset is asserted. - * - * param base WDOG peripheral base address - */ -void WDOG_Refresh(WDOG_Type *base) -{ - uint32_t primaskValue = 0U; - - /* Disable the global interrupt to protect refresh sequence */ - primaskValue = DisableGlobalIRQ(); - base->WSR = WDOG_REFRESH_KEY & 0xFFFFU; - base->WSR = (WDOG_REFRESH_KEY >> 16U) & 0xFFFFU; - EnableGlobalIRQ(primaskValue); -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbara.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbara.c deleted file mode 100644 index cc6307bbb6..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbara.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_xbara.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xbara" -#endif - -/* Macros for entire XBARA_CTRL register. */ -#define XBARA_CTRLx(base, index) (((volatile uint16_t *)(&((base)->CTRL0)))[(index)]) - -typedef union -{ - uint8_t _u8[2]; - uint16_t _u16; -} xbara_u8_u16_t; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get the XBARA instance from peripheral base address. - * - * @param base XBARA peripheral base address. - * @return XBARA instance. - */ -static uint32_t XBARA_GetInstance(XBARA_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Array of XBARA peripheral base address. */ -static XBARA_Type *const s_xbaraBases[] = XBARA_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of XBARA clock name. */ -static const clock_ip_name_t s_xbaraClock[] = XBARA_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t XBARA_GetInstance(XBARA_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_xbaraBases); instance++) - { - if (s_xbaraBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_xbaraBases)); - - return instance; -} - -/*! - * brief Initializes the XBARA module. - * - * This function un-gates the XBARA clock. - * - * param base XBARA peripheral address. - */ -void XBARA_Init(XBARA_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable XBARA module clock. */ - CLOCK_EnableClock(s_xbaraClock[XBARA_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Shuts down the XBARA module. - * - * This function disables XBARA clock. - * - * param base XBARA peripheral address. - */ -void XBARA_Deinit(XBARA_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable XBARA module clock. */ - CLOCK_DisableClock(s_xbaraClock[XBARA_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Sets a connection between the selected XBARA_IN[*] input and the XBARA_OUT[*] output signal. - * - * This function connects the XBARA input to the selected XBARA output. - * If more than one XBARA module is available, only the inputs and outputs from the same module - * can be connected. - * - * Example: - code - XBARA_SetSignalsConnection(XBARA, kXBARA_InputPIT_TRG0, kXBARA_OutputDMAMUX18); - endcode - * - * param base XBARA peripheral address. - * param input XBARA input signal. - * param output XBARA output signal. - */ -void XBARA_SetSignalsConnection(XBARA_Type *base, xbar_input_signal_t input, xbar_output_signal_t output) -{ - xbara_u8_u16_t regVal; - uint8_t byteInReg; - uint8_t outputIndex = (uint8_t)output; - - byteInReg = outputIndex % 2U; - - regVal._u16 = XBARA_SELx(base, outputIndex); - - regVal._u8[byteInReg] = (uint8_t)input; - - XBARA_SELx(base, outputIndex) = regVal._u16; -} - -/*! - * brief Gets the active edge detection status. - * - * This function gets the active edge detect status of all XBARA_OUTs. If the - * active edge occurs, the return value is asserted. When the interrupt or the DMA - * functionality is enabled for the XBARA_OUTx, this field is 1 when the interrupt - * or DMA request is asserted and 0 when the interrupt or DMA request has been - * cleared. - * - * param base XBARA peripheral address. - * return the mask of these status flag bits. - */ -uint32_t XBARA_GetStatusFlags(XBARA_Type *base) -{ - uint32_t status_flag; - - status_flag = ((uint32_t)base->CTRL0 & (XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK)); - - status_flag |= (((uint32_t)base->CTRL1 & (XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK)) << 16U); - - return status_flag; -} - -/*! - * brief Clears the edge detection status flags of relative mask. - * - * param base XBARA peripheral address. - * param mask the status flags to clear. - */ -void XBARA_ClearStatusFlags(XBARA_Type *base, uint32_t mask) -{ - uint16_t regVal; - - /* Assign regVal to CTRL0 register's value */ - regVal = (base->CTRL0); - /* Perform this command to avoid writing 1 into interrupt flag bits */ - regVal &= (uint16_t)(~(XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK)); - /* Write 1 to interrupt flag bits corresponding to mask */ - regVal |= (uint16_t)(mask & (XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK)); - /* Write regVal value into CTRL0 register */ - base->CTRL0 = regVal; - - /* Assign regVal to CTRL1 register's value */ - regVal = (base->CTRL1); - /* Perform this command to avoid writing 1 into interrupt flag bits */ - regVal &= (uint16_t)(~(XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK)); - /* Write 1 to interrupt flag bits corresponding to mask */ - regVal |= (uint16_t)((mask >> 16U) & (XBARA_CTRL1_STS2_MASK | XBARA_CTRL1_STS3_MASK)); - /* Write regVal value into CTRL1 register */ - base->CTRL1 = regVal; -} - -/*! - * brief Configures the XBARA control register. - * - * This function configures an XBARA control register. The active edge detection - * and the DMA/IRQ function on the corresponding XBARA output can be set. - * - * Example: - code - xbara_control_config_t userConfig; - userConfig.activeEdge = kXBARA_EdgeRising; - userConfig.requestType = kXBARA_RequestInterruptEnalbe; - XBARA_SetOutputSignalConfig(XBARA, kXBARA_OutputDMAMUX18, &userConfig); - endcode - * - * param base XBARA peripheral address. - * param output XBARA output number. - * param controlConfig Pointer to structure that keeps configuration of control register. - */ -void XBARA_SetOutputSignalConfig(XBARA_Type *base, - xbar_output_signal_t output, - const xbara_control_config_t *controlConfig) -{ - uint8_t outputIndex = (uint8_t)output; - uint8_t regIndex; - uint8_t byteInReg; - xbara_u8_u16_t regVal; - - assert(outputIndex < (uint32_t)FSL_FEATURE_XBARA_INTERRUPT_COUNT); - - regIndex = outputIndex / 2U; - byteInReg = outputIndex % 2U; - - regVal._u16 = XBARA_CTRLx(base, regIndex); - - /* Don't clear the status flags. */ - regVal._u16 &= (uint16_t)(~(XBARA_CTRL0_STS0_MASK | XBARA_CTRL0_STS1_MASK)); - - regVal._u8[byteInReg] = (uint8_t)(XBARA_CTRL0_EDGE0(controlConfig->activeEdge) | - (uint16_t)(((uint32_t)controlConfig->requestType) << XBARA_CTRL0_DEN0_SHIFT)); - - XBARA_CTRLx(base, regIndex) = regVal._u16; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbarb.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbarb.c deleted file mode 100644 index c1878a2ae4..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/drivers/fsl_xbarb.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2015, Freescale Semiconductor, Inc. - * Copyright 2016-2019 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_xbarb.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xbarb" -#endif - -typedef union -{ - uint8_t _u8[2]; - uint16_t _u16; -} xbarb_u8_u16_t; - -/******************************************************************************* - * Prototypes - ******************************************************************************/ - -/*! - * @brief Get the XBARB instance from peripheral base address. - * - * @param base XBARB peripheral base address. - * @return XBARB instance. - */ -static uint32_t XBARB_GetInstance(XBARB_Type *base); - -/******************************************************************************* - * Variables - ******************************************************************************/ - -/* Array of XBARB peripheral base address. */ -static XBARB_Type *const s_xbarbBases[] = XBARB_BASE_PTRS; - -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) -/* Array of XBARB clock name. */ -static const clock_ip_name_t s_xbarbClock[] = XBARB_CLOCKS; -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ - -/******************************************************************************* - * Code - ******************************************************************************/ - -static uint32_t XBARB_GetInstance(XBARB_Type *base) -{ - uint32_t instance; - - /* Find the instance index from base address mappings. */ - for (instance = 0; instance < ARRAY_SIZE(s_xbarbBases); instance++) - { - if (s_xbarbBases[instance] == base) - { - break; - } - } - - assert(instance < ARRAY_SIZE(s_xbarbBases)); - - return instance; -} - -/*! - * brief Initializes the XBARB module. - * - * This function un-gates the XBARB clock. - * - * param base XBARB peripheral address. - */ -void XBARB_Init(XBARB_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Enable XBARB module clock. */ - CLOCK_EnableClock(s_xbarbClock[XBARB_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Shuts down the XBARB module. - * - * This function disables XBARB clock. - * - * param base XBARB peripheral address. - */ -void XBARB_Deinit(XBARB_Type *base) -{ -#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) - /* Disable XBARB module clock. */ - CLOCK_DisableClock(s_xbarbClock[XBARB_GetInstance(base)]); -#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ -} - -/*! - * brief Configures a connection between the selected XBARB_IN[*] input and the XBARB_OUT[*] output signal. - * - * This function configures which XBARB input is connected to the selected XBARB output. - * If more than one XBARB module is available, only the inputs and outputs from the same module - * can be connected. - * - * param base XBARB peripheral address. - * param input XBARB input signal. - * param output XBARB output signal. - */ -void XBARB_SetSignalsConnection(XBARB_Type *base, xbar_input_signal_t input, xbar_output_signal_t output) -{ - xbarb_u8_u16_t regVal; - uint8_t byteInReg; - uint8_t outputIndex = (uint8_t)output; - - byteInReg = outputIndex % 2U; - - regVal._u16 = XBARB_SELx(base, outputIndex); - - regVal._u8[byteInReg] = (uint8_t)input; - - XBARB_SELx(base, outputIndex) = regVal._u16; -} diff --git a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c b/bsps/arm/imxrt/nxp/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c deleted file mode 100644 index 41b273f70b..0000000000 --- a/bsps/arm/imxrt/nxp/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include "fsl_flexspi_nor_boot.h" - -/* Component ID definition, used by tools. */ -#ifndef FSL_COMPONENT_ID -#define FSL_COMPONENT_ID "platform.drivers.xip_device" -#endif - -#if defined(XIP_BOOT_HEADER_ENABLE) && (XIP_BOOT_HEADER_ENABLE == 1) -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) - __attribute__((section(".boot_hdr.ivt"))) -#elif defined(__ICCARM__) -#pragma location=".boot_hdr.ivt" -#endif -/************************************* - * IVT Data - *************************************/ -const ivt image_vector_table = { - IVT_HEADER, /* IVT Header */ - IMAGE_ENTRY_ADDRESS, /* Image Entry Function */ - IVT_RSVD, /* Reserved = 0 */ - (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */ - (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */ - (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */ - (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */ - IVT_RSVD /* Reserved = 0 */ -}; - -#if defined(__CC_ARM) || defined(__ARMCC_VERSION) || defined(__GNUC__) - __attribute__((section(".boot_hdr.boot_data"))) -#elif defined(__ICCARM__) -#pragma location=".boot_hdr.boot_data" -#endif -/************************************* - * Boot Data - *************************************/ -const BOOT_DATA_T boot_data = { - FLASH_BASE, /* boot start location */ - FLASH_SIZE, /* size */ - PLUGIN_FLAG, /* Plugin flag*/ - 0xFFFFFFFF /* empty - extra data word */ -}; -#endif - - |