MCUXpresso: Update Analogin support

Signed-off-by: Mahesh Mahadevan <mahesh.mahadevan@nxp.com>
pull/9910/head
Mahesh Mahadevan 2019-01-16 10:01:16 -06:00
parent 616fa49890
commit 2e9bb17596
7 changed files with 208 additions and 19 deletions

View File

@ -16,7 +16,7 @@
#include "mbed_assert.h" #include "mbed_assert.h"
#include "analogin_api.h" #include "analogin_api.h"
#if DEVICE_ANALOGIN #if DEVICE_ANALOGIN && !defined(NXP_LPADC)
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"

View File

@ -0,0 +1,148 @@
/* mbed Microcontroller Library
* Copyright (c) 2006-2013 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "mbed_assert.h"
#include "analogin_api.h"
#if DEVICE_ANALOGIN && defined(NXP_LPADC)
#include "cmsis.h"
#include "pinmap.h"
#include "gpio_api.h"
#include "PeripheralNames.h"
#include "fsl_lpadc.h"
#include "fsl_power.h"
#include "PeripheralPins.h"
/* Array of ADC peripheral base address. */
static ADC_Type *const adc_addrs[] = ADC_BASE_PTRS;
extern void ADC_ClockPower_Configuration(void);
#define LPADC_USER_CMDID 1U /* CMD1 */
void analogin_init(analogin_t *obj, PinName pin)
{
gpio_t gpio;
obj->adc = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
MBED_ASSERT(obj->adc != (ADCName)NC);
uint32_t instance = obj->adc >> ADC_INSTANCE_SHIFT;
lpadc_config_t adc_config;
uint32_t reg;
uint32_t pin_number = pin & 0x1F;
uint8_t port_number = pin / 32;
ADC_ClockPower_Configuration();
LPADC_GetDefaultConfig(&adc_config);
adc_config.enableAnalogPreliminary = true;
#if defined(LPADC_VREF_SOURCE)
adc_config.referenceVoltageSource = LPADC_VREF_SOURCE;
#endif
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS
adc_config.conversionAverageMode = kLPADC_ConversionAverage128;
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */
LPADC_Init(adc_addrs[instance], &adc_config);
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
/* Request offset calibration. */
if (true == LPADC_DO_OFFSET_CALIBRATION) {
LPADC_DoOffsetCalibration(adc_addrs[instance]);
} else {
LPADC_SetOffsetValue(adc_addrs[instance], LPADC_OFFSET_VALUE_A, LPADC_OFFSET_VALUE_B);
}
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
/* Request gain calibration. */
LPADC_DoAutoCalibration(adc_addrs[instance]);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */
#if (defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS)
/* Do auto calibration. */
LPADC_DoAutoCalibration(adc_addrs[instance]);
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
pinmap_pinout(pin, PinMap_ADC);
reg = IOCON->PIO[port_number][pin_number];
/* Clear the DIGIMODE bit */
reg &= ~IOCON_PIO_DIGIMODE_MASK;
/* For pins PIO0_9, PIO0_11, PIO0_12, PIO0_15, PIO0_18, PIO0_31, PIO1_0 and
PIO1_9, leave ASW bit at '0' in the related IOCON register. */
if (((port_number == 0) && ((pin_number == 9) || (pin_number == 11) || (pin_number == 12) ||
(pin_number == 15) || (pin_number == 18) || (pin_number == 31))) ||
((port_number == 1) && ((pin_number == 0) || (pin_number == 9)))) {
/* Disable Analog Switch Input control */
reg &= ~IOCON_PIO_ASW_MASK;
} else {
/* Enable Analog Switch Input control */
reg |= IOCON_PIO_ASW_MASK;
}
IOCON->PIO[port_number][pin_number] = reg;
/* Need to ensure the pin is in input mode */
gpio_init(&gpio, pin);
gpio_dir(&gpio, PIN_INPUT);
}
uint16_t analogin_read_u16(analogin_t *obj)
{
uint32_t instance = obj->adc >> ADC_INSTANCE_SHIFT;
uint32_t channel = obj->adc & 0xF;
lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
lpadc_conv_command_config_t mLpadcCommandConfigStruct;
lpadc_conv_result_t mLpadcResultConfigStruct;
memset(&mLpadcTriggerConfigStruct, 0, sizeof(mLpadcTriggerConfigStruct));
memset(&mLpadcCommandConfigStruct, 0, sizeof(mLpadcCommandConfigStruct));
memset(&mLpadcResultConfigStruct, 0, sizeof(mLpadcResultConfigStruct));
/* Set conversion CMD configuration. */
LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
mLpadcCommandConfigStruct.channelNumber = channel;
LPADC_SetConvCommandConfig(adc_addrs[instance], LPADC_USER_CMDID, &mLpadcCommandConfigStruct);
/* Set trigger configuration. */
LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
mLpadcTriggerConfigStruct.targetCommandId = LPADC_USER_CMDID;
mLpadcTriggerConfigStruct.enableHardwareTrigger = false;
LPADC_SetConvTriggerConfig(adc_addrs[instance], 0U, &mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
LPADC_DoSoftwareTrigger(adc_addrs[instance], 1U); /* 1U is trigger0 mask. */
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
while (!LPADC_GetConvResult(adc_addrs[instance], &mLpadcResultConfigStruct, 0U)) {
}
#else
while (!LPADC_GetConvResult(adc_addrs[instance], &mLpadcResultConfigStruct)) {
}
#endif /* FSL_FEATURE_LPADC_FIFO_COUNT */
return ((mLpadcResultConfigStruct.convValue) >> 3U);
}
float analogin_read(analogin_t *obj)
{
uint16_t value = analogin_read_u16(obj);
return (float)value * (1.0f / (float)0xFFFF);
}
const PinMap *analogin_pinmap()
{
return PinMap_ADC;
}
#endif

View File

@ -20,6 +20,11 @@
#define NUMBER_OF_GPIO_INTS 8 #define NUMBER_OF_GPIO_INTS 8
#define LPADC_VREF_SOURCE kLPADC_ReferenceVoltageAlt2
#define LPADC_DO_OFFSET_CALIBRATION false
#define LPADC_OFFSET_VALUE_A 10U
#define LPADC_OFFSET_VALUE_B 10U
#define APP_EXCLUDE_FROM_DEEPSLEEP (kPDRUNCFG_PD_DCDC | kPDRUNCFG_PD_FRO192M | kPDRUNCFG_PD_FRO32K) #define APP_EXCLUDE_FROM_DEEPSLEEP (kPDRUNCFG_PD_DCDC | kPDRUNCFG_PD_FRO192M | kPDRUNCFG_PD_FRO32K)
/* Defines used by the sleep code */ /* Defines used by the sleep code */

View File

@ -36,16 +36,26 @@ void rtc_setup_oscillator(void)
uint32_t us_ticker_get_clock() uint32_t us_ticker_get_clock()
{ {
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
/* Use 12 MHz clock us ticker timer */ /* Use 96 MHz clock us ticker timer */
CLOCK_AttachClk(kFRO_HF_to_CTIMER0); CLOCK_AttachClk(kFRO_HF_to_CTIMER0);
return CLOCK_GetFreq(kCLOCK_CTmier0);; return CLOCK_GetFreq(kCLOCK_CTmier0);;
#else #else
/* Use 12 MHz clock us ticker timer */ /* Use 96 MHz clock us ticker timer */
CLOCK_AttachClk(kFRO_HF_to_CTIMER1); CLOCK_AttachClk(kFRO_HF_to_CTIMER1);
return CLOCK_GetFreq(kCLOCK_CTmier1);; return CLOCK_GetFreq(kCLOCK_CTmier1);;
#endif #endif
} }
void ADC_ClockPower_Configuration(void)
{
/* Set clock source for ADC0 */
CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 16U, true);
CLOCK_AttachClk(kMAIN_CLK_to_ADC_CLK);
/* Disable LDOGPADC power down */
POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC);
}
void sdio_clock_setup(void) void sdio_clock_setup(void)
{ {
/* Attach main clock to SDIF */ /* Attach main clock to SDIF */

View File

@ -554,6 +554,19 @@ void LPADC_DoAutoCalibration(ADC_Type *base)
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */ #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
/*!
* brief Do offset calibration.
*
* param base LPADC peripheral base address.
*/
void LPADC_DoOffsetCalibration(ADC_Type *base)
{
LPADC_EnableOffsetCalibration(base, true);
while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
{
}
}
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
/*! /*!
* brief Do auto calibration. * brief Do auto calibration.
@ -569,12 +582,6 @@ void LPADC_DoAutoCalibration(ADC_Type *base)
uint32_t GCRa; uint32_t GCRa;
uint32_t GCRb; uint32_t GCRb;
/* Request offset calibration. */
LPADC_EnableOffsetCalibration(base, true);
while (ADC_STAT_CAL_RDY_MASK != (base->STAT & ADC_STAT_CAL_RDY_MASK))
{
}
/* Request gain calibration. */ /* Request gain calibration. */
base->CTRL |= ADC_CTRL_CAL_REQ_MASK; base->CTRL |= ADC_CTRL_CAL_REQ_MASK;
while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK)) || while ((ADC_GCC_RDY_MASK != (base->GCC[0] & ADC_GCC_RDY_MASK)) ||

View File

@ -23,8 +23,8 @@
/*! @name Driver version */ /*! @name Driver version */
/*@{*/ /*@{*/
/*! @brief LPADC driver version 2.0.2. */ /*! @brief LPADC driver version 2.0.3. */
#define FSL_LPADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) #define FSL_LPADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 3))
/*@}*/ /*@}*/
/*! /*!
@ -750,9 +750,6 @@ void LPADC_GetDefaultConvCommandConfig(lpadc_conv_command_config_t *config);
* @bool enable switcher to the calibration function. * @bool enable switcher to the calibration function.
*/ */
void LPADC_EnableCalibration(ADC_Type *base, bool enable); void LPADC_EnableCalibration(ADC_Type *base, bool enable);
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
#if !(defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS)
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM #if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
/*! /*!
* @brief Set proper offset value to trim ADC. * @brief Set proper offset value to trim ADC.
@ -767,11 +764,7 @@ static inline void LPADC_SetOffsetValue(ADC_Type *base, uint32_t value)
{ {
base->OFSTRIM = (value & ADC_OFSTRIM_OFSTRIM_MASK) >> ADC_OFSTRIM_OFSTRIM_SHIFT; base->OFSTRIM = (value & ADC_OFSTRIM_OFSTRIM_MASK) >> ADC_OFSTRIM_OFSTRIM_SHIFT;
} }
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */
#if defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) && FSL_FEATURE_LPADC_HAS_CFG_CALOFS
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
/*! /*!
* @brief Do auto calibration. * @brief Do auto calibration.
* *
@ -789,6 +782,23 @@ void LPADC_DoAutoCalibration(ADC_Type *base);
#endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */ #endif /* FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS #if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS) && FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM) && FSL_FEATURE_LPADC_HAS_OFSTRIM
/*!
* @brief Set proper offset value to trim ADC.
*
* Set the offset trim value for offset calibration manually.
*
* @param base LPADC peripheral base address.
* @param valueA Setting offset value A.
* @param valueB Setting offset value B.
* @note In normal adc sequence, the values are automatically calculated by LPADC_EnableOffsetCalibration.
*/
static inline void LPADC_SetOffsetValue(ADC_Type *base, uint32_t valueA, uint32_t valueB)
{
base->OFSTRIM = ADC_OFSTRIM_OFSTRIM_A(valueA) | ADC_OFSTRIM_OFSTRIM_B(valueB);
}
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
/*! /*!
* @brief Enable the offset calibration function. * @brief Enable the offset calibration function.
* *
@ -807,14 +817,22 @@ static inline void LPADC_EnableOffsetCalibration(ADC_Type *base, bool enable)
} }
} }
/*!
* @brief Do offset calibration.
*
* @param base LPADC peripheral base address.
*/
void LPADC_DoOffsetCalibration(ADC_Type *base);
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ) && FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ
/*! /*!
* brief Do auto calibration. * brief Do auto calibration.
* *
* param base LPADC peripheral base address. * param base LPADC peripheral base address.
*/ */
void LPADC_DoAutoCalibration(ADC_Type *base); void LPADC_DoAutoCalibration(ADC_Type *base);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */ #endif /* FSL_FEATURE_LPADC_HAS_CTRL_CAL_REQ */
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */
/* @} */ /* @} */
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -2075,6 +2075,7 @@
"device_has_add": [ "device_has_add": [
"USTICKER", "USTICKER",
"RTC", "RTC",
"ANALOGIN",
"I2C", "I2C",
"I2CSLAVE", "I2CSLAVE",
"INTERRUPTIN", "INTERRUPTIN",