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