|
@@ -14,8 +14,10 @@
|
|
|
************************************************************************************************************/
|
|
|
#include "hw_config.h"
|
|
|
#include "hw_board.h"
|
|
|
-#ifdef HW_ADC_MAP
|
|
|
+// #ifdef HW_ADC_MAP
|
|
|
+#if 1
|
|
|
#include "api/api_adc.h"
|
|
|
+#include "py32f002b_ll_adc.h"
|
|
|
/******************************************************************************************************
|
|
|
** Defined
|
|
|
*******************************************************************************************************/
|
|
@@ -31,10 +33,65 @@
|
|
|
/*****************************************************************************************************
|
|
|
** static Function
|
|
|
******************************************************************************************************/
|
|
|
+uint16_t irq_adc[m_adc_num]; //全局变量, 防止adc采样失败数据出错
|
|
|
+uint8_t num = 0;
|
|
|
|
|
|
/*****************************************************************************************************
|
|
|
** Function
|
|
|
******************************************************************************************************/
|
|
|
+/**
|
|
|
+ * @brief ADC calibration program.
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+static void APP_AdcCalibrate(void)
|
|
|
+{
|
|
|
+#if (USE_TIMEOUT == 1)
|
|
|
+ uint32_t Timeout = 0;
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (LL_ADC_IsEnabled(ADC1) == 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ /* Enable ADC calibration */
|
|
|
+ LL_ADC_StartCalibration(ADC1);
|
|
|
+
|
|
|
+#if (USE_TIMEOUT == 1)
|
|
|
+ Timeout = ADC_CALIBRATION_TIMEOUT_MS;
|
|
|
+#endif
|
|
|
+
|
|
|
+ while (LL_ADC_IsCalibrationOnGoing(ADC1) != 0)
|
|
|
+ {
|
|
|
+#if (USE_TIMEOUT == 1)
|
|
|
+ /* Detects if the calibration has timed out */
|
|
|
+ if (LL_SYSTICK_IsActiveCounterFlag())
|
|
|
+ {
|
|
|
+ if(Timeout-- == 0)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ /* The delay between the end of ADC calibration and ADC enablement is at least 4 ADC clocks */
|
|
|
+ LL_mDelay(1);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief Enable ADC.
|
|
|
+ * @param None
|
|
|
+ * @retval None
|
|
|
+ */
|
|
|
+static void APP_AdcEnable(void)
|
|
|
+{
|
|
|
+ /* Enable ADC */
|
|
|
+ LL_ADC_Enable(ADC1);
|
|
|
+
|
|
|
+ /* The delay between ADC enablement and ADC stabilization is at least 8 ADC clocks */
|
|
|
+ LL_mDelay(1);
|
|
|
+}
|
|
|
|
|
|
/*******************************************************************
|
|
|
** Parameters:
|
|
@@ -43,14 +100,13 @@
|
|
|
*******************************************************************/
|
|
|
uint16_t hal_adc_to_voltage(uint16_t adc)
|
|
|
{
|
|
|
- UNUSED_PARAMETER(adc);
|
|
|
return 0;
|
|
|
}
|
|
|
bool hal_adc_value(uint8_t id, uint16_t* valp)
|
|
|
{
|
|
|
- UNUSED_PARAMETER(id);
|
|
|
- UNUSED_PARAMETER(valp);
|
|
|
- return false;
|
|
|
+ if(id >= m_adc_num) return false;
|
|
|
+ valp = irq_adc[id];
|
|
|
+ return true;
|
|
|
}
|
|
|
bool hal_adc_start_scan(void)
|
|
|
{
|
|
@@ -58,14 +114,87 @@ bool hal_adc_start_scan(void)
|
|
|
}
|
|
|
bool hal_adc_init(void)
|
|
|
{
|
|
|
- return false;
|
|
|
+ uint8_t id;
|
|
|
+
|
|
|
+ LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);
|
|
|
+
|
|
|
+ for(id=0; id<m_adc_num; id++){
|
|
|
+ get_gpio_rcc(m_adc_map[id].pin);
|
|
|
+ LL_GPIO_SetPinMode(get_gpio_port(m_adc_map[id].pin), get_gpio_pin(m_adc_map[id].pin), LL_GPIO_MODE_ANALOG);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Set ADC clock to pclk/4 */
|
|
|
+ LL_ADC_SetClock(ADC1, LL_ADC_CLOCK_SYNC_PCLK_DIV4);
|
|
|
+
|
|
|
+ /* Set ADC resolution to 12 bit */
|
|
|
+ LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);
|
|
|
+
|
|
|
+ /* ADC conversion data alignment: right aligned */
|
|
|
+ LL_ADC_SetDataAlignment(ADC1, LL_ADC_DATA_ALIGN_RIGHT);
|
|
|
+
|
|
|
+ /* No ADC low power mode activated */
|
|
|
+ LL_ADC_SetLowPowerMode(ADC1, LL_ADC_LP_MODE_NONE);
|
|
|
+
|
|
|
+ /* Sampling time 239.5 ADC clock cycles */
|
|
|
+ LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_239CYCLES_5);
|
|
|
+
|
|
|
+ /* ADC regular group conversion trigger from external IP: TIM1 TRGO. */
|
|
|
+ LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_EXT_TIM1_TRGO);
|
|
|
+
|
|
|
+ /* Set Trigger edge to rising edge */
|
|
|
+ LL_ADC_REG_SetTriggerEdge(ADC1, LL_ADC_REG_TRIG_EXT_RISING);
|
|
|
+
|
|
|
+ /* Set ADC conversion mode to single mode: one conversion per trigger */
|
|
|
+ LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_SINGLE);
|
|
|
+
|
|
|
+ /* ADC regular group behavior in case of overrun: data overwritten */
|
|
|
+ LL_ADC_REG_SetOverrun(ADC1, LL_ADC_REG_OVR_DATA_OVERWRITTEN);
|
|
|
+
|
|
|
+ /* Disable ADC regular group sequencer discontinuous mode */
|
|
|
+ LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE);
|
|
|
+ for(id=0; id<m_adc_num; id++){
|
|
|
+ if(id == 0){
|
|
|
+ LL_ADC_REG_SetSequencerChannels(ADC1, ADC_CH_ATT(id));
|
|
|
+ }else{
|
|
|
+ LL_ADC_REG_SetSequencerChAdd(ADC1, ADC_CH_ATT(id));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Dose not enable internal conversion channel */
|
|
|
+ LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_VREFINT );
|
|
|
+
|
|
|
+ /* Enable EOC IT */
|
|
|
+ LL_ADC_EnableIT_EOC(ADC1);
|
|
|
+
|
|
|
+ NVIC_SetPriority(ADC_COMP_IRQn,1);
|
|
|
+ NVIC_EnableIRQ(ADC_COMP_IRQn);
|
|
|
+
|
|
|
+ /* ADC automatic self-calibration */
|
|
|
+ APP_AdcCalibrate();
|
|
|
+
|
|
|
+ /* Enable ADC */
|
|
|
+ APP_AdcEnable();
|
|
|
+
|
|
|
+ /* Start ADC conversion (if it is software triggered then start conversion directly) */
|
|
|
+ LL_ADC_REG_StartConversion(ADC1);
|
|
|
+ return true;
|
|
|
}
|
|
|
bool hal_adc_deinit(void)
|
|
|
{
|
|
|
+ LL_ADC_Disable(ADC1);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+/******************************************************************************/
|
|
|
+/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
|
|
+/******************************************************************************/
|
|
|
+void ADC_COMP_IRQHandler(void)
|
|
|
+{
|
|
|
+ /* Clear ADC EOC IT flag */
|
|
|
+ LL_ADC_ClearFlag_EOC(ADC1);
|
|
|
+ irq_adc[num++]=ADC1->DR;
|
|
|
+ if(num >= m_adc_num) i = 0;
|
|
|
+}
|
|
|
#endif
|
|
|
|
|
|
|