// // 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); } tAdcFlagchip ADC_Initial( ADC_InstanceType ADCx, // ADC_INSTANCE_0, ADC_INSTANCE_1 PCC_ClkSrcType adcClock, // PCC_CLK_ADC0, PCC_CLK_ADC1 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 ) { PCC_CtrlType bSP_PCC_Config; bSP_PCC_Config.eClockName = adcClock; bSP_PCC_Config.bEn = TRUE; bSP_PCC_Config.eClkSrc = PCC_CLKGATE_SRC_FOSCDIV; bSP_PCC_Config.eDivider = PCC_CLK_DIV_BY1; PCC_SetPcc(&bSP_PCC_Config); tAdcFlagchip adc = { .ADCx = ADCx, .DMA_BUF = DMA_BUF, .offset = offset, .div = div, .mux = mux, .num_aChannels = num_aChannels, .txAccessQueue = osMessageQueueNew(1, 1, NULL), .s_tAdcInitCfg = { .eResolution = ADC_RESOLUTION_12_BIT, //!< 12 bit resolution .eAlign = ADC_ALIGN_RIGHT, //!< Align right .eTriggerMode = ADC_TRIGMODE_SW, //!< Software trigger .bWaitEnable = false, //!< Disable wait conversion mode .bCalEnable = false, .s32CalOffset = 0U, .s32CalGain = 0U, .bSequenceGroupModeEnable = false, //!< Disable sequence group mode .eTrgLatchUnitPri = TRG_LATCH_UNIT_PRI_ROUND_ROBIN, //!< Round robin priority .eClockDivider = ADC_CLOCK_DIV_1, //!< Adc clock divided by 1 .eSequenceMode = ADC_SEQMODE_SINGLE, //!< Single sequence mode .eOverrunMode = ADC_OVERRUN_MODE_PRESERVE, //!< When overrun occurred, the old conversion data are preserved .eVoltageRef = ADC_REF_INTERNAL, //!< Use internal reference .bHwAvgEnable = false, //!< Disable averaging functionality .eHwAverage = ADC_AVERAGE_4, //!< Selection for number of samples used for averaging .aSampleTimes = {4U, 10U, 40U, 80U}, //!< ADC channel sample time options }, .s_tAdcDmaCfg = { .bDmaEnable = true, .eSeqGroupIndex = ADC_SEQUENCE_GROUP_0, .eDmaInstance = DMA_INSTANCE_0, .eDmaChannel = ADC_DMA_CHANNEL, .u8ChannelPriority = IRQ_DMA_CHANNEL_PRIORITY, .pResultBuffer = (void *) ((uint32_t) DMA_BUF), .pConvCompleteNotify = Bsp_ADC_HandleResult, } }; ADC_Init(ADCx, &adc.s_tAdcInitCfg); ADC_InitChannel(ADCx, s_aChannels, num_aChannels); ADC_InitDmaChannel(ADCx, &adc.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); return adc; } 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; }