// // Created by cfif on 07.09.22. // #include #include "AdcNation.h" tAdcNation ADC_Initial( ADC_Module *ADCx, uint8_t ADC_Channel, int32_t mux, int32_t div, int32_t offset, uint32_t timeout ) { uint32_t endMs = SystemGetMs() + timeout; ADC_InitType ADC_InitStructure; // ADC configuration ------------------------------------------------------ ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT; ADC_InitStructure.MultiChEn = DISABLE; ADC_InitStructure.ContinueConvEn = DISABLE; ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE; ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R; ADC_InitStructure.ChsNumber = 1; ADC_Init(ADCx, &ADC_InitStructure); // Enable ADC ADC_Enable(ADCx, ENABLE); // Check ADC Ready while (ADC_GetFlagStatusNew(ADCx, ADC_FLAG_RDY) == RESET); // Start ADC calibration ADC_StartCalibration(ADCx); bool isCalibration = true; // Check the end of ADC calibration while (ADC_GetCalibrationStatus(ADCx)) { if (SystemGetMs() > endMs) { isCalibration = false; } } tAdcNation adc = { .ADCx = ADCx, .ADC_Channel = ADC_Channel, .isCalibration = isCalibration, .ratio = { .mux = mux, .div = div, .offset = offset } }; return adc; } static int32_t vAdcGet(tAdcNation *env, uint32_t timeout) { uint32_t endMs = SystemGetMs() + timeout; uint16_t data; ADC_ConfigRegularChannel(env->ADCx, env->ADC_Channel, 1, ADC_SAMP_TIME_239CYCLES5); // Start ADC Software Conversion ADC_EnableSoftwareStartConv(env->ADCx, ENABLE); while (ADC_GetFlagStatus(env->ADCx, ADC_FLAG_ENDC) == 0) { if (SystemGetMs() > endMs) { //todo error return 0; } } ADC_ClearFlag(env->ADCx, ADC_FLAG_ENDC); ADC_ClearFlag(env->ADCx, ADC_FLAG_STR); data = ADC_GetDat(env->ADCx); data = (data * env->ratio.mux) / env->ratio.div + env->ratio.offset; return data; } tAdcIO vAdcGetIo(tAdcNation *env) { tAdcIO io = { .env = env, .get = (AdcIOTransaction) vAdcGet, }; return io; }