| | |
| | | /* |
| | | * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and |
| | | * Copyright (c) 2019-2025 Beijing Hanwei Innovation Technology Ltd. Co. and |
| | | * its subsidiaries and affiliates (collectly called MKSEMI). |
| | | * |
| | | * All rights reserved. |
| | |
| | | return DRV_ERROR; |
| | | } |
| | | |
| | | // check if ADC is using by HW or not |
| | | if (adc_handle.base->STATUS & ADC_STATUS_BUSY_MSK) |
| | | if (adc_handle.state == ADC_STATE_BUSY) |
| | | { |
| | | return DRV_BUSY; |
| | | } |
| | |
| | | |
| | | /* If the sampling rate setting exceeds the conversion rate threshold, the maximum sampling rate is used by default */ |
| | | uint32_t rate = (adc_clk == ADC_CLK_LOW_FREQ) ? ((config->rate < ADC_CLK_L_MAX_SAMPLE_RATE) ? config->rate : ADC_CLK_L_MAX_SAMPLE_RATE) |
| | | : (config->rate < ADC_CLK_H_MAX_SAMPLE_RATE ? config->rate : ADC_CLK_H_MAX_SAMPLE_RATE); |
| | | : (config->rate < ADC_CLK_H_MAX_SAMPLE_RATE ? config->rate : ADC_CLK_H_MAX_SAMPLE_RATE); |
| | | |
| | | /* If the sample rate is set to 0, no frequency division */ |
| | | uint16_t div = (uint16_t)((adc_clk / ((rate == 0) ? 1 : rate)) - 1); |
| | |
| | | /* If the external reference voltage driving capability is insufficient */ |
| | | /* It is recommended to enable this configuration */ |
| | | // val |= (9 << 1) | (1 << 4); |
| | | val |= (1 << 9) | (7 << 5) | (1 << 4); |
| | | } |
| | | REG_WRITE(0x4000062C, val); |
| | | |
| | |
| | | |
| | | int adc_close(void) |
| | | { |
| | | // check if ADC is using by HW or not |
| | | if ((adc_handle.base->STATUS & ADC_STATUS_BUSY_MSK) && (adc_handle.state != ADC_STATE_BUSY)) |
| | | if (adc_handle.state == ADC_STATE_BUSY) |
| | | { |
| | | return DRV_BUSY; |
| | | } |
| | |
| | | // update state |
| | | switch (adc_handle.state) |
| | | { |
| | | case ADC_STATE_READY: |
| | | adc_handle.state = ADC_STATE_BUSY; |
| | | break; |
| | | case ADC_STATE_BUSY: |
| | | int_unlock(lock); |
| | | return DRV_BUSY; |
| | | case ADC_STATE_RESET: |
| | | case ADC_STATE_TIMEOUT: |
| | | case ADC_STATE_ERROR: |
| | | int_unlock(lock); |
| | | return DRV_ERROR; |
| | | case ADC_STATE_READY: |
| | | adc_handle.state = ADC_STATE_BUSY; |
| | | break; |
| | | case ADC_STATE_BUSY: |
| | | int_unlock(lock); |
| | | return DRV_BUSY; |
| | | case ADC_STATE_RESET: |
| | | case ADC_STATE_TIMEOUT: |
| | | case ADC_STATE_ERROR: |
| | | int_unlock(lock); |
| | | return DRV_ERROR; |
| | | } |
| | | |
| | | adc_handle.data = data; |
| | |
| | | |
| | | dma_open(adc_handle.dma_ch, &adc_dma_cfg); |
| | | dma_transfer(adc_handle.dma_ch, (uint32_t *)&adc_handle.base->DATA, data, number, adc_dma_callback); |
| | | |
| | | adc_handle.base->DMA_EN = ADC_DMA_EN_MSK; |
| | | |
| | | // start conversion |
| | | adc_handle.base->CTRL2 = ADC_CTRL2_CONV_EN_MSK; |
| | | #endif |
| | |
| | | { |
| | | if (adc_handle.mode == ADC_MODE_CONTINUE) |
| | | { |
| | | adc_handle.base->DMA_EN &= ~ADC_DMA_EN_MSK; |
| | | |
| | | // stop conversion |
| | | adc_handle.base->CTRL2 &= ~ADC_CTRL2_CONV_EN_MSK; |
| | | } |
| | |
| | | adc_close(); |
| | | } |
| | | |
| | | static void adc_continue_callback(void *data, uint32_t number) |
| | | { |
| | | |
| | | LOG_INFO(TRACE_MODULE_APP, "Chip adc callback %d degree\r\n", data); |
| | | } |
| | | int16_t battery_monitor_get(void) |
| | | { |
| | | #define NUM_SAMPLES (3) |
| | | |
| | | uint32_t sample[NUM_SAMPLES]; |
| | | adc_get(&sample[0], NUM_SAMPLES, adc_continue_callback); |
| | | adc_get(&sample[0], NUM_SAMPLES, NULL); |
| | | |
| | | int32_t sum = 0; |
| | | for (int i = 0; i < NUM_SAMPLES; i++) |