Adc_NATION_N32G45X/Src/AdcNation.c

86 lines
2.2 KiB
C

//
// Created by cfif on 07.09.22.
//
#include <SystemDelayInterface.h>
#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;
}