// // Created by cfif on 07.09.22. // #include #include "Adc_AC7840x.h" #define ADC0_INDEX (0U) #define ADC1_INDEX (1U) #define ADC0_DMA_CHANNEL (0U) #define ADC1_DMA_CHANNEL (1U) tAdcGlobalAC7840x adcGlobalAC7840x; void DmaInit() { dma_channel_config_t dma_adc0_config; dma_channel_config_t dma_adc1_config; DMA_DRV_Init(&adcGlobalAC7840x.g_dma_state, NULL, NULL, 0); dma_adc0_config.channelPriority = DMA_CHN_PRIORITY_LOW; dma_adc0_config.virtChnConfig = ADC0_DMA_CHANNEL; dma_adc0_config.source = DMA_REQ_ADC0; dma_adc0_config.callback = NULL; dma_adc0_config.enableTrigger = false; DMA_DRV_ChannelInit(&adcGlobalAC7840x.g_dma_adc0_state, &dma_adc0_config); dma_adc1_config.channelPriority = DMA_CHN_PRIORITY_LOW; dma_adc1_config.virtChnConfig = ADC1_DMA_CHANNEL; dma_adc1_config.source = DMA_REQ_ADC1; dma_adc1_config.callback = NULL; dma_adc1_config.enableTrigger = false; DMA_DRV_ChannelInit(&adcGlobalAC7840x.g_dma_adc1_state, &dma_adc1_config); } void ADC0_DmaStart() { DMA_DRV_ConfigTransfer(ADC0_DMA_CHANNEL, DMA_TRANSFER_PERIPH2MEM, (uint32_t) (ADC0->RDR), (uint32_t) adcGlobalAC7840x.g_adc0_array, DMA_TRANSFER_SIZE_2B, adcGlobalAC7840x.ADC0_CHANNEL_NUM * 2); DMA_DRV_SetSrcAddr(ADC0_DMA_CHANNEL, (uint32_t) (&(ADC0->RDR[0])), (uint32_t) (&(ADC0->RDR[adcGlobalAC7840x.ADC0_CHANNEL_NUM]))); DMA_DRV_SetSrcOffset(ADC0_DMA_CHANNEL, 4); DMA_DRV_SetCircularMode(ADC0_DMA_CHANNEL, true); DMA_DRV_StartChannel(ADC0_DMA_CHANNEL); ADC_DRV_SoftwareStartRegularConvert(ADC0_INDEX); } void ADC1_DmaStart() { DMA_DRV_ConfigTransfer(ADC1_DMA_CHANNEL, DMA_TRANSFER_PERIPH2MEM, (uint32_t) (ADC1->RDR), (uint32_t) adcGlobalAC7840x.g_adc1_array, DMA_TRANSFER_SIZE_2B, adcGlobalAC7840x.ADC1_CHANNEL_NUM * 2); DMA_DRV_SetSrcAddr(ADC1_DMA_CHANNEL, (uint32_t) (&(ADC1->RDR[0])), (uint32_t) (&(ADC1->RDR[adcGlobalAC7840x.ADC1_CHANNEL_NUM]))); DMA_DRV_SetSrcOffset(ADC1_DMA_CHANNEL, 4); DMA_DRV_SetCircularMode(ADC1_DMA_CHANNEL, true); DMA_DRV_StartChannel(ADC1_DMA_CHANNEL); ADC_DRV_SoftwareStartRegularConvert(ADC1_INDEX); } void ADC_ConfigChannel(const uint32_t instance, const adc_sequence_t seq, adc_inputchannel_t channel) { // ADCCLK = FCLK/clockDivide = 60/6 = 10MHz // = (SPT+ resolution12/10/8) ADCCLK + 5 FCLK = (5+12)/10+5/60 - 1.78us // 12bit - 1Msps 10bit - 1.2Msps 8bit - 1.4Msps adc_chan_config_t adcChConfig; ADC_DRV_InitChanStruct(&adcChConfig); adcChConfig.channel = channel; adcChConfig.spt = ADC_SPT_CLK_5; adcChConfig.interruptEn = false; ADC_DRV_ConfigChan(instance, seq, &adcChConfig); } tAdcAC7840x ADC0_Add(PORT_Type *port, uint32_t pinMask, adc_sequence_t sequence, adc_inputchannel_t channel, int32_t offset, double mux, double div) { GPIO_DRV_SetMuxModeSel(port, pinMask, PORT_PIN_DISABLED); ++adcGlobalAC7840x.ADC0_CHANNEL_NUM; adcGlobalAC7840x.adc0Config.regularSequenceLength = adcGlobalAC7840x.ADC0_CHANNEL_NUM; ADC_ConfigChannel(ADC0_INDEX, sequence, channel); #ifdef ACCESS_ADC tAdcAC7840x adc = { .offset = offset, .div = div, .mux = mux, .index = adcGlobalAC7840x.ADC0_CHANNEL_NUM, .g_adc_array = adcGlobalAC7840x.g_adc0_array, .access = osMutexNew(NULL) }; #else tAdcAC7840x adc = { .offset = offset, .div = div, .mux = mux, .index = adcGlobalAC7840x.ADC1_CHANNEL_NUM, .g_adc_array = adcGlobalAC7840x.g_adc0_array, }; #endif return adc; } tAdcAC7840x ADC1_Add(PORT_Type *port, uint32_t pinMask, adc_sequence_t sequence, adc_inputchannel_t channel, int32_t offset, double mux, double div) { GPIO_DRV_SetMuxModeSel(port, pinMask, PORT_PIN_DISABLED); ++adcGlobalAC7840x.ADC1_CHANNEL_NUM; adcGlobalAC7840x.adc0Config.regularSequenceLength = adcGlobalAC7840x.ADC1_CHANNEL_NUM; ADC_ConfigChannel(ADC1_INDEX, sequence, channel); #ifdef ACCESS_ADC tAdcAC7840x adc = { .offset = offset, .div = div, .mux = mux, .index = adcGlobalAC7840x.ADC1_CHANNEL_NUM, .g_adc_array = adcGlobalAC7840x.g_adc1_array, .access = osMutexNew(NULL) }; #else tAdcAC7840x adc = { .ADCx = ADCx, .ADC_Channel = ADC_Channel, .offset = offset, .div = div, .mux = mux, .index = adcGlobalAC7840x.ADC1_CHANNEL_NUM, .g_adc_array = adcGlobalAC7840x.g_adc1_array, }; #endif return adc; } void ADC_StartInit(tAdcAC7840x *env) { adcGlobalAC7840x.ADC0_CHANNEL_NUM = 0; ADC_DRV_Init(ADC0_INDEX); ADC_DRV_InitConverterStruct(&adcGlobalAC7840x.adc0Config); adcGlobalAC7840x.adc0Config.clockDivide = ADC_CLK_DIVIDE_6; adcGlobalAC7840x.adc0Config.resolution = ADC_RESOLUTION_12BIT; adcGlobalAC7840x.adc0Config.regularTrigger = ADC_TRIGGER_INTERNAL; adcGlobalAC7840x.adc0Config.injectTrigger = ADC_TRIGGER_INTERNAL; adcGlobalAC7840x.adc0Config.dmaEnable = true; adcGlobalAC7840x.adc0Config.voltageRef = ADC_VOLTAGEREF_VREF; adcGlobalAC7840x.adc0Config.scanModeEn = true; adcGlobalAC7840x.adc0Config.continuousModeEn = true; adcGlobalAC7840x.adc0Config.regularDiscontinuousModeEn = false; adcGlobalAC7840x.adc0Config.injectDiscontinuousModeEn = false; adcGlobalAC7840x.adc0Config.injectAutoModeEn = false; adcGlobalAC7840x.adc0Config.intervalModeEn = false; adcGlobalAC7840x.adc0Config.regularDiscontinuousNum = 0; adcGlobalAC7840x.adc0Config.regularSequenceLength = adcGlobalAC7840x.ADC0_CHANNEL_NUM; adcGlobalAC7840x.adc0Config.injectSequenceLength = 0; adcGlobalAC7840x.adc0Config.powerEn = true; adcGlobalAC7840x.ADC1_CHANNEL_NUM = 0; ADC_DRV_Init(ADC1_INDEX); ADC_DRV_InitConverterStruct(&adcGlobalAC7840x.adc1Config); adcGlobalAC7840x.adc1Config.clockDivide = ADC_CLK_DIVIDE_6; adcGlobalAC7840x.adc1Config.resolution = ADC_RESOLUTION_12BIT; adcGlobalAC7840x.adc1Config.regularTrigger = ADC_TRIGGER_INTERNAL; adcGlobalAC7840x.adc1Config.injectTrigger = ADC_TRIGGER_INTERNAL; adcGlobalAC7840x.adc1Config.dmaEnable = true; adcGlobalAC7840x.adc1Config.voltageRef = ADC_VOLTAGEREF_VREF; adcGlobalAC7840x.adc1Config.scanModeEn = true; adcGlobalAC7840x.adc1Config.continuousModeEn = true; adcGlobalAC7840x.adc1Config.regularDiscontinuousModeEn = false; adcGlobalAC7840x.adc1Config.injectDiscontinuousModeEn = false; adcGlobalAC7840x.adc1Config.injectAutoModeEn = false; adcGlobalAC7840x.adc1Config.intervalModeEn = false; adcGlobalAC7840x.adc1Config.regularDiscontinuousNum = 0; adcGlobalAC7840x.adc1Config.regularSequenceLength = adcGlobalAC7840x.ADC1_CHANNEL_NUM; adcGlobalAC7840x.adc1Config.injectSequenceLength = 0; adcGlobalAC7840x.adc1Config.powerEn = true; } void ADC_EndInit() { ADC_DRV_ConfigConverter(ADC0_INDEX, &adcGlobalAC7840x.adc0Config); ADC_DRV_ConfigConverter(ADC1_INDEX, &adcGlobalAC7840x.adc1Config); } static uint32_t vAdcGet(tAdcAC7840x *env) { #ifdef ACCESS_ADC if (osMutexAcquire(env->access, 100) == osOK) { volatile uint16_t data = env->g_adc_array[env->index]; int32_t projected = (int32_t) ((double) (data + env->offset) * env->mux / env->div); osMutexRelease(env->access); return projected; } else { return 0; } #else volatile uint16_t data = env->g_adc_array[env->index]; int32_t projected = ((data + env->offset) * env->mux / env->div); return projected; #endif } tAdcIO vAdcGetIo(tAdcAC7840x *env) { tAdcIO io = { .env = env, .get = (AdcIOTransaction) vAdcGet, }; return io; }