WXK
2024-09-18 05e2e954bd127de378a9d1dfbb0ed95d725aad63
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
 * @file     pan_hal_adc.c
 * @version  V0.0.0
 * $Revision: 1 $
 * $Date:    23/09/10 $
 * @brief    Panchip series ADC (Analog-to-Digital Converter) HAL (Hardware Abstraction Layer) source file.
 * @note
 * Copyright (C) 2023 Panchip Technology Corp. All rights reserved.
 *****************************************************************************/
#include "pan_hal.h"
#include "freertos.h"
#include "semphr.h"
 
SemaphoreHandle_t xSemaphore = NULL;
 
void HAL_ADC_Init(ADC_HandleTypeDef *pADC)
{
    if (xSemaphore == NULL) {
        xSemaphore = xSemaphoreCreateMutex();
    } else {
        return;
    }
    
    /* Setting input range (0 ~ 1.2V) as default 
     *  Note: if the input voltage over 1.2V, should
     *  adopt r1/r1+r2 mothod
     */
    CLK_APB1PeriphClockCmd(CLK_APB1Periph_ADC, ENABLE);
    ADC_Init(ADC, true);
    ADC_SelInputRange(ADC,ADC_INPUTRANGE_LOW);
    CLK_APB1PeriphClockCmd(CLK_APB1Periph_ADC, DISABLE);
}
 
 
void HAL_ADC_DeInit(ADC_HandleTypeDef *pADC)
{
    pADC->id = ADC_IDLE;
}
 
int32_t HAL_ADC_GetValue(ADC_HandleTypeDef *pADC, void *value)
{
    uint32_t ch_bit = BIT(pADC->id);
    uint32_t result_code;
    
    if ((pADC->id > ADC_CH_BATTERY) || ((pADC->id > ADC_CH7) && (pADC->id < ADC_CH_TEMP))) {
        return PAN_HAL_IO_ERROR;
    }
    
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
    
    /* Open clock related adc */
    CLK_APB1PeriphClockCmd(CLK_APB1Periph_ADC, ENABLE);
    
    /* Normal external adc channel sample */
    if (pADC->id <= ADC_CH7) {
        
        uint16_t temp_buf[32];
        
        ADC_Open(ADC,ch_bit);
        /* Prepare ADC vbg calib paramter because currnet soc battery volatage has changed in a lot of application*/
        ADC_PrepareVbgCalibData(ADC);
        ADC_PowerOn(ADC);
        
        /* Delay a while to wait adc stable */
        if (m_adc_opt.chip_info >= 0x20) {
            SYS_delay_10nop(500);   // Delay 100us+
        } else {
            SYS_delay_10nop(50000); // Delay 15ms+
        }
        
        /* It can be optimized by user */
        result_code = ADC_SamplingCodeTrimMean(ADC, temp_buf, 32, 8);
        
        /* Convert ADC sampling code to voltage */
        *(float *)value = ADC_OutputVoltage(ADC, result_code);
        
        ADC_PowerDown(ADC);
 
    } else if (pADC->id == ADC_CH_BATTERY) {
        *(uint16_t *)value = ADC_MeasureSocVbat(ADC);
    } else if (pADC->id == ADC_CH_TEMP) {
        *(float *)value = ADC_MeasureSocTemperature(ADC);
    }
    
    /* Open clock related adc */
    CLK_APB1PeriphClockCmd(CLK_APB1Periph_ADC, DISABLE);
    xSemaphoreGive(xSemaphore);
    
    return PAN_HAL_SUCCESS;
}