86 lines
2.2 KiB
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;
|
|
} |