LPC54114: Update the ADC SDK driver

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/11110/head
Mahesh Mahadevan 2019-06-21 11:08:19 -05:00 committed by Evelyne Donnaes
parent 1ad10d72c7
commit dc5ff9ecd6
5 changed files with 1525 additions and 532 deletions

View File

@ -1,41 +1,19 @@
/*
** ###################################################################
** Version: rev. 1.0, 2016-05-09
** Build: b160802
** Build: b190225
**
** Abstract:
** Chip specific module features.
**
** Copyright (c) 2016 Freescale Semiconductor, Inc.
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2019 NXP
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without modification,
** are permitted provided that the following conditions are met:
** SPDX-License-Identifier: BSD-3-Clause
**
** o Redistributions of source code must retain the above copyright notice, this list
** of conditions and the following disclaimer.
**
** o Redistributions in binary form must reproduce the above copyright notice, this
** list of conditions and the following disclaimer in the documentation and/or
** other materials provided with the distribution.
**
** o Neither the name of Freescale Semiconductor, Inc. nor the names of its
** contributors may be used to endorse or promote products derived from this
** software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**
** http: www.freescale.com
** mail: support@freescale.com
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2016-05-09)
@ -55,6 +33,8 @@
#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1)
/* @brief CRC availability on the SoC. */
#define FSL_FEATURE_SOC_CRC_COUNT (1)
/* @brief CTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_CTIMER_COUNT (5)
/* @brief DMA availability on the SoC. */
#define FSL_FEATURE_SOC_DMA_COUNT (1)
/* @brief DMIC availability on the SoC. */
@ -89,8 +69,6 @@
#define FSL_FEATURE_SOC_SPIFI_COUNT (1)
/* @brief SYSCON availability on the SoC. */
#define FSL_FEATURE_SOC_SYSCON_COUNT (1)
/* @brief CTIMER availability on the SoC. */
#define FSL_FEATURE_SOC_CTIMER_COUNT (5)
/* @brief USART availability on the SoC. */
#define FSL_FEATURE_SOC_USART_COUNT (8)
/* @brief USB availability on the SoC. */
@ -100,16 +78,139 @@
/* @brief WWDT availability on the SoC. */
#define FSL_FEATURE_SOC_WWDT_COUNT (1)
/* ADC module features */
/* @brief Do not has input select (register INSEL). */
#define FSL_FEATURE_ADC_HAS_NO_INSEL (0)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE (1)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_RESOL (1)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL (1)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_TSAMP (1)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE (0)
/* @brief Has ASYNMODE bitfile in CTRL reigster. */
#define FSL_FEATURE_ADC_HAS_CTRL_CALMODE (0)
/* @brief Has startup register. */
#define FSL_FEATURE_ADC_HAS_STARTUP_REG (1)
/* @brief Has ADTrim register */
#define FSL_FEATURE_ADC_HAS_TRIM_REG (0)
/* @brief Has Calibration register. */
#define FSL_FEATURE_ADC_HAS_CALIB_REG (1)
/* DMA module features */
/* @brief Number of channels */
#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (20)
/* @brief Align size of DMA descriptor */
#define FSL_FEATURE_DMA_DESCRIPTOR_ALIGN_SIZE (512)
/* @brief DMA head link descriptor table align size */
#define FSL_FEATURE_DMA_LINK_DESCRIPTOR_ALIGN_SIZE (16U)
/* FLEXCOMM module features */
/* @brief FLEXCOMM0 USART INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_USART_INDEX (0)
/* @brief FLEXCOMM0 SPI INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_SPI_INDEX (0)
/* @brief FLEXCOMM0 I2C INDEX 0 */
#define FSL_FEATURE_FLEXCOMM0_I2C_INDEX (0)
/* @brief FLEXCOMM1 USART INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_USART_INDEX (1)
/* @brief FLEXCOMM1 SPI INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_SPI_INDEX (1)
/* @brief FLEXCOMM1 I2C INDEX 1 */
#define FSL_FEATURE_FLEXCOMM1_I2C_INDEX (1)
/* @brief FLEXCOMM2 USART INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_USART_INDEX (2)
/* @brief FLEXCOMM2 SPI INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_SPI_INDEX (2)
/* @brief FLEXCOMM2 I2C INDEX 2 */
#define FSL_FEATURE_FLEXCOMM2_I2C_INDEX (2)
/* @brief FLEXCOMM3 USART INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_USART_INDEX (3)
/* @brief FLEXCOMM3 SPI INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_SPI_INDEX (3)
/* @brief FLEXCOMM3 I2C INDEX 3 */
#define FSL_FEATURE_FLEXCOMM3_I2C_INDEX (3)
/* @brief FLEXCOMM4 USART INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_USART_INDEX (4)
/* @brief FLEXCOMM4 SPI INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_SPI_INDEX (4)
/* @brief FLEXCOMM4 I2C INDEX 4 */
#define FSL_FEATURE_FLEXCOMM4_I2C_INDEX (4)
/* @brief FLEXCOMM5 USART INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_USART_INDEX (5)
/* @brief FLEXCOMM5 SPI INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_SPI_INDEX (5)
/* @brief FLEXCOMM5 I2C INDEX 5 */
#define FSL_FEATURE_FLEXCOMM5_I2C_INDEX (5)
/* @brief FLEXCOMM6 USART INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_USART_INDEX (6)
/* @brief FLEXCOMM6 SPI INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_SPI_INDEX (6)
/* @brief FLEXCOMM6 I2C INDEX 6 */
#define FSL_FEATURE_FLEXCOMM6_I2C_INDEX (6)
/* @brief FLEXCOMM7 I2S INDEX 0 */
#define FSL_FEATURE_FLEXCOMM6_I2S_INDEX (0)
/* @brief FLEXCOMM7 USART INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_USART_INDEX (7)
/* @brief FLEXCOMM7 SPI INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_SPI_INDEX (7)
/* @brief FLEXCOMM7 I2C INDEX 7 */
#define FSL_FEATURE_FLEXCOMM7_I2C_INDEX (7)
/* @brief FLEXCOMM7 I2S INDEX 1 */
#define FSL_FEATURE_FLEXCOMM7_I2S_INDEX (1)
/* @brief I2S has DMIC interconnection */
#define FSL_FEATURE_FLEXCOMM_INSTANCE_I2S_HAS_DMIC_INTERCONNECTIONn(x) \
(((x) == FLEXCOMM0) ? (0) : \
(((x) == FLEXCOMM1) ? (0) : \
(((x) == FLEXCOMM2) ? (0) : \
(((x) == FLEXCOMM3) ? (0) : \
(((x) == FLEXCOMM4) ? (0) : \
(((x) == FLEXCOMM5) ? (0) : \
(((x) == FLEXCOMM6) ? (0) : \
(((x) == FLEXCOMM7) ? (1) : (-1)))))))))
/* I2S module features */
/* @brief I2S support dual channel transfer */
#define FSL_FEATURE_I2S_SUPPORT_SECONDARY_CHANNEL (0)
/* @brief I2S has DMIC interconnection */
#define FSL_FEATURE_FLEXCOMM_I2S_HAS_DMIC_INTERCONNECTION (1)
/* MAILBOX module features */
/* @brief Mailbox side for current core */
#define FSL_FEATURE_MAILBOX_SIDE_A (1)
/* @brief Mailbox has no reset control */
#define FSL_FEATURE_MAILBOX_HAS_NO_RESET (1)
/* MRT module features */
/* @brief number of channels. */
#define FSL_FEATURE_MRT_NUMBER_OF_CHANNELS (4)
/* interrupt module features */
/* @brief Lowest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MIN (-14)
/* @brief Highest interrupt request number. */
#define FSL_FEATURE_INTERRUPT_IRQ_MAX (105)
/* PINT module features */
/* @brief Number of connected outputs */
#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (8)
/* RTC module features */
/* @brief RTC has no reset control */
#define FSL_FEATURE_RTC_HAS_NO_RESET (1)
/* SCT module features */
/* @brief Number of events */
@ -118,6 +219,8 @@
#define FSL_FEATURE_SCT_NUMBER_OF_STATES (10)
/* @brief Number of match capture */
#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (10)
/* @brief Number of outputs */
#define FSL_FEATURE_SCT_NUMBER_OF_OUTPUTS (8)
/* SYSCON module features */
@ -129,6 +232,24 @@
#define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768)
/* @brief Flash size in bytes */
#define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (262144)
/* @brief IAP has Flash read & write function */
#define FSL_FEATURE_IAP_HAS_FLASH_FUNCTION (1)
/* @brief IAP has read Flash signature function */
#define FSL_FEATURE_IAP_HAS_FLASH_SIGNATURE_READ (1)
/* @brief IAP has read extended Flash signature function */
#define FSL_FEATURE_IAP_HAS_FLASH_EXTENDED_SIGNATURE_READ (0)
/* SysTick module features */
/* @brief Systick has external reference clock. */
#define FSL_FEATURE_SYSTICK_HAS_EXT_REF (0)
/* @brief Systick external reference clock is core clock divided by this value. */
#define FSL_FEATURE_SYSTICK_EXT_REF_CORE_DIV (0)
/* USB module features */
/* @brief Number of the endpoint in USB FS */
#define FSL_FEATURE_USB_EP_NUM (5)
#endif /* _LPC54114_cm4_FEATURES_H_ */

View File

@ -1,45 +1,32 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_adc.h"
#include "fsl_clock.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.lpc_adc"
#endif
static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
#define FREQUENCY_1MHZ (1000000U)
static uint32_t ADC_GetInstance(ADC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < FSL_FEATURE_SOC_ADC_COUNT; instance++)
for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
{
if (s_adcBases[instance] == base)
{
@ -47,19 +34,27 @@ static uint32_t ADC_GetInstance(ADC_Type *base)
}
}
assert(instance < FSL_FEATURE_SOC_ADC_COUNT);
assert(instance < ARRAY_SIZE(s_adcBases));
return instance;
}
/*!
* brief Initialize the ADC module.
*
* param base ADC peripheral base address.
* param config Pointer to configuration structure, see to #adc_config_t.
*/
void ADC_Init(ADC_Type *base, const adc_config_t *config)
{
assert(config != NULL);
uint32_t tmp32 = 0U;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable clock. */
CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* Disable the interrupts. */
base->INTEN = 0U; /* Quickly disable all the interrupts. */
@ -67,6 +62,7 @@ void ADC_Init(ADC_Type *base, const adc_config_t *config)
/* Configure the ADC block. */
tmp32 = ADC_CTRL_CLKDIV(config->clockDividerNumber);
#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
/* Async or Sync clock mode. */
switch (config->clockMode)
{
@ -76,84 +72,236 @@ void ADC_Init(ADC_Type *base, const adc_config_t *config)
default: /* kADC_ClockSynchronousMode */
break;
}
#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
/* Resolution. */
tmp32 |= ADC_CTRL_RESOL(config->resolution);
tmp32 |= ADC_CTRL_RESOL(config->resolution);
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL
/* Bypass calibration. */
if (config->enableBypassCalibration)
{
tmp32 |= ADC_CTRL_BYPASSCAL_MASK;
}
#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */
/* Sample time clock count. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP
/* Sample time clock count. */
#if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL)
if (config->clockMode == kADC_ClockAsynchronousMode)
{
#endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */
tmp32 |= ADC_CTRL_TSAMP(config->sampleTimeNumber);
#if (defined(FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL) && FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL)
}
#endif /* FSL_FEATURE_ADC_SYNCHRONOUS_USE_GPADC_CTRL */
#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE
if (config->enableLowPowerMode)
{
tmp32 |= ADC_CTRL_LPWRMODE_MASK;
}
#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */
base->CTRL = tmp32;
#if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN) && FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN
base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_LDO_POWER_EN_MASK;
if (config->clockMode == kADC_ClockSynchronousMode)
{
base->GPADC_CTRL0 |= ADC_GPADC_CTRL0_PASS_ENABLE(config->sampleTimeNumber);
}
#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL0_LDO_POWER_EN */
#if defined(FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL) && FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL
tmp32 = *(uint32_t *)FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL;
if (tmp32 & FSL_FEATURE_FLASH_ADDR_OF_TEMP_CAL_VALID)
{
base->GPADC_CTRL1 = (tmp32 >> 1);
}
#if !(defined(FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT) && FSL_FEATURE_ADC_HAS_STARTUP_ADC_INIT)
base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; /* Set the ADC Start bit */
#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */
#endif /* FSL_FEATURE_ADC_HAS_GPADC_CTRL1_OFFSET_CAL */
#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG
base->TRM &= ~ADC_TRM_VRANGE_MASK;
base->TRM |= ADC_TRM_VRANGE(config->voltageRange);
#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
}
/*!
* brief Gets an available pre-defined settings for initial configuration.
*
* This function initializes the initial configuration structure with an available settings. The default values are:
* code
* config->clockMode = kADC_ClockSynchronousMode;
* config->clockDividerNumber = 0U;
* config->resolution = kADC_Resolution12bit;
* config->enableBypassCalibration = false;
* config->sampleTimeNumber = 0U;
* endcode
* param config Pointer to configuration structure.
*/
void ADC_GetDefaultConfig(adc_config_t *config)
{
/* Initializes the configure structure to zero. */
memset(config, 0, sizeof(*config));
#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
config->clockMode = kADC_ClockSynchronousMode;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
config->clockDividerNumber = 0U;
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
config->resolution = kADC_Resolution12bit;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL
config->enableBypassCalibration = false;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP
config->sampleTimeNumber = 0U;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE
config->enableLowPowerMode = false;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */
#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG
config->voltageRange = kADC_HighVoltageRange;
#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
}
/*!
* brief Deinitialize 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 */
}
#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) & FSL_FEATURE_ADC_HAS_CALIB_REG
/*!
* brief Do the self calibration. To calibrate the ADC, set the ADC clock to 1 mHz.
* In order to achieve the specified ADC accuracy, the A/D converter must be recalibrated, at a minimum,
* following every chip reset before initiating normal ADC operation.
*
* param base ADC peripheral base address.
* retval true Calibration succeed.
* retval false Calibration failed.
*/
bool ADC_DoSelfCalibration(ADC_Type *base)
{
uint32_t i;
uint32_t frequency = 0U;
uint32_t delayUs = 0U;
/* Enable the converter. */
/* This bit acn only be set 1 by software. It is cleared automatically whenever the ADC is powered down.
This bit should be set after at least 10 ms after the ADC is powered on. */
base->STARTUP = ADC_STARTUP_ADC_ENA_MASK;
for (i = 0U; i < 0x10; i++) /* Wait a few clocks to startup up. */
{
__ASM("NOP");
}
SDK_DelayAtLeastUs(1U);
if (!(base->STARTUP & ADC_STARTUP_ADC_ENA_MASK))
{
return false; /* ADC is not powered up. */
}
/* Get the ADC clock frequency in synchronous mode. */
frequency = CLOCK_GetFreq(kCLOCK_BusClk) / (((base->CTRL & ADC_CTRL_CLKDIV_MASK) >> ADC_CTRL_CLKDIV_SHIFT) + 1);
base->CTRL |= ADC_CTRL_CLKDIV((frequency / 1000000U) - 1U);
frequency = 1000000U;
#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) && FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
/* Get the ADC clock frequency in asynchronous mode. */
if (ADC_CTRL_ASYNMODE_MASK == (base->CTRL & ADC_CTRL_ASYNMODE_MASK))
{
frequency = CLOCK_GetAdcClkFreq();
}
#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE */
assert(0U != frequency);
/* If not in by-pass mode, do the calibration. */
if ((ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) &&
(0U == (base->CTRL & ADC_CTRL_BYPASSCAL_MASK)))
{
/* A calibration cycle requires approximately 81 ADC clocks to complete. */
delayUs = (120 * FREQUENCY_1MHZ) / frequency + 1;
/* Calibration is needed, do it now. */
base->CALIB = ADC_CALIB_CALIB_MASK;
i = 0xF0000;
while ((ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK)) && (--i))
{
}
if (i == 0U)
SDK_DelayAtLeastUs(delayUs);
if (ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK))
{
return false; /* Calibration timeout. */
}
}
/* A dummy conversion cycle will be performed. */
/* A “dummy” conversion cycle requires approximately 6 ADC clocks */
delayUs = (10 * FREQUENCY_1MHZ) / frequency + 1;
base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK;
i = 0x7FFFF;
while ((ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK)) && (--i))
{
}
if (i == 0U)
SDK_DelayAtLeastUs(delayUs);
if (ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK))
{
return false;
}
return true;
}
#else
/*!
* brief Do the self calibration. To calibrate the ADC, set the ADC clock to 1 mHz.
* In order to achieve the specified ADC accuracy, the A/D converter must be recalibrated, at a minimum,
* following every chip reset before initiating normal ADC operation.
*
* param base ADC peripheral base address.
* param frequency The ststem clock frequency to ADC.
* retval true Calibration succeed.
* retval false Calibration failed.
*/
bool ADC_DoSelfCalibration(ADC_Type *base, uint32_t frequency)
{
uint32_t tmp32;
/* Store the current contents of the ADC CTRL register. */
tmp32 = base->CTRL;
/* Start ADC self-calibration. */
base->CTRL |= ADC_CTRL_CALMODE_MASK;
/* Divide the system clock to yield an ADC clock of about 1 mHz. */
base->CTRL &= ~ADC_CTRL_CLKDIV_MASK;
base->CTRL |= ADC_CTRL_CLKDIV((frequency / 1000000U) - 1U);
/* Clear the LPWR bit. */
base->CTRL &= ~ADC_CTRL_LPWRMODE_MASK;
/* Delay for 120 uSec @ 1 mHz ADC clock */
SDK_DelayAtLeastUs(120U);
/* Check the completion of calibration. */
if (ADC_CTRL_CALMODE_MASK == (base->CTRL & ADC_CTRL_CALMODE_MASK))
{
/* Restore the contents of the ADC CTRL register. */
base->CTRL = tmp32;
return false; /* Calibration timeout. */
}
/* Restore the contents of the ADC CTRL register. */
base->CTRL = tmp32;
return true;
}
#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC*/
/*!
* brief Configure the conversion sequence A.
*
* param base ADC peripheral base address.
* param config Pointer to configuration structure, see to #adc_conv_seq_config_t.
*/
void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
{
assert(config != NULL);
@ -198,6 +346,12 @@ void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
base->SEQ_CTRL[0] = tmp32;
}
/*!
* brief Configure the conversion sequence B.
*
* param base ADC peripheral base address.
* param config Pointer to configuration structure, see to #adc_conv_seq_config_t.
*/
void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
{
assert(config != NULL);
@ -242,6 +396,14 @@ void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config)
base->SEQ_CTRL[1] = tmp32;
}
/*!
* brief Get the global ADC conversion infomation of sequence A.
*
* param base ADC peripheral base address.
* param info Pointer to information structure, see to #adc_result_info_t;
* retval true The conversion result is ready.
* retval false The conversion result is not ready yet.
*/
bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
{
assert(info != NULL);
@ -264,6 +426,14 @@ bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *in
return true;
}
/*!
* brief Get the global ADC conversion infomation of sequence B.
*
* param base ADC peripheral base address.
* param info Pointer to information structure, see to #adc_result_info_t;
* retval true The conversion result is ready.
* retval false The conversion result is not ready yet.
*/
bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info)
{
assert(info != NULL);
@ -286,6 +456,15 @@ bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *in
return true;
}
/*!
* brief Get the channel's ADC conversion completed under each conversion sequence.
*
* param base ADC peripheral base address.
* param channel The indicated channel number.
* param info Pointer to information structure, see to #adc_result_info_t;
* retval true The conversion result is ready.
* retval false The conversion result is not ready yet.
*/
bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info)
{
assert(info != NULL);
@ -299,6 +478,22 @@ bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result
}
info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT;
#if (defined(FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) && FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT)
switch ((base->CTRL & ADC_CTRL_RESOL_MASK) >> ADC_CTRL_RESOL_SHIFT)
{
case kADC_Resolution10bit:
info->result >>= kADC_Resolution10bitInfoResultShift;
break;
case kADC_Resolution8bit:
info->result >>= kADC_Resolution8bitInfoResultShift;
break;
case kADC_Resolution6bit:
info->result >>= kADC_Resolution6bitInfoResultShift;
break;
default:
break;
}
#endif
info->thresholdCompareStatus =
(adc_threshold_compare_status_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT);
info->thresholdCorssingStatus =
@ -308,3 +503,26 @@ bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result
return true;
}
#if defined(FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) && (FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP)
void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable)
{
if (enable)
{
SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE_MASK;
ASYNC_SYSCON->TEMPSENSORCTRL = kADC_NoOffsetAdded;
ASYNC_SYSCON->TEMPSENSORCTRL |= ASYNC_SYSCON_TEMPSENSORCTRL_ENABLE_MASK;
base->GPADC_CTRL0 |= (kADC_ADCInUnityGainMode | kADC_Impedance87kOhm);
}
else
{
/* if the temperature sensor is not turned on then ASYNCAPBCTRL is likely to be zero
* and accessing the registers will cause a memory access error. Test for this */
if (SYSCON->ASYNCAPBCTRL == SYSCON_ASYNCAPBCTRL_ENABLE_MASK)
{
ASYNC_SYSCON->TEMPSENSORCTRL = 0x0;
base->GPADC_CTRL0 &= ~(kADC_ADCInUnityGainMode | kADC_Impedance87kOhm);
base->GPADC_CTRL0 |= kADC_Impedance55kOhm;
}
}
}
#endif

View File

@ -1,31 +1,9 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __FSL_ADC_H__
@ -46,13 +24,14 @@
/*! @name Driver version */
/*@{*/
/*! @brief ADC driver version 1.0.0. */
#define LPC_ADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
/*! @brief ADC driver version 2.3.1. */
#define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 3, 1))
/*@}*/
/*!
* @brief Flags
*/
enum _adc_status_flags
{
kADC_ThresholdCompareFlagOnChn0 = 1U << 0U, /*!< Threshold comparison event on Channel 0. */
@ -96,7 +75,7 @@ enum _adc_status_flags
kADC_ConvSeqAInterruptFlag = 1U << 28U, /*!< Sequence A interrupt/DMA trigger. */
kADC_ConvSeqBInterruptFlag = 1U << 29U, /*!< Sequence B interrupt/DMA trigger. */
kADC_ThresholdCompareInterruptFlag = 1U << 30U, /*!< Threshold comparision interrupt flag. */
kADC_OverrunInterruptFlag = 1U << 31U, /*!< Overrun interrupt flag. */
kADC_OverrunInterruptFlag = (int)(1U << 31U), /*!< Overrun interrupt flag. */
};
/*!
@ -114,6 +93,7 @@ enum _adc_interrupt_enable
interrupt/DMA trigger. */
};
#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
/*!
* @brief Define selection of clock mode.
*/
@ -123,7 +103,22 @@ typedef enum _adc_clock_mode
0U, /*!< The ADC clock would be derived from the system clock based on "clockDividerNumber". */
kADC_ClockAsynchronousMode = 1U, /*!< The ADC clock would be based on the SYSCON block's divider. */
} adc_clock_mode_t;
#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
#if defined(FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT) && (FSL_FEATURE_ADC_DAT_OF_HIGH_ALIGNMENT)
/*!
* @brief Define selection of resolution.
*/
typedef enum _adc_resolution
{
kADC_Resolution6bit = 3U,
/*!< 6-bit resolution. */ /* This is a HW issue that the ADC resolution enum configure not align with HW implement,
ES2 chip already fixed the issue, Currently, update ADC enum define as a workaround */
kADC_Resolution8bit = 2U, /*!< 8-bit resolution. */
kADC_Resolution10bit = 1U, /*!< 10-bit resolution. */
kADC_Resolution12bit = 0U, /*!< 12-bit resolution. */
} adc_resolution_t;
#elif defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
/*!
* @brief Define selection of resolution.
*/
@ -134,6 +129,18 @@ typedef enum _adc_resolution
kADC_Resolution10bit = 2U, /*!< 10-bit resolution. */
kADC_Resolution12bit = 3U, /*!< 12-bit resolution. */
} adc_resolution_t;
#endif
#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG
/*!
* @brief Definfe range of the analog supply voltage VDDA.
*/
typedef enum _adc_voltage_range
{
kADC_HighVoltageRange = 0U, /* High voltage. VDD = 2.7 V to 3.6 V. */
kADC_LowVoltageRange = 1U, /* Low voltage. VDD = 2.4 V to 2.7 V. */
} adc_vdda_range_t;
#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
/*!
* @brief Define selection of polarity of selected input trigger for conversion sequence.
@ -150,7 +157,7 @@ typedef enum _adc_trigger_polarity
typedef enum _adc_priority
{
kADC_PriorityLow = 0U, /*!< This sequence would be preempted when another sequence is started. */
kADC_PriorityHigh = 1U, /*!< This sequence would preempt other sequence even when is is started. */
kADC_PriorityHigh = 1U, /*!< This sequence would preempt other sequence even when it is started. */
} adc_priority_t;
/*!
@ -204,22 +211,79 @@ typedef enum _adc_threshold_interrupt_mode
kADC_ThresholdInterruptOnCrossing = 2U, /*!< Threshold comparison interrupt is enabled on crossing threshold. */
} adc_threshold_interrupt_mode_t;
/*!
* @brief Define the info result mode of different resolution.
*/
typedef enum _adc_inforesultshift
{
kADC_Resolution12bitInfoResultShift = 0U, /*!< Info result shift of Resolution12bit. */
kADC_Resolution10bitInfoResultShift = 2U, /*!< Info result shift of Resolution10bit. */
kADC_Resolution8bitInfoResultShift = 4U, /*!< Info result shift of Resolution8bit. */
kADC_Resolution6bitInfoResultShift = 6U, /*!< Info result shift of Resolution6bit. */
} adc_inforesult_t;
/*!
* @brief Define common modes for Temerature sensor.
*/
typedef enum _adc_tempsensor_common_mode
{
kADC_HighNegativeOffsetAdded = 0x0U, /*!< Temerature sensor common mode: high negative offset added. */
kADC_IntermediateNegativeOffsetAdded =
0x4U, /*!< Temerature sensor common mode: intermediate negative offset added. */
kADC_NoOffsetAdded = 0x8U, /*!< Temerature sensor common mode: no offset added. */
kADC_LowPositiveOffsetAdded = 0xcU, /*!< Temerature sensor common mode: low positive offset added. */
} adc_tempsensor_common_mode_t;
/*!
* @brief Define source impedance modes for GPADC control.
*/
typedef enum _adc_second_control
{
kADC_Impedance621Ohm = 0x1U << 9U, /*!< Extand ADC sampling time according to source impedance 1: 0.621 kOhm. */
kADC_Impedance55kOhm =
0x14U << 9U, /*!< Extand ADC sampling time according to source impedance 20 (default): 55 kOhm. */
kADC_Impedance87kOhm = 0x1fU << 9U, /*!< Extand ADC sampling time according to source impedance 31: 87 kOhm. */
kADC_NormalFunctionalMode = 0x0U << 14U, /*!< TEST mode: Normal functional mode. */
kADC_MultiplexeTestMode = 0x1U << 14U, /*!< TEST mode: Multiplexer test mode. */
kADC_ADCInUnityGainMode = 0x2U << 14U, /*!< TEST mode: ADC in unity gain mode. */
} adc_second_control_t;
/*!
* @brief Define structure for configuring the block.
*/
typedef struct _adc_config
{
#if defined(FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE) & FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE
adc_clock_mode_t clockMode; /*!< Select the clock mode for ADC converter. */
#endif /* FSL_FEATURE_ADC_HAS_CTRL_ASYNMODE. */
uint32_t clockDividerNumber; /*!< This field is only available when using kADC_ClockSynchronousMode for "clockMode"
field. The divider would be plused by 1 based on the value in this field. The
available range is in 8 bits. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_RESOL) & FSL_FEATURE_ADC_HAS_CTRL_RESOL
adc_resolution_t resolution; /*!< Select the conversion bits. */
#endif /* FSL_FEATURE_ADC_HAS_CTRL_RESOL. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL) & FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL
bool enableBypassCalibration; /*!< By default, a calibration cycle must be performed each time the chip is
powered-up. Re-calibration may be warranted periodically - especially if
operating conditions have changed. To enable this option would avoid the need to
calibrate if offset error is not a concern in the application. */
#endif /* FSL_FEATURE_ADC_HAS_CTRL_BYPASSCAL. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_TSAMP) & FSL_FEATURE_ADC_HAS_CTRL_TSAMP
uint32_t sampleTimeNumber; /*!< By default, with value as "0U", the sample period would be 2.5 ADC clocks. Then,
to plus the "sampleTimeNumber" value here. The available value range is in 3 bits.*/
#endif /* FSL_FEATURE_ADC_HAS_CTRL_TSAMP. */
#if defined(FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE) & FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE
bool enableLowPowerMode; /*!< If disable low-power mode, ADC remains activated even when no conversions are
requested.
If enable low-power mode, The ADC is automatically powered-down when no conversions are
taking place. */
#endif /* FSL_FEATURE_ADC_HAS_CTRL_LPWRMODE. */
#if defined(FSL_FEATURE_ADC_HAS_TRIM_REG) & FSL_FEATURE_ADC_HAS_TRIM_REG
adc_vdda_range_t
voltageRange; /*!< Configure the ADC for the appropriate operating range of the analog supply voltage VDDA.
Failure to set the area correctly causes the ADC to return incorrect conversion results. */
#endif /* FSL_FEATURE_ADC_HAS_TRIM_REG. */
} adc_config_t;
/*!
@ -247,7 +311,7 @@ typedef struct _adc_conv_seq_config
*/
typedef struct _adc_result_info
{
uint32_t result; /*!< Keey the conversion data value. */
uint32_t result; /*!< Keep the conversion data value. */
adc_threshold_compare_status_t thresholdCompareStatus; /*!< Keep the threshold compare status. */
adc_threshold_crossing_status_t thresholdCorssingStatus; /*!< Keep the threshold crossing status. */
uint32_t channelNumber; /*!< Keep the channel number for this conversion. */
@ -298,6 +362,8 @@ void ADC_Deinit(ADC_Type *base);
*/
void ADC_GetDefaultConfig(adc_config_t *config);
#if !(defined(FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC) && FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC)
#if defined(FSL_FEATURE_ADC_HAS_CALIB_REG) && FSL_FEATURE_ADC_HAS_CALIB_REG
/*!
* @brief Do the self hardware calibration.
*
@ -306,7 +372,22 @@ void ADC_GetDefaultConfig(adc_config_t *config);
* @retval false Calibration failed.
*/
bool ADC_DoSelfCalibration(ADC_Type *base);
#else
/*!
* @brief Do the self calibration. To calibrate the ADC, set the ADC clock to 500 kHz.
* In order to achieve the specified ADC accuracy, the A/D converter must be recalibrated, at a minimum,
* following every chip reset before initiating normal ADC operation.
*
* @param base ADC peripheral base address.
* @param frequency The ststem clock frequency to ADC.
* @retval true Calibration succeed.
* @retval false Calibration failed.
*/
bool ADC_DoSelfCalibration(ADC_Type *base, uint32_t frequency);
#endif /* FSL_FEATURE_ADC_HAS_CALIB_REG */
#endif /* FSL_FEATURE_ADC_HAS_NO_CALIB_FUNC */
#if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL)
/*!
* @brief Enable the internal temperature sensor measurement.
*
@ -316,6 +397,9 @@ bool ADC_DoSelfCalibration(ADC_Type *base);
* @param base ADC peripheral base address.
* @param enable Switcher to enable the feature or not.
*/
#if defined(FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP) && (FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP)
void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable);
#else
static inline void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable)
{
if (enable)
@ -327,8 +411,9 @@ static inline void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable)
base->INSEL = (base->INSEL & ~ADC_INSEL_SEL_MASK) | ADC_INSEL_SEL(0);
}
}
/* @} */
#endif /* FSL_FEATURE_ADC_ASYNC_SYSCON_TEMP. */
#endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */
/* @} */
/*!
* @name Control conversion sequence A.
@ -611,13 +696,24 @@ static inline void ADC_DisableInterrupts(ADC_Type *base, uint32_t mask)
}
/*!
* @brief Enable the interrupt of shreshold compare event for each channel.
* @brief Enable the interrupt of threshold compare event for each channel.
* @deprecated Do not use this function. It has been superceded by @ADC_EnableThresholdCompareInterrupt
*/
static inline void ADC_EnableShresholdCompareInterrupt(ADC_Type *base,
uint32_t channel,
adc_threshold_interrupt_mode_t mode)
{
base->INTEN = (base->INTEN & ~(0x3U << ((channel << 1U) + 3U))) | ((uint32_t)(mode) << ((channel << 1U) + 3U));
}
/*!
* @brief Enable the interrupt of threshold compare event for each channel.
*
* @param base ADC peripheral base address.
* @param channel Channel number.
* @param mode Interrupt mode for threshold compare event, see to #adc_threshold_interrupt_mode_t.
*/
static inline void ADC_EnableShresholdCompareInterrupt(ADC_Type *base,
static inline void ADC_EnableThresholdCompareInterrupt(ADC_Type *base,
uint32_t channel,
adc_threshold_interrupt_mode_t mode)
{

View File

@ -1,40 +1,16 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2019 , NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_CLOCK_H_
#define _FSL_CLOCK_H_
#include "fsl_device_registers.h"
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include "fsl_common.h"
/*! @addtogroup clock */
/*! @{ */
@ -44,11 +20,34 @@
/*******************************************************************************
* Definitions
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief CLOCK driver version 2.2.0. */
#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 2, 0))
/*@}*/
/*!
* @brief User-defined the size of cache for CLOCK_PllGetConfig() function.
*
* Once define this MACRO to be non-zero value, CLOCK_PllGetConfig() function
* would cache the recent calulation and accelerate the execution to get the
* right settings.
*/
#ifndef CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT
#define CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT 2U
#endif
/* Definition for delay API in clock driver, users can redefine it to the real application. */
#ifndef SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY
#define SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY (96000000UL)
#endif
/*! @brief Clock ip name array for FLEXCOMM. */
#define FLEXCOMM_CLOCKS \
{ \
kCLOCK_FlexComm0, kCLOCK_FlexComm1, kCLOCK_FlexComm2, kCLOCK_FlexComm3, \
kCLOCK_FlexComm4, kCLOCK_FlexComm5, kCLOCK_FlexComm6, kCLOCK_FlexComm7 \
kCLOCK_FlexComm0, kCLOCK_FlexComm1, kCLOCK_FlexComm2, kCLOCK_FlexComm3, kCLOCK_FlexComm4, kCLOCK_FlexComm5, \
kCLOCK_FlexComm6, kCLOCK_FlexComm7 \
}
/*! @brief Clock ip name array for LPUART. */
#define LPUART_CLOCKS \
@ -254,7 +253,7 @@ typedef enum _clock_name
kCLOCK_ExtClk, /*!< External Clock */
kCLOCK_PllOut, /*!< PLL Output */
kCLOCK_UsbClk, /*!< USB input */
kClock_WdtOsc, /*!< Watchdog Oscillator */
kCLOCK_WdtOsc, /*!< Watchdog Oscillator */
kCLOCK_Frg, /*!< Frg Clock */
kCLOCK_Dmic, /*!< Digital Mic clock */
kCLOCK_AsyncApbClk, /*!< Async APB clock */
@ -279,18 +278,22 @@ typedef enum _async_clock_src
} async_clock_src_t;
/*! @brief Clock Mux Switches
* The encoding is as follows each connection identified is 64bits wide
* starting from LSB upwards
*
* [4 bits for choice, where 1 is A, 2 is B, 3 is C and 4 is D, 0 means end of descriptor] [8 bits mux ID]*
*
*/
* The encoding is as follows each connection identified is 32bits wide while 24bits are valuable
* starting from LSB upwards
*
* [4 bits for choice, 0 means invalid choice] [8 bits mux ID]*
*
*/
#define MUX_A(m, choice) (((m) << 0) | ((choice + 1) << 8))
#define MUX_B(m, choice) (((m) << 12) | ((choice + 1) << 20))
#define MUX_C(m, choice) (((m) << 24) | ((choice + 1) << 32))
#define MUX_D(m, choice) (((m) << 36) | ((choice + 1) << 44))
#define MUX_E(m, choice) (((m) << 48) | ((choice + 1) << 56))
#define CLK_ATTACH_ID(mux, sel, pos) (((mux << 0U) | ((sel + 1) & 0xFU) << 8U) << (pos * 12U))
#define MUX_A(mux, sel) CLK_ATTACH_ID(mux, sel, 0U)
#define MUX_B(mux, sel, selector) (CLK_ATTACH_ID(mux, sel, 1U) | (selector << 24U))
#define GET_ID_ITEM(connection) ((connection)&0xFFFU)
#define GET_ID_NEXT_ITEM(connection) ((connection) >> 12U)
#define GET_ID_ITEM_MUX(connection) ((connection)&0xFFU)
#define GET_ID_ITEM_SEL(connection) ((((connection)&0xF00U) >> 8U) - 1U)
#define GET_ID_SELECTOR(connection) ((connection)&0xF000000U)
#define CM_MAINCLKSELA 0
#define CM_MAINCLKSELB 1
@ -326,12 +329,12 @@ typedef enum _async_clock_src
typedef enum _clock_attach_id
{
kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0),
kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0),
kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0),
kFRO_HF_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 3) | MUX_B(CM_MAINCLKSELB, 0),
kSYS_PLL_to_MAIN_CLK = MUX_A(CM_MAINCLKSELB, 2),
kOSC32K_to_MAIN_CLK = MUX_A(CM_MAINCLKSELB, 3),
kFRO12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0, 0),
kEXT_CLK_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0, 0),
kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0, 0),
kFRO_HF_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 3) | MUX_B(CM_MAINCLKSELB, 0, 0),
kSYS_PLL_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 2, 0),
kOSC32K_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 3, 0),
kFRO12M_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 0),
kEXT_CLK_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 1),
@ -416,6 +419,7 @@ typedef enum _clock_attach_id
kFRO_HF_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 0),
kSYS_PLL_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 1),
kMAIN_CLK_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 2),
kNONE_to_MCLK = MUX_A(CM_FXI2S0MCLKCLKSEL, 7),
kFRO12M_to_DMIC = MUX_A(CM_DMICCLKSEL, 0),
@ -428,6 +432,7 @@ typedef enum _clock_attach_id
kFRO_HF_to_USB_CLK = MUX_A(CM_USBCLKSEL, 0),
kSYS_PLL_to_USB_CLK = MUX_A(CM_USBCLKSEL, 1),
kMAIN_CLK_to_USB_CLK = MUX_A(CM_USBCLKSEL, 2),
kNONE_to_USB_CLK = MUX_A(CM_USBCLKSEL, 7),
kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 0),
@ -438,7 +443,7 @@ typedef enum _clock_attach_id
kFRO12M_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 5),
kOSC32K_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 6),
kNONE_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 7),
kNONE_to_NONE = 0x80000000U,
kNONE_to_NONE = (int)0x80000000U,
} clock_attach_id_t;
/* Clock dividers */
@ -500,8 +505,6 @@ typedef enum _clock_flashtim
kCLOCK_Flash4Cycle, /*!< Flash accesses use 4 CPU clocks */
kCLOCK_Flash5Cycle, /*!< Flash accesses use 5 CPU clocks */
kCLOCK_Flash6Cycle, /*!< Flash accesses use 6 CPU clocks */
kCLOCK_Flash7Cycle, /*!< Flash accesses use 7 CPU clocks */
kCLOCK_Flash8Cycle /*!< Flash accesses use 8 CPU clocks */
} clock_flashtim_t;
/**
@ -533,6 +536,14 @@ status_t CLOCK_SetupFROClocking(uint32_t iFreq);
* @return Nothing
*/
void CLOCK_AttachClk(clock_attach_id_t connection);
/**
* @brief Get the actual clock attach id.
* This fuction uses the offset in input attach id, then it reads the actual source value in
* the register and combine the offset to obtain an actual attach id.
* @param attachId : Clock attach id to get.
* @return Clock source value.
*/
clock_attach_id_t CLOCK_GetClockAttachId(clock_attach_id_t attachId);
/**
* @brief Setup peripheral clock dividers.
* @param div_name : Clock divider name
@ -557,6 +568,16 @@ uint32_t CLOCK_GetFreq(clock_name_t clockName);
*/
uint32_t CLOCK_GetFRGInputClock(void);
/*! @brief Return Input frequency for the DMIC
* @return Input Frequency for DMIC
*/
uint32_t CLOCK_GetDmicClkFreq(void);
/*! @brief Return Input frequency for the FRG
* @return Input Frequency for FRG
*/
uint32_t CLOCK_GetFrgClkFreq(void);
/*! @brief Set output of the Fractional baud rate generator
* @param freq : Desired output frequency
* @return Error Code 0 - fail 1 - success
@ -579,6 +600,10 @@ uint32_t CLOCK_GetWdtOscFreq(void);
* @return Frequency of High-Freq output of FRO
*/
uint32_t CLOCK_GetFroHfFreq(void);
/*! @brief Return Frequency of USB
* @return Frequency of USB
*/
uint32_t CLOCK_GetUsbClkFreq(void);
/*! @brief Return Frequency of PLL
* @return Frequency of PLL
*/
@ -599,6 +624,10 @@ uint32_t CLOCK_GetI2SMClkFreq(void);
* @return Frequency of Flexcomm functional Clock
*/
uint32_t CLOCK_GetFlexCommClkFreq(uint32_t id);
/*! @brief Return Frequency of Adc Clock
* @return Frequency of Adc Clock.
*/
uint32_t CLOCK_GetAdcClkFreq(void);
/*! @brief Return Asynchronous APB Clock source
* @return Asynchronous APB CLock source
*/
@ -670,11 +699,13 @@ void CLOCK_SetStoredPLLClockRate(uint32_t rate);
*/
#define PLL_CONFIGFLAG_USEINRATE (1 << 0) /*!< Flag to use InputRate in PLL configuration structure for setup */
#define PLL_CONFIGFLAG_FORCENOFRACT \
(1 \
<< 2) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or SS \ \
\ \ \ \
\ \ \ \ \ \
\ \ \ \ \ \ \ \
(1 << 2) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or SS \
\ \ \
\ \ \ \ \
\ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \
\ \ \ \ \ \ \ \ \ \ \ \ \
hardware */
/*! @brief PLL Spread Spectrum (SS) Programmable modulation frequency
@ -742,19 +773,20 @@ typedef struct _pll_config
} pll_config_t;
/*! @brief PLL setup structure flags for 'flags' field
* These flags control how the PLL setup function sets up the PLL
*/
* These flags control how the PLL setup function sets up the PLL
*/
#define PLL_SETUPFLAG_POWERUP (1 << 0) /*!< Setup will power on the PLL after setup */
#define PLL_SETUPFLAG_WAITLOCK (1 << 1) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */
#define PLL_SETUPFLAG_ADGVOLT (1 << 2) /*!< Optimize system voltage for the new PLL rate */
#define PLL_SETUPFLAG_USEFEEDBACKDIV2 (1 << 3) /*!< Use feedback divider by 2 in divider path */
/*! @brief PLL setup structure
* This structure can be used to pre-build a PLL setup configuration
* at run-time and quickly set the PLL to the configuration. It can be
* populated with the PLL setup function. If powering up or waiting
* for PLL lock, the PLL input clock source should be configured prior
* to PLL setup.
*/
* This structure can be used to pre-build a PLL setup configuration
* at run-time and quickly set the PLL to the configuration. It can be
* populated with the PLL setup function. If powering up or waiting
* for PLL lock, the PLL input clock source should be configured prior
* to PLL setup.
*/
typedef struct _pll_setup
{
uint32_t syspllctrl; /*!< PLL control register SYSPLLCTRL */
@ -804,7 +836,7 @@ pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup);
/*! @brief Set PLL output from PLL setup structure (precise frequency)
* @param pSetup : Pointer to populated PLL setup structure
* @param flagcfg : Flag configuration for PLL config structure
* @param flagcfg : Flag configuration for PLL config structure
* @return PLL_ERROR_SUCCESS on success, or PLL setup error code
* @note This function will power off the PLL, setup the PLL with the
* new setup data, and then optionally powerup the PLL, wait for PLL lock,
@ -848,6 +880,17 @@ static inline void CLOCK_DisableUsbfs0Clock(void)
CLOCK_DisableClock(kCLOCK_Usbd0);
}
bool CLOCK_EnableUsbfs0Clock(clock_usb_src_t src, uint32_t freq);
/*!
* @brief Use DWT to delay at least for some time.
* Please note that, this API will calculate the microsecond period with the maximum
* supported CPU frequency, so this API will only delay for at least the given microseconds, if precise
* delay count was needed, please implement a new timer count to achieve this function.
*
* @param delay_us Delay time in unit of microsecond.
*/
void SDK_DelayAtLeastUs(uint32_t delay_us);
#if defined(__cplusplus)
}
#endif /* __cplusplus */