Adc_Flagchip_FC7240/Src/AdcFlagchip.c

119 lines
3.8 KiB
C

//
// Created by cfif on 07.09.22.
//
#include <SystemDelayInterface.h>
#include "AdcFlagchip.h"
#define VREF 5.0F
static const uint8_t DUMMY_BYTE = 0xFF;
void Get_ADC_Result(tAdcFlagchip *env) {
osMessageQueuePut(env->txAccessQueue, &DUMMY_BYTE, 0, 0);
}
void ADC_Initial(
tAdcFlagchip *env,
ADC_InstanceType ADCx, // ADC_INSTANCE_0, ADC_INSTANCE_1
DMA_ChannelType ADC_DMA_CHANNEL, // DMA_CHANNEL_0 .. DMA_CHANNEL_15
IRQn_Type IRQ_DMA,
uint8_t IRQ_DMA_PRIORITY,
uint8_t IRQ_DMA_CHANNEL_PRIORITY,
const uint32_t *DMA_BUF,
uint8_t num_aChannels,
ADC_ChannelCfgType *s_aChannels,
int32_t offset,
double mux,
double div,
ADC_ConvCompleteCallbackType Bsp_ADC_HandleResult
) {
env->ADCx = ADCx;
env->DMA_BUF = (uint32_t *) DMA_BUF;
env->offset = offset;
env->div = div;
env->mux = mux;
env->num_aChannels = num_aChannels;
env->txAccessQueue = osMessageQueueNew(1, 1, NULL);
env->s_tAdcInitCfg.eResolution = ADC_RESOLUTION_12_BIT, //!< 12 bit resolution
env->s_tAdcInitCfg.eAlign = ADC_ALIGN_RIGHT, //!< Align right
env->s_tAdcInitCfg.eTriggerMode = ADC_TRIGMODE_SW, //!< Software trigger
env->s_tAdcInitCfg.bWaitEnable = false; //!< Disable wait conversion mode
env->s_tAdcInitCfg.bCalEnable = false;
env->s_tAdcInitCfg.s32CalOffset = 0U;
env->s_tAdcInitCfg.s32CalGain = 0U;
env->s_tAdcInitCfg.bSequenceGroupModeEnable = false; //!< Disable sequence group mode
env->s_tAdcInitCfg.eTrgLatchUnitPri = TRG_LATCH_UNIT_PRI_ROUND_ROBIN; //!< Round robin priority
env->s_tAdcInitCfg.eClockDivider = ADC_CLOCK_DIV_1; //!< Adc clock divided by 1
env->s_tAdcInitCfg.eSequenceMode = ADC_SEQMODE_SINGLE; //!< Single sequence mode
env->s_tAdcInitCfg.eOverrunMode = ADC_OVERRUN_MODE_PRESERVE; //!< When overrun occurred, the old conversion data are preserved
env->s_tAdcInitCfg.eVoltageRef = ADC_REF_INTERNAL; //!< Use internal reference
env->s_tAdcInitCfg.bHwAvgEnable = false; //!< Disable averaging functionality
env->s_tAdcInitCfg.eHwAverage = ADC_AVERAGE_4; //!< Selection for number of samples used for averaging
env->s_tAdcInitCfg.aSampleTimes[0] = 4U;
env->s_tAdcInitCfg.aSampleTimes[1] = 10U;
env->s_tAdcInitCfg.aSampleTimes[2] = 40U;
env->s_tAdcInitCfg.aSampleTimes[3] = 80U;
env->s_tAdcDmaCfg.bDmaEnable = true;
env->s_tAdcDmaCfg.eSeqGroupIndex = ADC_SEQUENCE_GROUP_0;
env->s_tAdcDmaCfg.eDmaInstance = DMA_INSTANCE_0;
env->s_tAdcDmaCfg.eDmaChannel = ADC_DMA_CHANNEL;
env->s_tAdcDmaCfg.u8ChannelPriority = IRQ_DMA_CHANNEL_PRIORITY;
env->s_tAdcDmaCfg.pResultBuffer = (void *) ((uint32_t) DMA_BUF);
env->s_tAdcDmaCfg.pConvCompleteNotify = Bsp_ADC_HandleResult;
ADC_Init(ADCx, &env->s_tAdcInitCfg);
ADC_InitChannel(ADCx, s_aChannels, num_aChannels);
ADC_InitDmaChannel(ADCx, &env->s_tAdcDmaCfg);
ADC_Enable(ADC_INSTANCE_0);
NVIC_SetPriorityGrouping(NVIC_PRIORITY_GROUP_4);
NVIC_EnableIRQ(IRQ_DMA);
NVIC_SetPriority(DMA_Error_IRQn, IRQ_DMA_PRIORITY);
NVIC_SetPriority(IRQ_DMA, IRQ_DMA_PRIORITY);
}
static float *vAdcGet(tAdcFlagchip *env, uint32_t timeout) {
ADC_Start(env->ADCx);
uint8_t res;
uint16_t sent = osMessageQueueGet(env->txAccessQueue, &res, 0, timeout);
if (sent == osOK) {
for (uint8_t i = 0; i < env->num_aChannels; ++i) {
env->pVoltageBuffer[i] = (float) env->DMA_BUF[i] / ((1U << 12U) - 1U) * VREF;
}
}
return env->pVoltageBuffer;
}
tAdcIO vAdcGetIo(tAdcFlagchip *env) {
tAdcIO io = {
.env = env,
.get = (AdcIOTransaction) vAdcGet,
};
return io;
}