// // Created by cfif on 07.09.22. // #include #include "AdcArtery.h" tAdcArtery ADC_Initial( adc_type *ADCx, adc_channel_select_type ADC_Channel, int32_t offset, int32_t mux, int32_t div ) { adc_common_config_type adc_common_struct; adc_base_config_type adc_base_struct; // nvic_irq_enable(ADC1_2_3_IRQn, 0, 0); adc_common_default_para_init(&adc_common_struct); /* config combine mode */ adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE; /* config division,adcclk is division by hclk */ adc_common_struct.div = ADC_HCLK_DIV_17; /* config common dma mode,it's not useful in independent mode */ adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE; /* config common dma request repeat */ adc_common_struct.common_dma_request_repeat_state = FALSE; /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */ adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_20CYCLES; /* config inner temperature sensor and vintrv */ adc_common_struct.tempervintrv_state = FALSE; /* config voltage battery */ adc_common_struct.vbat_state = FALSE; adc_common_config(&adc_common_struct); adc_base_default_para_init(&adc_base_struct); adc_base_struct.sequence_mode = TRUE; adc_base_struct.repeat_mode = TRUE; adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT; adc_base_struct.ordinary_channel_length = 1; adc_base_config(ADCx, &adc_base_struct); adc_resolution_set(ADCx, ADC_RESOLUTION_12B); /* config ordinary channel */ adc_ordinary_channel_set(ADCx, ADC_Channel, 1, ADC_SAMPLETIME_640_5); /* config ordinary trigger source and trigger edge */ adc_ordinary_conversion_trigger_set(ADCx, ADC_ORDINARY_TRIG_TMR1CH1, ADC_ORDINARY_TRIG_EDGE_NONE); /* config dma mode,it's not useful when common dma mode is use */ adc_dma_mode_enable(ADCx, FALSE); /* config dma request repeat,it's not useful when common dma mode is use */ adc_dma_request_repeat_enable(ADCx, FALSE); /* each ordinary channel conversion set occe flag */ adc_occe_each_conversion_enable(ADCx, TRUE); /* enable adc overflow interrupt */ // adc_interrupt_enable(ADCx, ADC_OCCO_INT, TRUE); /* adc enable */ adc_enable(ADCx, TRUE); while (adc_flag_get(ADCx, ADC_RDY_FLAG) == RESET); /* adc calibration */ adc_calibration_init(ADCx); while (adc_calibration_init_status_get(ADCx)); adc_calibration_start(ADCx); while (adc_calibration_status_get(ADCx)); tAdcArtery adc = { .ADCx = ADCx, .ADC_Channel = ADC_Channel, .offset = offset, .div = div, .mux = mux }; return adc; } static uint16_t vAdcGet(tAdcArtery *env, uint32_t timeout) { uint32_t endMs = SystemGetMs() + timeout; uint16_t data; adc_ordinary_software_trigger_enable(env->ADCx, TRUE); while (adc_flag_get(env->ADCx, ADC_OCCE_FLAG) == RESET) { if (SystemGetMs() > endMs) { //todo error return 0; } } data = adc_ordinary_conversion_data_get(env->ADCx); adc_flag_clear(env->ADCx, ADC_OCCO_FLAG); int64_t projected = ((data + env->offset) * env->mux / env->div); return projected; } tAdcIO vAdcGetIo(tAdcArtery *env) { tAdcIO io = { .env = env, .get = (AdcIOTransaction) vAdcGet, }; return io; }