in IndustrialDeviceController/Software/MT3620_IDC_RTApp/lib/ADC.c [118:230]
static int32_t ADC_Read(
AdcContext *handle, void (*callback)(int32_t status),
uint32_t dmaFifoSize, ADC_Data *data,
uint32_t *rawData, uint16_t channel,
bool periodic, uint32_t frequency,
uint16_t referenceVoltage)
{
handle->callback = callback;
handle->fifoSize = dmaFifoSize;
handle->rawData = rawData;
handle->data = data;
mt3620_adc_ctl3_t ctl3 = { .mask = mt3620_adc->adc_ctl3 };
ctl3.comp_time_delay = 1;
ctl3.comp_preamp_current = 1;
ctl3.comp_preamp_en = 1;
ctl3.dither_en = 1;
ctl3.dither_step_size = 2;
ctl3.auxadc_in_mux_en = 1;
ctl3.vcm_gen_en = 1;
ctl3.auxadc_clk_gen_en = 1;
ctl3.auxadc_pmu_clk_inv = 0;
ctl3.auxadc_clk_src = 0;
if (referenceVoltage > ADC_VREF_1V8_MIN && referenceVoltage < ADC_VREF_1V8_MAX) {
ctl3.vcm_azure_en = 1;
}
else if (referenceVoltage > ADC_VREF_2V5_MIN && referenceVoltage < ADC_VREF_2V5_MAX) {
ctl3.vcm_azure_en = 0;
}
else if (referenceVoltage > ADC_VREF_1V8_MAX && referenceVoltage < ADC_VREF_2V5_MIN) {
ctl3.vcm_azure_en = ADC_VCM_AZURE_EN_DEF;
} else {
return ERROR_ADC_VREF_UNSUPPORTED;
};
mt3620_adc->adc_ctl3 = ctl3.mask;
mt3620_adc_ctl0_t ctl0 = { .mask = mt3620_adc->adc_ctl0 };
ctl0.adc_fsm_en = 0;
ctl0.reg_avg_mode = 0;
ctl0.reg_t_ch = 8;
ctl0.pmode_en = 0;
ctl0.reg_t_init = 20;
ctl0.reg_ch_map = 0;
mt3620_adc->adc_ctl0 = ctl0.mask;
#ifdef ADC_FIFO_CLEAR
while (true) {
mt3620_adc_fifo_debug16_t debug16 = (mt3620_adc_fifo_debug16_t)mt3620_adc->adc_fifo_debug16;
if (debug16.read_ptr == debug16.write_ptr) {
break;
}
(void)mt3620_adc->adc_fifo_rbr;
}
#endif
/* Wait for time specified in datasheet */
GPT *timer = GPT_Open(MT3620_UNIT_GPT3, MT3620_GPT_3_LOW_SPEED, GPT_MODE_NONE);
GPT_WaitTimer_Blocking(timer, 50, GPT_UNITS_MICROSEC);
GPT_Close(timer);
/* Set trigger level based on number of channels selected */
uint8_t numChannels = ADC_CountChannels(channel);
handle->channelsCount = numChannels;
//Check fifo size is at least as great as the number of channels
if (handle->fifoSize < numChannels) {
return ERROR_ADC_FIFO_INVALID;
}
//Set DMA registers
mt3620_dma_global->ch_en_set = (1 << MT3620_ADC_DMA_CHANNEL);
MT3620_DMA_FIELD_WRITE(MT3620_ADC_DMA_CHANNEL, start, str, false);
mt3620_dma[MT3620_ADC_DMA_CHANNEL].pgmaddr = handle->rawData;
mt3620_dma[MT3620_ADC_DMA_CHANNEL].ffsize = handle->fifoSize;
if (handle->fifoSize == 1) {
mt3620_dma[MT3620_ADC_DMA_CHANNEL].count = 1;
} else {
mt3620_dma[MT3620_ADC_DMA_CHANNEL].count = ((3 * mt3620_dma[MT3620_ADC_DMA_CHANNEL].ffsize) / 4);
}
mt3620_dma[MT3620_ADC_DMA_CHANNEL].fixaddr = (void*)&mt3620_adc->adc_fifo_rbr;
mt3620_dma[MT3620_ADC_DMA_CHANNEL].swptr = 0;
MT3620_DMA_FIELD_WRITE(MT3620_ADC_DMA_CHANNEL, ackint, ack, 1);
MT3620_ADC_FIELD_WRITE(adc_fifo_dma_en, rx_dma_en, 1);
mt3620_dma_con_t con = { .mask = mt3620_dma[MT3620_ADC_DMA_CHANNEL].con };
con.size = 2;
con.dir = 1;
con.dreq = true;
con.iten = true;
con.toen = false;
mt3620_dma[MT3620_ADC_DMA_CHANNEL].con = con.mask;
MT3620_DMA_FIELD_WRITE(MT3620_ADC_DMA_CHANNEL, start, str, true);
/* Select ADC channel and enable ADC finite state machine */
ctl0.mask = mt3620_adc->adc_ctl0;
if (periodic) {
if (frequency > ADC_CLK_FREQUENCY) {
return ERROR_ADC_FREQUENCY_UNSUPPORTED;
}
mt3620_adc->reg_period = (ADC_CLK_FREQUENCY / frequency) - 1;
ctl0.pmode_en = periodic;
}
ctl0.reg_ch_map = channel;
ctl0.adc_fsm_en = 1;
mt3620_adc->adc_ctl0 = ctl0.mask;
return ERROR_NONE;
}