1740 lines
61 KiB
C
1740 lines
61 KiB
C
|
/*******************************************************************************
|
||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||
|
*
|
||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||
|
* (the "License"); You may not use this file except in compliance with the
|
||
|
* License. You may obtain a copy of the License at:
|
||
|
* opensource.org/licenses/BSD-3-Clause
|
||
|
*/
|
||
|
/******************************************************************************/
|
||
|
/** \file hc32f460_adc.c
|
||
|
**
|
||
|
** A detailed description is available at
|
||
|
** @link AdcGroup Adc description @endlink
|
||
|
**
|
||
|
** - 2018-11-30 CDT First version for Device Driver Library of Adc.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Include files
|
||
|
******************************************************************************/
|
||
|
#include "hc32f460_adc.h"
|
||
|
#include "hc32f460_utility.h"
|
||
|
|
||
|
#if (DDL_ADC_ENABLE == DDL_ON)
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \addtogroup AdcGroup
|
||
|
******************************************************************************/
|
||
|
//@{
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local type definitions ('typedef')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local pre-processor symbols/macros ('#define')
|
||
|
******************************************************************************/
|
||
|
/*! Parameter validity check for ADC peripherals. */
|
||
|
#define IS_ADC_PERIPH(ADCx) \
|
||
|
( ((ADCx) == M4_ADC1) || \
|
||
|
((ADCx) == M4_ADC2))
|
||
|
|
||
|
/*! Parameter validity check for ADC1 channel index. */
|
||
|
#define IS_ADC1_CH_INDEX(x) \
|
||
|
( ((x) < ADC1_CH_COUNT))
|
||
|
|
||
|
/*! Parameter validity check for ADC2 channel index. */
|
||
|
#define IS_ADC2_CH_INDEX(x) \
|
||
|
( ((x) < ADC2_CH_COUNT))
|
||
|
|
||
|
/*! Parameter validity check for ADC average count. */
|
||
|
#define IS_ADC_AVCNT(AVCNT) \
|
||
|
( ((AVCNT) == AdcAvcnt_2) || \
|
||
|
(((AVCNT) >= AdcAvcnt_4) && ((AVCNT) <= AdcAvcnt_256)))
|
||
|
|
||
|
/*! Parameter validity check for ADC data alignment. */
|
||
|
#define IS_ADC_DATA_ALIGN(ALIGN) \
|
||
|
( ((ALIGN) == AdcDataAlign_Right) || \
|
||
|
((ALIGN) == AdcDataAlign_Left))
|
||
|
|
||
|
/*! Parameter validity check for ADC auto clear DR. */
|
||
|
#define IS_ADC_CLREN(EN) \
|
||
|
( ((EN) == AdcClren_Enable) || \
|
||
|
((EN) == AdcClren_Disable))
|
||
|
|
||
|
/*! Parameter validity check for ADC resolution. */
|
||
|
#define IS_ADC_RESOLUTION(RESOLUTION) \
|
||
|
( ((RESOLUTION) == AdcResolution_8Bit) || \
|
||
|
((RESOLUTION) == AdcResolution_10Bit) || \
|
||
|
((RESOLUTION) == AdcResolution_12Bit))
|
||
|
|
||
|
/*! Parameter validity check for ADC scan convert mode. */
|
||
|
#define IS_ADC_SCAN_MODE(MODE) \
|
||
|
( ((MODE) == AdcMode_SAOnce) || \
|
||
|
((MODE) == AdcMode_SAContinuous) || \
|
||
|
((MODE) == AdcMode_SAOnceSBOnce) || \
|
||
|
((MODE) == AdcMode_SAContinuousSBOnce))
|
||
|
|
||
|
/*! Parameter validity check for ADC RSCHSEL. */
|
||
|
#define IS_ADC_RSCHSEL(SEL) \
|
||
|
( ((SEL) == AdcRschsel_Continue) || \
|
||
|
((SEL) == AdcRschsel_Restart))
|
||
|
|
||
|
/*! Parameter validity check for ADC SA trigger source. */
|
||
|
#define IS_ADC_TRGEN(EN) \
|
||
|
( ((EN) == AdcTrgen_Enable) || \
|
||
|
((EN) == AdcTrgen_Disable))
|
||
|
|
||
|
/*! Parameter validity check for ADC SA trigger source. */
|
||
|
#define IS_ADC_TRGSEL(SEL) \
|
||
|
( ((SEL) == AdcTrgsel_ADTRGX) || \
|
||
|
((SEL) == AdcTrgsel_TRGX0) || \
|
||
|
((SEL) == AdcTrgsel_TRGX1) || \
|
||
|
((SEL) == AdcTrgsel_TRGX0_TRGX1))
|
||
|
|
||
|
/*! Parameter validity check for ADC common trigger. */
|
||
|
#define IS_ADC_COM_TRIGGER(x) \
|
||
|
( ((x) == AdcComTrigger_1) || \
|
||
|
((x) == AdcComTrigger_2) || \
|
||
|
((x) == AdcComTrigger_1_2))
|
||
|
|
||
|
/*! Parameter validity check for ADC EOCAIEN/ENCBIEN. */
|
||
|
#define IS_ADC_EOCIEN(EN) \
|
||
|
( ((EN) == AdcEocien_Disable) || \
|
||
|
((EN) == AdcEocien_Enable))
|
||
|
|
||
|
/*! Parameter validity check for ADC sampling time. */
|
||
|
#define IS_ADC_SAMPLE_TIME(TIME) \
|
||
|
( ((TIME) == 255u) || \
|
||
|
(((TIME) >= 5u) && ((TIME) <= 254u)))
|
||
|
|
||
|
/*! Parameter validity check for ADC sync trigger mode. */
|
||
|
#define IS_ADC_SYNC_MODE(MODE) \
|
||
|
( ((MODE) == AdcSync_SingleSerial) || \
|
||
|
((MODE) == AdcSync_SingleParallel) || \
|
||
|
((MODE) == AdcSync_ContinuousSerial) || \
|
||
|
((MODE) == AdcSync_ContinuousParallel))
|
||
|
|
||
|
/*! Parameter validity check for ADC sync able. */
|
||
|
#define IS_ADC_SYNC_ENABLE(EN) \
|
||
|
( ((EN) == AdcSync_Disable) || \
|
||
|
((EN) == AdcSync_Enable))
|
||
|
|
||
|
/*! Parameter validity check for ADC ADWIEN */
|
||
|
#define IS_ADC_AWDIEN(EN) \
|
||
|
( ((EN) == AdcAwdInt_Disable) || \
|
||
|
((EN) == AdcAwdInt_Enable))
|
||
|
|
||
|
/*! Parameter validity check for ADC AWDSS */
|
||
|
#define IS_ADC_AWDSS(SS) \
|
||
|
( ((SS) == AdcAwdSel_SA_SB) || \
|
||
|
((SS) == AdcAwdSel_SA) || \
|
||
|
((SS) == AdcAwdSel_SB) || \
|
||
|
((SS) == AdcAwdSel_SB_SA))
|
||
|
|
||
|
/*! Parameter validity check for ADC AWDMD */
|
||
|
#define IS_ADC_AWDMD(MD) \
|
||
|
( ((MD) == AdcAwdCmpMode_0) || \
|
||
|
((MD) == AdcAwdCmpMode_1))
|
||
|
|
||
|
/*! Parameter validity check for ADC AWDEN */
|
||
|
#define IS_ADC_AWDEN(EN) \
|
||
|
( ((EN) == AdcAwd_Disable) || \
|
||
|
((EN) == AdcAwd_Enable))
|
||
|
|
||
|
/*! Parameter validity check for ADC PGA control */
|
||
|
#define IS_ADC_PGA_CTL(CTL) \
|
||
|
( ((CTL) == AdcPgaCtl_Invalid) || \
|
||
|
((CTL) == AdcPgaCtl_Amplify))
|
||
|
|
||
|
/*! Parameter validity check for ADC gain factor. */
|
||
|
#define IS_ADC_PGA_FACTOR(FACTOR) \
|
||
|
( ((FACTOR) == AdcPgaFactor_2) || \
|
||
|
(((FACTOR) >= AdcPgaFactor_2P133) && ((FACTOR) <= AdcPgaFactor_32)))
|
||
|
|
||
|
/*! Parameter validity check for ADC PGA negative. */
|
||
|
#define IS_ADC_PGA_NEGATIVE(N) \
|
||
|
( ((N) == AdcPgaNegative_VSSA) || \
|
||
|
((N) == AdcPgaNegative_PGAVSS))
|
||
|
|
||
|
/*! Parameter validity check for ADC trigger source event . */
|
||
|
#define IS_ADC_TRIG_SRC_EVENT(x) \
|
||
|
( ((x) == EVT_PORT_EIRQ0) || \
|
||
|
(((x) > EVT_PORT_EIRQ0) && ((x) <= EVT_PORT_EIRQ15)) || \
|
||
|
(((x) >= EVT_DMA1_TC0) && ((x) <= EVT_DMA2_BTC3)) || \
|
||
|
(((x) >= EVT_EFM_OPTEND) && ((x) <= EVT_USBFS_SOF)) || \
|
||
|
(((x) >= EVT_DCU1) && ((x) <= EVT_DCU4)) || \
|
||
|
(((x) >= EVT_TMR01_GCMA) && ((x) <= EVT_TMR02_GCMB)) || \
|
||
|
(((x) >= EVT_RTC_ALM) && ((x) <= EVT_RTC_PRD)) || \
|
||
|
(((x) >= EVT_TMR61_GCMA) && ((x) <= EVT_TMR61_GUDF)) || \
|
||
|
(((x) >= EVT_TMR61_SCMA) && ((x) <= EVT_TMR61_SCMB)) || \
|
||
|
(((x) >= EVT_TMR62_GCMA) && ((x) <= EVT_TMR62_GUDF)) || \
|
||
|
(((x) >= EVT_TMR62_SCMA) && ((x) <= EVT_TMR62_SCMB)) || \
|
||
|
(((x) >= EVT_TMR63_GCMA) && ((x) <= EVT_TMR63_GUDF)) || \
|
||
|
(((x) >= EVT_TMR63_SCMA) && ((x) <= EVT_TMR63_SCMB)) || \
|
||
|
(((x) >= EVT_TMRA1_OVF) && ((x) <= EVT_TMRA5_CMP)) || \
|
||
|
(((x) >= EVT_TMRA6_OVF) && ((x) <= EVT_TMRA6_CMP)) || \
|
||
|
(((x) >= EVT_USART1_EI) && ((x) <= EVT_USART4_RTO)) || \
|
||
|
(((x) >= EVT_SPI1_SPRI) && ((x) <= EVT_AOS_STRG)) || \
|
||
|
(((x) >= EVT_TMR41_SCMUH) && ((x) <= EVT_TMR42_SCMWL)) || \
|
||
|
(((x) >= EVT_TMR43_SCMUH) && ((x) <= EVT_TMR43_SCMWL)) || \
|
||
|
(((x) >= EVT_EVENT_PORT1) && ((x) <= EVT_EVENT_PORT4)) || \
|
||
|
(((x) >= EVT_I2S1_TXIRQOUT) && ((x) <= EVT_I2S1_RXIRQOUT)) || \
|
||
|
(((x) >= EVT_I2S2_TXIRQOUT) && ((x) <= EVT_I2S2_RXIRQOUT)) || \
|
||
|
(((x) >= EVT_I2S3_TXIRQOUT) && ((x) <= EVT_I2S3_RXIRQOUT)) || \
|
||
|
(((x) >= EVT_I2S4_TXIRQOUT) && ((x) <= EVT_I2S4_RXIRQOUT)) || \
|
||
|
(((x) >= EVT_ACMP1) && ((x) <= EVT_ACMP3)) || \
|
||
|
(((x) >= EVT_I2C1_RXI) && ((x) <= EVT_I2C3_EEI)) || \
|
||
|
(((x) >= EVT_PVD_PVD1) && ((x) <= EVT_OTS)) || \
|
||
|
((x) == EVT_WDT_REFUDF) || \
|
||
|
(((x) >= EVT_ADC1_EOCA) && ((x) <= EVT_TRNG_END)) || \
|
||
|
(((x) >= EVT_SDIOC1_DMAR) && ((x) <= EVT_SDIOC1_DMAW)) || \
|
||
|
(((x) >= EVT_SDIOC2_DMAR) && ((x) <= EVT_SDIOC2_DMAW)) || \
|
||
|
((x) == EVT_MAX))
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Global variable definitions (declared in header file with 'extern')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local function prototypes ('static')
|
||
|
******************************************************************************/
|
||
|
static void ADC_ReadAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length);
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local variable definitions ('static')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Function implementation - global ('extern')
|
||
|
******************************************************************************/
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Initializes an ADC instance.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] pstcInit Pointer to ADC initialization structure.
|
||
|
** See @ref stc_adc_init_t for details.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_Init(M4_ADC_TypeDef *ADCx, const stc_adc_init_t *pstcInit)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if ((NULL != ADCx) && (NULL != pstcInit))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_RESOLUTION(pstcInit->enResolution));
|
||
|
DDL_ASSERT(IS_ADC_DATA_ALIGN(pstcInit->enDataAlign));
|
||
|
DDL_ASSERT(IS_ADC_CLREN(pstcInit->enAutoClear));
|
||
|
DDL_ASSERT(IS_ADC_SCAN_MODE(pstcInit->enScanMode));
|
||
|
DDL_ASSERT(IS_ADC_RSCHSEL(pstcInit->enRschsel));
|
||
|
|
||
|
/* Stop ADC conversion. */
|
||
|
ADCx->STR = 0u;
|
||
|
|
||
|
ADCx->CR0_f.ACCSEL = pstcInit->enResolution;
|
||
|
ADCx->CR0_f.DFMT = pstcInit->enDataAlign;
|
||
|
ADCx->CR0_f.CLREN = pstcInit->enAutoClear;
|
||
|
ADCx->CR0_f.MS = pstcInit->enScanMode;
|
||
|
ADCx->CR1_f.RSCHSEL = pstcInit->enRschsel;
|
||
|
|
||
|
/* Disable EOC(End Of Conversion) interrupts default. */
|
||
|
ADCx->ICR = (uint8_t)0x0;
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Deinitializes an ADC instance.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_DeInit(M4_ADC_TypeDef *ADCx)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
/* Set the value of all registers to the reset value. */
|
||
|
/* Stop ADC conversion. */
|
||
|
ADCx->STR = 0u;
|
||
|
ADCx->CR0 = 0u;
|
||
|
ADCx->CR1 = 0u;
|
||
|
ADCx->TRGSR = 0u;
|
||
|
ADCx->CHSELRA0 = 0u;
|
||
|
ADCx->CHSELRB0 = 0u;
|
||
|
ADCx->AVCHSELR0 = 0u;
|
||
|
ADCx->AWDCHSR0 = 0u;
|
||
|
ADCx->SSTR0 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR1 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR2 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR3 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR4 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR5 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR6 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR7 = (uint8_t)0x0B;
|
||
|
ADCx->SSTR8 = (uint8_t)0x0B;
|
||
|
ADCx->CHMUXR0 = (uint16_t)0x3210;
|
||
|
ADCx->CHMUXR1 = (uint16_t)0x7654;
|
||
|
ADCx->ISR = 0u;
|
||
|
ADCx->ICR = (uint8_t)0x03;
|
||
|
ADCx->AWDCR = 0u;
|
||
|
ADCx->AWDDR0 = 0u;
|
||
|
ADCx->AWDDR1 = 0u;
|
||
|
ADCx->AWDCHSR0 = 0u;
|
||
|
ADCx->AWDSR0 = 0u;
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->CHSELRA1 = 0u;
|
||
|
ADCx->CHSELRB1 = 0u;
|
||
|
ADCx->AVCHSELR1 = 0u;
|
||
|
ADCx->CHMUXR2 = (uint16_t)0xBA98;
|
||
|
ADCx->CHMUXR3 = (uint16_t)0xFEDC;
|
||
|
ADCx->SYNCCR = (uint16_t)0x0C00;
|
||
|
ADCx->AWDCHSR1 = 0u;
|
||
|
ADCx->AWDSR1 = 0u;
|
||
|
ADCx->PGACR = 0u;
|
||
|
ADCx->PGAGSR = 0u;
|
||
|
ADCx->PGAINSR0 = 0u;
|
||
|
ADCx->PGAINSR1 = 0u;
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Set scan mode.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param[in] enMode See @ref en_adc_scan_mode_t for details.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_SetScanMode(M4_ADC_TypeDef *ADCx, en_adc_scan_mode_t enMode)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_SCAN_MODE(enMode));
|
||
|
|
||
|
ADCx->CR0_f.MS = enMode;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Set trigger source.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] pstcTrgCfg Pointer to ADC trigger source configuration structure.
|
||
|
** \arg u8Sequence The sequence which you want to set it's trigger source.
|
||
|
** \arg enTrgEnable Enable or disable trigger source.
|
||
|
** \arg enTrgSel The type of trigger source.
|
||
|
** \arg enInTrg0 Event number @ref en_event_src_t.
|
||
|
** \arg enInTrg1 Event number @ref en_event_src_t.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
** \note Sequence A and Sequence B CAN NOT set the same trigger source.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_ConfigTriggerSrc(M4_ADC_TypeDef *ADCx,
|
||
|
const stc_adc_trg_cfg_t *pstcTrgCfg)
|
||
|
{
|
||
|
uint32_t u32TrgSelR;
|
||
|
__IO uint32_t *io32AdcxTrgSelR0;
|
||
|
__IO uint32_t *io32AdcxTrgSelR1;
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if ((NULL != ADCx) &&
|
||
|
(NULL != pstcTrgCfg) &&
|
||
|
(pstcTrgCfg->u8Sequence <= ADC_SEQ_B))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_TRGSEL(pstcTrgCfg->enTrgSel));
|
||
|
|
||
|
if (ADC_SEQ_A == pstcTrgCfg->u8Sequence)
|
||
|
{
|
||
|
ADCx->TRGSR_f.TRGSELA = pstcTrgCfg->enTrgSel;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADCx->TRGSR_f.TRGSELB = pstcTrgCfg->enTrgSel;
|
||
|
}
|
||
|
|
||
|
if (AdcTrgsel_ADTRGX != pstcTrgCfg->enTrgSel)
|
||
|
{
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
io32AdcxTrgSelR0 = &(M4_AOS->ADC1_ITRGSELR0);
|
||
|
io32AdcxTrgSelR1 = &(M4_AOS->ADC1_ITRGSELR1);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
io32AdcxTrgSelR0 = &(M4_AOS->ADC2_ITRGSELR0);
|
||
|
io32AdcxTrgSelR1 = &(M4_AOS->ADC2_ITRGSELR1);
|
||
|
}
|
||
|
|
||
|
if ((pstcTrgCfg->enTrgSel & AdcTrgsel_TRGX0) == AdcTrgsel_TRGX0)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_TRIG_SRC_EVENT(pstcTrgCfg->enInTrg0));
|
||
|
|
||
|
u32TrgSelR = *io32AdcxTrgSelR0;
|
||
|
u32TrgSelR &= ~0x1FFul;
|
||
|
u32TrgSelR |= pstcTrgCfg->enInTrg0;
|
||
|
*io32AdcxTrgSelR0 = u32TrgSelR;
|
||
|
}
|
||
|
if ((pstcTrgCfg->enTrgSel & AdcTrgsel_TRGX1) == AdcTrgsel_TRGX1)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_TRIG_SRC_EVENT(pstcTrgCfg->enInTrg1));
|
||
|
|
||
|
u32TrgSelR = *io32AdcxTrgSelR1;
|
||
|
u32TrgSelR &= ~0x1FFul;
|
||
|
u32TrgSelR |= pstcTrgCfg->enInTrg1;
|
||
|
*io32AdcxTrgSelR1 = u32TrgSelR;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Set trigger source.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u8Seq The sequence which you want to set it's trigger source.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable trigger source.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_TriggerSrcCmd(M4_ADC_TypeDef *ADCx,
|
||
|
uint8_t u8Seq,
|
||
|
en_functional_state_t enState)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if ((NULL != ADCx) && (u8Seq <= ADC_SEQ_B))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
if (ADC_SEQ_A == u8Seq)
|
||
|
{
|
||
|
ADCx->TRGSR_f.TRGENA = enState;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADCx->TRGSR_f.TRGENB = enState;
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Enable or disable ADC common trigger.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] enTrgSel ADC trigger source type. See @ref en_adc_trgsel_t for details.
|
||
|
**
|
||
|
** \param [in] enComTrigger ADC common trigger selection. See @ref en_adc_com_trigger_t for details.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable the specified common trigger.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ComTriggerCmd(M4_ADC_TypeDef *ADCx, en_adc_trgsel_t enTrgSel, \
|
||
|
en_adc_com_trigger_t enComTrigger, en_functional_state_t enState)
|
||
|
{
|
||
|
uint32_t u32ComTrig = enComTrigger;
|
||
|
uint32_t u32ITRGSELRAddr;
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_TRGSEL(enTrgSel) && (enTrgSel != AdcTrgsel_ADTRGX));
|
||
|
DDL_ASSERT(IS_ADC_COM_TRIGGER(enComTrigger));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32ITRGSELRAddr = (uint32_t)&M4_AOS->ADC1_ITRGSELR0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32ITRGSELRAddr = (uint32_t)&M4_AOS->ADC2_ITRGSELR0;
|
||
|
}
|
||
|
|
||
|
u32ComTrig <<= 30u;
|
||
|
|
||
|
if ((enTrgSel & AdcTrgsel_TRGX0) == AdcTrgsel_TRGX0)
|
||
|
{
|
||
|
if (enState == Enable)
|
||
|
{
|
||
|
*(__IO uint32_t *)u32ITRGSELRAddr |= u32ComTrig;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*(__IO uint32_t *)u32ITRGSELRAddr &= ~u32ComTrig;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ((enTrgSel & AdcTrgsel_TRGX1) == AdcTrgsel_TRGX1)
|
||
|
{
|
||
|
u32ITRGSELRAddr += 4ul;
|
||
|
if (enState == Enable)
|
||
|
{
|
||
|
*(__IO uint32_t *)u32ITRGSELRAddr |= u32ComTrig;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*(__IO uint32_t *)u32ITRGSELRAddr &= ~u32ComTrig;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Add ADC channel.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] pstcChCfg Pointer to ADC channel configuration structure.
|
||
|
** \arg u32Channel The channel(s) you want to configure.
|
||
|
** \arg u8Sequence The sequence which the channel(s) belong(s) to.
|
||
|
** \arg pu8SampTime Pointer to sampling time.
|
||
|
** eg. u32Channel = 1001b
|
||
|
** pu8SampTime[0] = channel 0's time
|
||
|
** pu8SampTime[1] = channel 3's time
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
** \note Sequence A and Sequence B CAN NOT set the same channel!!!
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_AddAdcChannel(M4_ADC_TypeDef *ADCx, const stc_adc_ch_cfg_t *pstcChCfg)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint8_t i;
|
||
|
uint8_t j;
|
||
|
uint32_t u32ChannelSel;
|
||
|
__IO uint8_t *io8Sstr;
|
||
|
|
||
|
if ((NULL != ADCx) &&
|
||
|
(NULL != pstcChCfg) &&
|
||
|
(pstcChCfg->u8Sequence <= ADC_SEQ_B))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32ChannelSel = pstcChCfg->u32Channel & ADC1_CH_ALL;
|
||
|
if (ADC_SEQ_A == pstcChCfg->u8Sequence)
|
||
|
{
|
||
|
ADCx->CHSELRA0 |= (uint16_t)u32ChannelSel;
|
||
|
ADCx->CHSELRA1 |= (uint16_t)(u32ChannelSel >> 16u);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADCx->CHSELRB0 |= (uint16_t)u32ChannelSel;
|
||
|
ADCx->CHSELRB1 |= (uint16_t)(u32ChannelSel >> 16u);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32ChannelSel = pstcChCfg->u32Channel & ADC2_CH_ALL;
|
||
|
if (ADC_SEQ_A == pstcChCfg->u8Sequence)
|
||
|
{
|
||
|
ADCx->CHSELRA0 |= (uint16_t)u32ChannelSel;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADCx->CHSELRB0 |= (uint16_t)u32ChannelSel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Set sampling time */
|
||
|
i = 0u;
|
||
|
j = 0u;
|
||
|
io8Sstr = &(ADCx->SSTR0);
|
||
|
while (0u != u32ChannelSel)
|
||
|
{
|
||
|
if (u32ChannelSel & 0x1ul)
|
||
|
{
|
||
|
io8Sstr[i] = pstcChCfg->pu8SampTime[j++];
|
||
|
}
|
||
|
u32ChannelSel >>= 1u;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Delete ADC channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32Channel The channel(s) you want to delete.
|
||
|
** \arg ADC1_CH0 ~ ADC1_CH16
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
** \note You can use this function to delete ADC channel(s)
|
||
|
** and then set the corresponding pin(s) of the channel(s)
|
||
|
** to the other mode you need in your application.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_DelAdcChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint16_t u16ChSelR0;
|
||
|
uint16_t u16ChSelR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
u16ChSelR0 = (uint16_t)u32Channel;
|
||
|
u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
|
||
|
|
||
|
ADCx->CHSELRA0 &= (uint16_t)(~u16ChSelR0);
|
||
|
ADCx->CHSELRB0 &= (uint16_t)(~u16ChSelR0);
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->CHSELRA1 &= (uint16_t)(~u16ChSelR1);
|
||
|
ADCx->CHSELRB1 &= (uint16_t)(~u16ChSelR1);
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC interrupt configuration.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u8Seq The sequence to be configured.
|
||
|
**
|
||
|
** \param [in] enState Enable or Disable sequence conversion done interrupt.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_SeqITCmd(M4_ADC_TypeDef *ADCx,
|
||
|
uint8_t u8Seq,
|
||
|
en_functional_state_t enState)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint8_t u8Msk = 0u;
|
||
|
|
||
|
if ((NULL != ADCx) && (u8Seq <= ADC_SEQ_B))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
u8Msk = (uint8_t)(0x1ul << u8Seq);
|
||
|
ADCx->ISR &= (uint8_t)(~u8Msk);
|
||
|
|
||
|
if (Enable == enState)
|
||
|
{
|
||
|
ADCx->ICR |= u8Msk;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADCx->ICR &= (uint8_t)(~u8Msk);
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC average conversion configuration.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] enAvgCnt Average after enAvgCnt conversions.
|
||
|
** See @ref en_adc_avcnt_t for details.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_ConfigAvg(M4_ADC_TypeDef *ADCx, en_adc_avcnt_t enAvgCnt)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_AVCNT(enAvgCnt));
|
||
|
|
||
|
ADCx->CR0_f.AVCNT = enAvgCnt;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Add average channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32Channel The channel(s), which will be set as average channel(s).
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
** \note The channel must first be configured as an analog channel
|
||
|
** by function ADC_AddAdcChannel.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_AddAvgChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint16_t u16AvgChR0;
|
||
|
uint16_t u16AvgChR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32Channel &= ADC1_CH_ALL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32Channel &= ADC2_CH_ALL;
|
||
|
}
|
||
|
|
||
|
u16AvgChR0 = (uint16_t)u32Channel;
|
||
|
u16AvgChR1 = (uint16_t)(u32Channel >> 16u);
|
||
|
|
||
|
ADCx->AVCHSELR0 |= u16AvgChR0;
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AVCHSELR1 |= u16AvgChR1;
|
||
|
}
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Delete average channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32Channel The average channel(s) which you want to delete.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_DelAvgChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint16_t u16AvgChR0;
|
||
|
uint16_t u16AvgChR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
u16AvgChR0 = (uint16_t)u32Channel;
|
||
|
u16AvgChR1 = (uint16_t)(u32Channel >> 16u);
|
||
|
|
||
|
ADCx->AVCHSELR0 &= (uint16_t)(~u16AvgChR0);
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AVCHSELR1 &= (uint16_t)(~u16AvgChR1);
|
||
|
}
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC AWD(analog watch dog) configuration.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] pstcAwdCfg Pointer to the configuration structure.
|
||
|
** See @ref stc_adc_awd_cfg_t for details.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_ConfigAwd(M4_ADC_TypeDef *ADCx, const stc_adc_awd_cfg_t *pstcAwdCfg)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if ((NULL != ADCx) && (NULL != pstcAwdCfg))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_ADC_AWDMD(pstcAwdCfg->enAwdmd));
|
||
|
DDL_ASSERT(IS_ADC_AWDSS(pstcAwdCfg->enAwdss));
|
||
|
|
||
|
ADCx->AWDCR_f.AWDEN = AdcAwd_Disable;
|
||
|
ADCx->AWDCR_f.AWDIEN = AdcAwdInt_Disable;
|
||
|
ADCx->AWDCR_f.AWDMD = pstcAwdCfg->enAwdmd;
|
||
|
ADCx->AWDCR_f.AWDSS = pstcAwdCfg->enAwdss;
|
||
|
|
||
|
ADCx->AWDDR0 = pstcAwdCfg->u16AwdDr0;
|
||
|
ADCx->AWDDR1 = pstcAwdCfg->u16AwdDr1;
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Enable or disable ADC AWD(analog watch dog).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable AWD.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_AwdCmd(M4_ADC_TypeDef *ADCx, en_functional_state_t enState)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
ADCx->AWDCR_f.AWDEN = enState;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Enable or disable ADC AWD(analog watch dog) interrupt.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable AWD interrupt.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_AwdITCmd(M4_ADC_TypeDef *ADCx, en_functional_state_t enState)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
ADCx->AWDCR_f.AWDIEN = enState;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Add AWD channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32Channel The channel(s), which will be set as AWD channel(s).
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
** \note The channel must first be configured as an analog channel
|
||
|
** by function ADC_AddAdcChannel.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_AddAwdChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint16_t u16ChSelR0;
|
||
|
uint16_t u16ChSelR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32Channel &= ADC1_CH_ALL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32Channel &= ADC2_CH_ALL;
|
||
|
}
|
||
|
|
||
|
u16ChSelR0 = (uint16_t)u32Channel;
|
||
|
u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
|
||
|
|
||
|
ADCx->AWDCHSR0 |= u16ChSelR0;
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AWDCHSR1 |= u16ChSelR1;
|
||
|
}
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Delete AWD channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32Channel The AWD channel(s) which you are going to delete.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_DelAwdChannel(M4_ADC_TypeDef *ADCx, uint32_t u32Channel)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint16_t u16ChSelR0;
|
||
|
uint16_t u16ChSelR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
u16ChSelR0 = (uint16_t)u32Channel;
|
||
|
u16ChSelR1 = (uint16_t)(u32Channel >> 16u);
|
||
|
|
||
|
ADCx->AWDCHSR0 &= (uint16_t)(~u16ChSelR0);
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AWDCHSR1 &= (uint16_t)(~u16ChSelR1);
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC programmable gain amplifier(PGA) configuration.
|
||
|
**
|
||
|
** \param [in] enFactor PGA gain factor.
|
||
|
** \param [in] enNegativeIn PGA negative input select.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
** \note Only ADC1 has PGA.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ConfigPga(en_adc_pga_factor_t enFactor, en_adc_pga_negative_t enNegativeIn)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PGA_FACTOR(enFactor));
|
||
|
DDL_ASSERT(IS_ADC_PGA_NEGATIVE(enNegativeIn));
|
||
|
|
||
|
M4_ADC1->PGAGSR_f.GAIN = enFactor;
|
||
|
M4_ADC1->PGAINSR1_f.PGAVSSEN = enNegativeIn;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Enable or disable PGA.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable PGA.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_PgaCmd(en_functional_state_t enState)
|
||
|
{
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
if (Enable == enState)
|
||
|
{
|
||
|
M4_ADC1->PGACR_f.PGACTL = AdcPgaCtl_Amplify;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
M4_ADC1->PGACR_f.PGACTL = AdcPgaCtl_Invalid;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Add PGA channel(s).
|
||
|
**
|
||
|
** \param[in] u32Channel The channel(s), which you want to gain.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
** \note Only ADC1 has PGA. The channel must first
|
||
|
** be configured as an analog channel
|
||
|
** by function ADC_AddAdcChannel
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_AddPgaChannel(uint32_t u32Channel)
|
||
|
{
|
||
|
M4_ADC1->PGAINSR0 |= ((uint16_t)(u32Channel & PGA_CH_ALL));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Delete PGA channel(s).
|
||
|
**
|
||
|
** \param[in] u32Channel The PGA channel(s) which will be deleted.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_DelPgaChannel(uint32_t u32Channel)
|
||
|
{
|
||
|
M4_ADC1->PGAINSR0 &= (uint16_t)(~u32Channel);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC sync mode configuration.
|
||
|
**
|
||
|
** \param [in] enMode Synchronous mode types.
|
||
|
** \param [in] u8TrgDelay ADC2 trigger delay time.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ConfigSync(en_adc_sync_mode_t enMode, uint8_t u8TrgDelay)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_SYNC_MODE(enMode));
|
||
|
|
||
|
/* Disable synchronous mode first. */
|
||
|
M4_ADC1->SYNCCR_f.SYNCEN = AdcSync_Disable;
|
||
|
|
||
|
M4_ADC1->SYNCCR_f.SYNCMD = enMode;
|
||
|
M4_ADC1->SYNCCR_f.SYNCDLY = u8TrgDelay;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Enable or disable sync mode.
|
||
|
**
|
||
|
** \param [in] enState Enable or disable sync mode.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_SyncCmd(en_functional_state_t enState)
|
||
|
{
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enState));
|
||
|
|
||
|
M4_ADC1->SYNCCR_f.SYNCEN = enState;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Start an ADC conversion.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
** \note Software startup only support sequence A.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_StartConvert(M4_ADC_TypeDef *ADCx)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
ADCx->STR = 1u;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Stop an ADC conversion and clear flags.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval ErrorTimeout Timeout.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_StopConvert(M4_ADC_TypeDef *ADCx)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
__IO uint32_t u32TimeCount = 0u;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
enRet = Ok;
|
||
|
/* Make sure the ADC is really stopped. */
|
||
|
while (ADCx->STR == 1u)
|
||
|
{
|
||
|
/* Stop ADC conversion. */
|
||
|
ADCx->STR = 0u;
|
||
|
if (++u32TimeCount > 10000u)
|
||
|
{
|
||
|
enRet = ErrorTimeout;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Get the conversion status flag.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u8Seq The sequence which you want to get
|
||
|
** it's conversion status flag.
|
||
|
**
|
||
|
** \retval Set ADC converted done.
|
||
|
** \retval Reset ADC is converting or parameter error.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_flag_status_t ADC_GetEocFlag(const M4_ADC_TypeDef *ADCx, uint8_t u8Seq)
|
||
|
{
|
||
|
en_flag_status_t enFlag = Reset;
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (ADCx->ISR & ((uint8_t)(0x1ul << u8Seq)))
|
||
|
{
|
||
|
enFlag = Set;
|
||
|
}
|
||
|
|
||
|
return enFlag;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Clear conversion status flag of sequence A or sequence B.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u8Seq The sequence which you want to clear
|
||
|
** it's conversion status flag.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ClrEocFlag(M4_ADC_TypeDef *ADCx, uint8_t u8Seq)
|
||
|
{
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
ADCx->ISR &= (uint8_t)(~(0x1ul << u8Seq));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief ADC start sequence A, check it's EOC status and get the data.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [out] pu16AdcData The address to store ADC value.
|
||
|
** The location of the data store depends on
|
||
|
** the parameter u8Length.
|
||
|
** u8Length >= ADCx_CH_COUNT(ADC1_CH_COUNT or ADC2_CH_COUNT),
|
||
|
** all of the ADC data regs will be read:
|
||
|
** pu16AdcData[0] = data of Channel 0,
|
||
|
** pu16AdcData[1] = data of Channel 1,
|
||
|
** pu16AdcData[2] = data of Channel 2,
|
||
|
** ...
|
||
|
** u8Length < ADCx_CH_COUNT(ADC1_CH_COUNT or ADC2_CH_COUNT),
|
||
|
** only the data of the enabled channles will be read:
|
||
|
** pu16AdcData[0] = data of the 1st enabled channel,
|
||
|
** pu16AdcData[1] = data of the 2nd enabled channel,
|
||
|
** pu16AdcData[2] = data of the 3rd enabled channel,
|
||
|
** ...
|
||
|
**
|
||
|
** \param [in] u8Length The length of the ADC data to be read.
|
||
|
**
|
||
|
** \param [in] u32Timeout Timeout value.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval ErrorTimeout Timeout.
|
||
|
** \retval OperationInProgress ADC is converting.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_PollingSa(M4_ADC_TypeDef *ADCx,
|
||
|
uint16_t *pu16AdcData,
|
||
|
uint8_t u8Length,
|
||
|
uint32_t u32Timeout)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint8_t u8AllDataLength = 0u;
|
||
|
uint32_t u32Channel = 0u;
|
||
|
uint32_t u32AdcTimeout = 0u;
|
||
|
__IO uint32_t u32TimeCount = 0u;
|
||
|
|
||
|
if ((NULL != ADCx) && (NULL != pu16AdcData) && (0u != u8Length))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
if (u8Length >= ADC1_CH_COUNT)
|
||
|
{
|
||
|
u8AllDataLength = ADC1_CH_COUNT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32Channel = (uint32_t)ADCx->CHSELRA1;
|
||
|
u32Channel <<= 16u;
|
||
|
u32Channel |= (uint32_t)ADCx->CHSELRA0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (u8Length >= ADC2_CH_COUNT)
|
||
|
{
|
||
|
u8AllDataLength = ADC2_CH_COUNT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32Channel = (uint32_t)M4_ADC1->CHSELRA0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Start ADC conversion. */
|
||
|
ADCx->STR = (uint8_t)0x01;
|
||
|
|
||
|
/* 10 is the number of required instructions cycles for the below loop statement. */
|
||
|
u32AdcTimeout = u32Timeout * (SystemCoreClock / 10u / 1000u);
|
||
|
u32TimeCount = 0u;
|
||
|
enRet = ErrorTimeout;
|
||
|
while (u32TimeCount < u32AdcTimeout)
|
||
|
{
|
||
|
if (ADCx->ISR_f.EOCAF)
|
||
|
{
|
||
|
/* Get ADC data. */
|
||
|
if (u8AllDataLength)
|
||
|
{
|
||
|
ADC_ReadAllData(ADCx, pu16AdcData, u8AllDataLength);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ADC_GetChData(ADCx, u32Channel, pu16AdcData, u8Length);
|
||
|
}
|
||
|
|
||
|
/* Clear sequence A flag. */
|
||
|
ADCx->ISR_f.EOCAF = 0u;
|
||
|
enRet = Ok;
|
||
|
break;
|
||
|
}
|
||
|
u32TimeCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Reading all data regs of an ADC.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [out] pu16AdcData The address where the data will be stored.
|
||
|
** pu16AdcData[0] = data of Channel 0,
|
||
|
** pu16AdcData[1] = data of Channel 1,
|
||
|
** pu16AdcData[2] = data of Channel 2,
|
||
|
** ...
|
||
|
**
|
||
|
** \param [in] u8Length The length of the ADC data to be read.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_GetAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
if (((M4_ADC1 == ADCx) && (u8Length >= ADC1_CH_COUNT)) ||
|
||
|
((M4_ADC2 == ADCx) && (u8Length >= ADC2_CH_COUNT)))
|
||
|
{
|
||
|
ADC_ReadAllData(ADCx, pu16AdcData, u8Length);
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Reading the data of the specified channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base
|
||
|
**
|
||
|
** \param [in] u32TargetCh The specified channel(s)
|
||
|
**
|
||
|
** \param [out] pu16AdcData The address where the data will be stored.
|
||
|
** pu16AdcData[0] = data of the 1st enabled channel,
|
||
|
** pu16AdcData[1] = data of the 2nd enabled channel,
|
||
|
** pu16AdcData[2] = data of the 3rd enabled channel,
|
||
|
** eg. u32TargetCh = 1001b
|
||
|
** pu16AdcData[0] = Channel 0's data,
|
||
|
** pu16AdcData[1] = Channel 3's data,
|
||
|
**
|
||
|
** \param [in] u8Length The length of the ADC data to be read.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_GetChData(const M4_ADC_TypeDef *ADCx,
|
||
|
uint32_t u32TargetCh,
|
||
|
uint16_t *pu16AdcData,
|
||
|
uint8_t u8Length)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint8_t i;
|
||
|
uint8_t j;
|
||
|
uint32_t u32Channel;
|
||
|
__IO const uint16_t *pu16DataReg = &(ADCx->DR0);
|
||
|
|
||
|
if ((NULL != ADCx) && (NULL != pu16AdcData) && (0u != u8Length))
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32Channel = u32TargetCh & ADC1_CH_ALL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32Channel = u32TargetCh & ADC2_CH_ALL;
|
||
|
}
|
||
|
|
||
|
i = 0u;
|
||
|
j = 0u;
|
||
|
while ((0u != u32Channel) && (0u != u8Length))
|
||
|
{
|
||
|
if (0u != (u32Channel & 0x1ul))
|
||
|
{
|
||
|
pu16AdcData[j] = pu16DataReg[i];
|
||
|
j++;
|
||
|
u8Length--;
|
||
|
}
|
||
|
|
||
|
u32Channel >>= 1u;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Get the value of a specified channel via channel index.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base
|
||
|
**
|
||
|
** \param [in] u8ChIndex The index of the specified channel.
|
||
|
** u8ChIndex < ADC1_CH_COUNT while ADCx == M4_ADC1;
|
||
|
** u8ChIndex < ADC2_CH_COUNT while ADCx == M4_ADC2.
|
||
|
**
|
||
|
** \retval An uint16_t value -- the ADC value of the specified channel.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
uint16_t ADC_GetValue(const M4_ADC_TypeDef *ADCx, uint8_t u8ChIndex)
|
||
|
{
|
||
|
__IO const uint16_t *pu16DataReg = &(ADCx->DR0);
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
return pu16DataReg[u8ChIndex];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Get all AWD channels status flags.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \retval u32AwdFlag 0 -- No ADC channel meets AWD comparison conditions.
|
||
|
** !0 -- The bit value of the channel that satisfies the
|
||
|
** AWD condition is 1.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
uint32_t ADC_GetAwdFlag(const M4_ADC_TypeDef *ADCx)
|
||
|
{
|
||
|
uint32_t u32AwdFlag;
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
u32AwdFlag = ADCx->AWDSR1;
|
||
|
u32AwdFlag <<= 16u;
|
||
|
u32AwdFlag |= ADCx->AWDSR0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
u32AwdFlag = ADCx->AWDSR0;
|
||
|
}
|
||
|
|
||
|
return u32AwdFlag;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Clear all AWD channels status flags
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ClrAwdFlag(M4_ADC_TypeDef *ADCx)
|
||
|
{
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
ADCx->AWDSR0 = 0u;
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AWDSR0 = 0u;
|
||
|
ADCx->AWDSR1 = 0u;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Clear AWD specified channels status flags.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32AwdCh The channel(s) which you want to clear it's flag(s).
|
||
|
**
|
||
|
** \retval None.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
void ADC_ClrAwdChFlag(M4_ADC_TypeDef *ADCx, uint32_t u32AwdCh)
|
||
|
{
|
||
|
uint16_t u16ChR0;
|
||
|
uint16_t u16ChR1;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
u16ChR0 = (uint16_t)u32AwdCh;
|
||
|
u16ChR1 = (uint16_t)(u32AwdCh >> 16u);
|
||
|
|
||
|
ADCx->AWDSR0 &= (uint16_t)(~u16ChR0);
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
ADCx->AWDSR1 &= (uint16_t)(~u16ChR1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Remap an ADC pin to channel(s).
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u32DestChannel Destination channel(s).
|
||
|
**
|
||
|
** \param [in] u8AdcPin ADC pin number.
|
||
|
**
|
||
|
** \retval ErrorInvalidParameter Parameter error.
|
||
|
** \retval Ok No error occurred.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
en_result_t ADC_ChannelRemap(M4_ADC_TypeDef *ADCx,
|
||
|
uint32_t u32DestChannel,
|
||
|
uint8_t u8AdcPin)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
uint8_t i;
|
||
|
uint8_t u8OffsetReg;
|
||
|
uint8_t u8ChPos;
|
||
|
uint16_t u16AdcPin = u8AdcPin;
|
||
|
__IO uint16_t *io16Chmuxr = NULL;
|
||
|
|
||
|
if (NULL != ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
enRet = Ok;
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
if (u16AdcPin <= ADC1_IN15)
|
||
|
{
|
||
|
u32DestChannel &= ADC1_PIN_MASK_ALL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
enRet = ErrorInvalidParameter;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ((u16AdcPin > ADC12_IN4) && (u16AdcPin < ADC12_IN11))
|
||
|
{
|
||
|
u16AdcPin -= 4u;
|
||
|
u32DestChannel &= ADC2_PIN_MASK_ALL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
enRet = ErrorInvalidParameter;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (Ok == enRet)
|
||
|
{
|
||
|
i = 0u;
|
||
|
while (0u != u32DestChannel)
|
||
|
{
|
||
|
if (u32DestChannel & 0x1ul)
|
||
|
{
|
||
|
u8OffsetReg = i / 4u;
|
||
|
u8ChPos = (i % 4u) * 4u;
|
||
|
io16Chmuxr = &(ADCx->CHMUXR0) + u8OffsetReg;
|
||
|
*io16Chmuxr &= (uint16_t)(~(0xFul << u8ChPos));
|
||
|
*io16Chmuxr |= (uint16_t)(u16AdcPin << u8ChPos);
|
||
|
}
|
||
|
|
||
|
u32DestChannel >>= 1u;
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Get the number of the pin corresponding to the specified channel.
|
||
|
**
|
||
|
** \param [in] ADCx Pointer to ADC instance register base.
|
||
|
** \arg M4_ADC1 ADC unit 1 instance register base.
|
||
|
** \arg M4_ADC2 ADC unit 2 instance register base.
|
||
|
**
|
||
|
** \param [in] u8ChIndex This channel that you want to get its pin number.
|
||
|
**
|
||
|
** \retval [0, 15] The correct ADC pin number.
|
||
|
** \retval [0xFF] The invalid ADC pin number.
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
uint8_t ADC_GetChannelPinNum(const M4_ADC_TypeDef *ADCx, uint8_t u8ChIndex)
|
||
|
{
|
||
|
uint8_t u8OffsetPin;
|
||
|
uint8_t u8OffsetReg;
|
||
|
uint8_t u8ChPos;
|
||
|
uint8_t u8AdcPin = ADC_PIN_INVALID;
|
||
|
__IO const uint16_t *io16Chmuxr = NULL;
|
||
|
|
||
|
DDL_ASSERT(IS_ADC_PERIPH(ADCx));
|
||
|
|
||
|
if (M4_ADC1 == ADCx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC1_CH_INDEX(u8ChIndex));
|
||
|
u8OffsetPin = 0u;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DDL_ASSERT(IS_ADC2_CH_INDEX(u8ChIndex));
|
||
|
u8OffsetPin = 4u;
|
||
|
}
|
||
|
|
||
|
u8OffsetReg = u8ChIndex / 4u;
|
||
|
u8ChPos = (u8ChIndex % 4u) * 4u;
|
||
|
io16Chmuxr = &(ADCx->CHMUXR0) + u8OffsetReg;
|
||
|
u8AdcPin = (uint8_t)((*io16Chmuxr >> u8ChPos) & ((uint16_t)0xF));
|
||
|
u8AdcPin += u8OffsetPin;
|
||
|
|
||
|
return u8AdcPin;
|
||
|
}
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Function implementation - local ('static')
|
||
|
******************************************************************************/
|
||
|
/**
|
||
|
*******************************************************************************
|
||
|
** \brief Read all data of an ADC. pu16AdcData[0] = DR0, pu16AdcData[1] = DR1, ...
|
||
|
**
|
||
|
******************************************************************************/
|
||
|
static void ADC_ReadAllData(const M4_ADC_TypeDef *ADCx, uint16_t *pu16AdcData, uint8_t u8Length)
|
||
|
{
|
||
|
uint8_t i;
|
||
|
__IO const uint16_t *pu16DataReg = &(ADCx->DR0);
|
||
|
|
||
|
for (i = 0u; i < u8Length; i++)
|
||
|
{
|
||
|
pu16AdcData[i] = pu16DataReg[i];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//@} // AdcGroup
|
||
|
|
||
|
#endif /* DDL_ADC_ENABLE */
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* EOF (not truncated)
|
||
|
******************************************************************************/
|