WXK
2025-02-11 e328ebef585cea2351b37117b2d5ac4978ecd3c0
keil/include/board/board.c
@@ -43,7 +43,13 @@
#include "mk_clock.h"
#include "mk_calib.h"
#include "mk_misc.h"
#ifdef UWB_EN
#include "mk_uwb.h"
#endif
#if (X38M4_AUTO_TUNE_EN == 2)
#include "mk_adc.h"
#include <math.h>
#endif
#ifdef WSF_EN
#include "wsf_nvm.h"
#endif
@@ -55,18 +61,9 @@
static enum TRACE_PORT_T user_trace_port;
#endif
#ifndef TRACE_BAUD_RATE
#define TRACE_BAUD_RATE (BAUD_115200)
#endif
struct BOARD_PARAM_T board_param = {0};
static GPIO_IRQ_HANDLER_T button_irq_handler = NULL;
static GPIO_IRQ_HANDLER_T accelerate_irq_handler=NULL;
 GPIO_IRQ_HANDLER_T _4Gusart_irq_handler=NULL;
 GPIO_IRQ_HANDLER_T pca_input_detect_irq_handler=NULL;
extern struct UART_CFG_T test_uart_cfg;
extern struct ADC_CFG_T usr_adc_cfg;
extern volatile int32_t m_EUART_DMA_RXPtr;
void board_clock_run(void)
{
    // default load cap
@@ -81,7 +78,7 @@
    calib_check(CALIB_REFPLL_DONE);
    calib_close();
    /* SYSCLK comes from XTAL */
    /* SYSCLK comes from XTAL 38.4M */
    clock_attach(SYS_CLK_SOURCE);
    /* Configure AHB clock, AHBCLK = SYSCLK/(div) */
@@ -111,21 +108,14 @@
    trace_open(port, TRACE_BAUD_RATE);
    user_trace_port = port;
#endif
//    LOG_INFO(TRACE_MODULE_APP, "Hello from MKSEMI!\r\n");
//    LOG_INFO(TRACE_MODULE_APP, "Build information %s\r\n", mk_build_inf);
}
//修改波特率函数
void board_debug_console_open_baud(enum TRACE_PORT_T port,enum UART_BAUD_T baud_rate)
{
#if TRACE_EN
    trace_open(port, baud_rate);
    user_trace_port = port;
#endif
    LOG_INFO(TRACE_MODULE_APP, "Hello from MKSEMI!\r\n");
    LOG_INFO(TRACE_MODULE_APP, "Build information %s\r\n", mk_build_inf);
}
void board_calibration_params_default(void)
{
    board_param.load_cap = 76;
    board_param.x38m4_load_cap = 76;
#ifdef UWB_EN
    board_param.tx_power_fcc[CALIB_CH9] = TX_POWER_LEVEL;
    board_param.tx_power_fcc[CALIB_CH5] = TX_POWER_LEVEL;
@@ -136,19 +126,17 @@
    board_param.peer_short_addr = 0;
#if (ANT_PATTERN == ANT_PATTERN_SQUARE)
    int16_t ant_delays_ch9[4] = {0, 0, 0, 36};
    int16_t ant_delays_ch5[4] = {0, 0, 0, 36};
    int16_t ant_delays_ch2[4] = {0, 0, 36, 0};
    int16_t ant_delays_ch9[4] = {106, 106, 106, 106};
    int16_t ant_delays_ch5[4] = {106, 106, 106, 106};
    int16_t ant_delays_ch2[4] = {106, 106, 106, 106};
    // 4-ANTs: 0, 1, 2, 3
    int16_t pdoa_delays_ch9[4] = {52, -21, -8, 0};
    int16_t pdoa_delays_ch5[4] = {52, -21, -8, 0};
    // int16_t pdoa_delays_ch5[4] = {70, -2, -0, 0};
    int16_t pdoa_delays_ch2[4] = {52, -21, -8, 0};
    int16_t pdoa_gains_ch9[4] = {94, 99, 89, 88};
    int16_t pdoa_gains_ch5[4] = {94, 99, 89, 88};
    // int16_t pdoa_gains_ch5[4] = {94, 93, 89, 98};
    int16_t pdoa_gains_ch2[4] = {94, 99, 89, 88};
    int16_t pdoa_offsets[2] = {0, 0};
@@ -156,9 +144,9 @@
#elif (ANT_PATTERN == ANT_PATTERN_TRIANGLE_REGULAR)
    int16_t ant_delays_ch9[4] = {0, 0, 0, 36};
    int16_t ant_delays_ch5[4] = {0, 0, 0, 36};
    int16_t ant_delays_ch2[4] = {0, 0, 36, 0};
    int16_t ant_delays_ch9[4] = {106, 106, 106, 106};
    int16_t ant_delays_ch5[4] = {106, 106, 106, 106};
    int16_t ant_delays_ch2[4] = {106, 106, 106, 106};
    // 3-ANTs: 3, 0, 1
    int16_t pdoa_delays_ch9[4] = {0, -21, 52};
@@ -175,9 +163,9 @@
#else
    // linear antenna array
    int16_t ant_delays_ch9[4] = {0, 0, 0, 122};
    int16_t ant_delays_ch5[4] = {0, 0, 0, 122};
    int16_t ant_delays_ch2[4] = {0, 0, 122, 0};
    int16_t ant_delays_ch9[4] = {152, 152, 152, 152};
    int16_t ant_delays_ch5[4] = {170, 170, 170, 170};
    int16_t ant_delays_ch2[4] = {170, 170, 170, 170};
#if RX_ANT_PORTS_NUM == 4
    // 4-ANTs: 0, 1, 2, 3
@@ -191,6 +179,9 @@
    int16_t pdoa_offsets[2] = {0, 0};
    board_param.pdoa_ant_space = 180;
    board_param.angle_correction[0] = 1122;
    board_param.angle_correction[1] = 3;
#elif RX_ANT_PORTS_NUM == 3
@@ -216,6 +207,9 @@
    int16_t pdoa_offsets[2] = {0, 0};
    board_param.pdoa_ant_space = 180;
    board_param.angle_correction[0] = 1229;
    board_param.angle_correction[1] = 14;
#elif RX_ANT_PORTS_NUM == 2
#if 0
@@ -239,6 +233,15 @@
#endif
    int16_t pdoa_offsets[2] = {0, 0};
    board_param.pdoa_ant_space = 180;
    board_param.angle_correction[0] = 1049;
    board_param.angle_correction[1] = -32;
    board_param.angle_correction[2] = -46;
    board_param.angle_correction[3] = 3714;
    board_param.angle_correction[4] = 103;
    board_param.angle_correction[5] = -131;
    board_param.angle_correction[6] = 872;
    board_param.angle_correction[7] = -283;
#endif
#endif
@@ -268,9 +271,9 @@
{
    board_calibration_params_default();
#ifdef WSF_EN
    if (TRUE == WsfNvmReadData(BOARD_LOAD_CAP, &board_param.load_cap, sizeof(board_param.load_cap), 0))
    if (TRUE == WsfNvmReadData(BOARD_X38M4_LOAD_CAP, &board_param.x38m4_load_cap, sizeof(board_param.x38m4_load_cap), 0))
    {
        board_param.flag |= (1 << BOARD_LOAD_CAP);
        board_param.flag |= (1 << BOARD_X38M4_LOAD_CAP);
    }
    if (TRUE == WsfNvmReadData(BOARD_TX_POWER_FCC_LEVEL, &board_param.tx_power_fcc[0], sizeof(board_param.tx_power_fcc), 0))
@@ -332,6 +335,21 @@
    {
        board_param.flag |= (1 << BOARD_X32K_LOAD_CAP);
    }
    if (TRUE == WsfNvmReadData(BOARD_CALIB_X38M4_TEMPERATURE, (uint8_t *)&board_param.calib_x38m4_temperature, sizeof(board_param.calib_x38m4_temperature), 0))
    {
        board_param.flag |= (1 << BOARD_CALIB_X38M4_TEMPERATURE);
    }
    if (TRUE == WsfNvmReadData(BOARD_CALIB_X38M4_PPM, (uint8_t *)&board_param.calib_x38m4_ppm, sizeof(board_param.calib_x38m4_ppm), 0))
    {
        board_param.flag |= (1 << BOARD_CALIB_X38M4_PPM);
    }
    if (TRUE == WsfNvmReadData(BOARD_ANGLE_CORRECTION, (uint8_t *)&board_param.angle_correction, sizeof(board_param.angle_correction), 0))
    {
        board_param.flag |= (1 << BOARD_ANGLE_CORRECTION);
    }
#endif
}
@@ -339,7 +357,7 @@
{
    uint8_t ret = 0;
#ifdef WSF_EN
    if (((id == BOARD_LOAD_CAP) && (param_len == sizeof(board_param.load_cap))) ||
    if (((id == BOARD_X38M4_LOAD_CAP) && (param_len == sizeof(board_param.x38m4_load_cap))) ||
        ((id == BOARD_TX_POWER_FCC_LEVEL) && (param_len == sizeof(board_param.tx_power_fcc))) ||
        ((id == BOARD_RANGING_SESSION_ID) && (param_len == sizeof(board_param.ranging_session_id))) ||
        ((id == BOARD_LOCAL_SHORT_ADDR) && (param_len == sizeof(board_param.local_short_addr))) ||
@@ -351,7 +369,10 @@
        ((id == BOARD_PDOA_OFFSETS) && (param_len == sizeof(board_param.pdoa_offsets))) ||
        ((id == BOARD_DEV_ROLE) && (param_len == sizeof(board_param.dev_role))) ||
        ((id == BOARD_DEV_ROLE_IDX) && (param_len == sizeof(board_param.dev_role_idx))) ||
        ((id == BOARD_X32K_LOAD_CAP) && (param_len == sizeof(board_param.x32k_load_cap))))
        ((id == BOARD_X32K_LOAD_CAP) && (param_len == sizeof(board_param.x32k_load_cap))) ||
        ((id == BOARD_CALIB_X38M4_TEMPERATURE) && (param_len == sizeof(board_param.calib_x38m4_temperature))) ||
        ((id == BOARD_CALIB_X38M4_PPM) && (param_len == sizeof(board_param.calib_x38m4_ppm))) ||
        ((id == BOARD_ANGLE_CORRECTION) && (param_len == sizeof(board_param.angle_correction))))
    {
        ret = WsfNvmWriteData(id, param, param_len, 0);
    }
@@ -365,7 +386,7 @@
    {
        return;
    }
#ifdef UWB_EN
#if (ANT_PATTERN == ANT_PATTERN_SQUARE) // 3D
#elif (ANT_PATTERN == ANT_PATTERN_TRIANGLE_REGULAR) // 3D
@@ -373,72 +394,225 @@
#elif (ANT_PATTERN == ANT_PATTERN_LINEAR) // 2D -90 ~ 90
    // azimuth correction
    float post_azimuth = mk_q7_to_f32(*azimuth);
#if RX_ANT_PORTS_NUM == 4
    post_azimuth = (int16_t)(1.1221f * post_azimuth + 0.2729f);
#elif RX_ANT_PORTS_NUM == 3
    post_azimuth = (int16_t)(1.2287f * post_azimuth + 1.3633f);
#elif RX_ANT_PORTS_NUM == 2
    if (post_azimuth < -13.1)
    if (board_param.angle_correction[0])
    {
        post_azimuth = (int16_t)(0.8719f * post_azimuth - 28.282f);
    }
    else if (post_azimuth < -4.6)
    {
        post_azimuth = (int16_t)(3.7137f * post_azimuth + 10.307f);
    }
    else
    {
        post_azimuth = (int16_t)(1.0492f * post_azimuth - 3.1928f);
        float k, b;
        if (board_param.angle_correction[6] && post_azimuth < 0.1f * board_param.angle_correction[5])
        {
            k = board_param.angle_correction[6] * 0.001f;
            b = board_param.angle_correction[7] * 0.1f;
        }
        else if (board_param.angle_correction[3] && post_azimuth < 0.1f * board_param.angle_correction[2])
        {
            k = board_param.angle_correction[3] * 0.001f;
            b = board_param.angle_correction[4] * 0.1f;
        }
        else
        {
            k = board_param.angle_correction[0] * 0.001f;
            b = board_param.angle_correction[1] * 0.1f;
        }
        post_azimuth = (int16_t)(k * post_azimuth + b);
    }
#endif
    post_azimuth = ((post_azimuth > 90) ? 90 : ((post_azimuth < -90) ? -90 : post_azimuth));
    *azimuth = mk_f32_to_q7(post_azimuth);
#endif
#endif
}
void board_5V_input_init(GPIO_IRQ_HANDLER_T irq_handler)
#if (X38M4_AUTO_TUNE_EN == 2)
#if (X38M4_AUTO_TUNE_CENTER_TYPE == 0)
static int32_t ppm_calculate(int16_t temp)
{
      button_irq_handler = irq_handler;
    gpio_pin_set_dir(INPUT_5V_Pin , GPIO_DIR_IN, 0);
    io_pull_set(INPUT_5V_Pin , IO_PULL_DOWN, IO_PULL_UP_NONE);
    gpio_enable_irq(INPUT_5V_Pin, GPIO_IRQ_TYPE_RISING_EDGE, button_irq_handler);
    //power_wakeup_enable((enum POWER_WAKEUP_SOURCE_T)INPUT_5V_Pin, POWER_WAKEUP_LEVEL_LOW);
    // TZ3398B TC Curve
    int32_t ppm = (int32_t)((1E-04 * pow(temp, 3) - 0.0084 * pow(temp, 2) - 0.1957 * temp + 8.6575) * 100);
    LOG_INFO(TRACE_MODULE_APP, "temp %d, ppm %d\r\n", temp, ppm);
    return ppm;
}
void board_acceleration_detection_init(GPIO_IRQ_HANDLER_T irq_handler)
#elif (X38M4_AUTO_TUNE_CENTER_TYPE == 1)
static void board_x38m4_ppm_detected_init(void)
{
      accelerate_irq_handler=irq_handler;
      gpio_pin_set_dir(ACCLERATE_DETECT_Pin , GPIO_DIR_IN, 0);
      io_pull_set(ACCLERATE_DETECT_Pin, IO_PULL_DOWN, IO_PULL_UP_LEVEL4);
    gpio_enable_irq(ACCLERATE_DETECT_Pin, GPIO_IRQ_TYPE_RISING_EDGE, accelerate_irq_handler);
    gpio_pin_set_dir(IO_PIN_1, GPIO_DIR_OUT, 1);
    static struct ADC_CFG_T usr_adc_cfg = {
        .mode = ADC_MODE_CONTINUE,    /* Selected single conversion mode  */
        .clk_sel = ADC_CLK_HIGH,      /* Selected 62.4M high speed clock */
        .vref_sel = ADC_SEL_VREF_EXT, /* Using external reference voltage (3.3V)*/
        .rate = 1000000,              /* ADC works at high frequency system clock, the maximum sampling rate is 2M */
        .channel_p = ADC_IN_EXTPIN0,  /* ADC positive channel --> GPIO0 */
        .channel_n = ADC_IN_GUD,      /* ADC negative channel --> GND */
        .int_en = false,
        .dma_en = false, /* DMA support only in continue mode */
        .acc_num = 0,
        .high_pulse_time = 4,
        .settle_time = 1,
    };
    adc_open(&usr_adc_cfg);
}
void board_4GUsart_detection_init(GPIO_IRQ_HANDLER_T irq_handler)  //4G 串口输入检测中断,下拉触发
static void board_x38m4_ppm_detected_close(void)
{
        _4Gusart_irq_handler=irq_handler;
        io_pin_mux_set(_4G_USART_RX_Pin,IO_FUNC0);//把原先io 变为普通GPIO
      gpio_pin_set_dir(_4G_USART_RX_Pin , GPIO_DIR_IN, 0);
      io_pull_set(_4G_USART_RX_Pin, IO_PULL_UP, IO_PULL_UP_LEVEL2);
        gpio_enable_irq(_4G_USART_RX_Pin, GPIO_IRQ_TYPE_FALLING_EDGE, _4Gusart_irq_handler);
      power_wakeup_enable((enum POWER_WAKEUP_SOURCE_T)_4G_USART_RX_Pin, POWER_WAKEUP_LEVEL_LOW);
    adc_close();
    gpio_pin_set_dir(IO_PIN_1, GPIO_DIR_OUT, 0);
}
void pca_input_detection_init(GPIO_IRQ_HANDLER_T irq_handler)
static int32_t ppm_calculate(int16_t temp)
{
      pca_input_detect_irq_handler=irq_handler;
      gpio_pin_set_dir(PCA_INPUT_DETECT , GPIO_DIR_IN, 0);
   io_pull_set(PCA_INPUT_DETECT, IO_PULL_UP, IO_PULL_UP_LEVEL2);
   gpio_enable_irq(PCA_INPUT_DETECT, GPIO_IRQ_TYPE_FALLING_EDGE, pca_input_detect_irq_handler);
   power_wakeup_enable((enum POWER_WAKEUP_SOURCE_T)PCA_INPUT_DETECT, POWER_WAKEUP_LEVEL_LOW);
    // TXC P/N: AF38470002
    int32_t ppm = (int32_t)((9E-05 * pow(temp, 3) - 0.0085 * pow(temp, 2) + 0.0072 * temp + 4.7202) * 100);
    return ppm;
}
#endif
#endif
int32_t board_x38m4_ppm_get(int32_t *p_ppm)
{
#if (X38M4_AUTO_TUNE_EN == 2)
#if (X38M4_AUTO_TUNE_CENTER_TYPE == 0)
    temp_sensor_open();
    int16_t temp = temp_sensor_get(0);
    // LOG_INFO(TRACE_MODULE_APP, "Chip temperature: %d degree\r\n", temp);
    temp_sensor_close();
#define TEMP_CACHE_NUM 10
    static int16_t temp_cache[TEMP_CACHE_NUM] = {0};
    static uint8_t temp_cnt = 0;
    temp_cache[temp_cnt % TEMP_CACHE_NUM] = temp;
    temp_cnt += 1;
    uint8_t temp_num = temp_cnt >= TEMP_CACHE_NUM ? TEMP_CACHE_NUM : temp_cnt;
    int16_t sum_temp = 0;
    for (uint8_t ii = 0; ii < temp_num; ii++)
    {
        sum_temp += temp_cache[ii];
    }
    temp = (uint8_t)(sum_temp / temp_num);
    LOG_INFO(TRACE_MODULE_APP, "temp[%d] %d %d %d %d %d, average %d\r\n", temp_num, temp_cache[0], temp_cache[1], temp_cache[2], temp_cache[3], temp_cache[4],
             sum_temp);
    int32_t ppm_calib = ppm_calculate(board_param.calib_x38m4_temperature);
    int32_t ppm = ppm_calculate(temp);
    if (p_ppm)
    {
        *p_ppm = ppm - ppm_calib;
    }
    LOG_INFO(TRACE_MODULE_APP, "ppm_get(%d) %d, ppm_calib(%d) %d, ppm offset %d\r\n", temp, ppm, board_param.calib_x38m4_temperature, ppm_calib, *p_ppm);
    return DRV_OK;
#elif (X38M4_AUTO_TUNE_CENTER_TYPE == 1)
// this function vill cost 148us without log print
#define SAMPLE_NUM 3
#define RESISTANCE_REF_VALUE 130 * 1000 // Ohm
#define ADC_EXTERNAL_VREF_MV 3300       // 3300 - 3.3V
#define X38M4_WORK_MIN_TEMP (-40)
    uint32_t adc_sample[SAMPLE_NUM] = {0};
    // adc sample
    board_x38m4_ppm_detected_init();
    int32_t ret = adc_get(&adc_sample[0], SAMPLE_NUM, 0);
    if (ret == DRV_OK)
    {
        uint32_t adc_sum = 0;
        for (uint16_t ii = 0; ii < SAMPLE_NUM; ii++)
        {
            adc_sum += adc_sample[ii];
        }
        adc_sum /= SAMPLE_NUM;
        LOG_INFO(TRACE_MODULE_APP, "adc value[%d] %d %d %d\r\n", SAMPLE_NUM, adc_sample[0], adc_sample[1], adc_sample[2]);
        int16_t tmp_mv = adc_code_to_mv((int16_t)adc_sum, ADC_EXTERNAL_VREF_MV);
        int32_t resistance_val = tmp_mv * RESISTANCE_REF_VALUE / (ADC_EXTERNAL_VREF_MV - tmp_mv);
        // resistance_val = 75658;
        // The temperature value is obtained from the thermistor resistance value
        // the fisrt value means the current temperature is X38M4_WORK_MIN_TEMP, the second is (X38M4_WORK_MIN_TEMP+1)
        // unit is Ohm
        // TXC P/N: AF38470002
        const int32_t rt_table[] = {
            4397120, 4092870, 3811720, 3551750, 3311240, 3088600, 2882400, 2691310, 2514140, 2349780, 2197230, 2055560, 1923930, 1801570, 1687770, 1581880,
            1483100, 1391110, 1305410, 1225530, 1151040, 1081540, 1016660, 956080,  899480,  846580,  797110,  750830,  707520,  666970,  628990,  593340,
            559930,  528600,  499210,  471630,  445770,  421480,  398650,  377190,  357010,  338010,  320120,  303290,  287430,  272500,  258430,  245160,
            232650,  220850,  209710,  199200,  189270,  17989,   171030,  162650,  154730,  147230,  140140,  133430,  127080,  121070,  115370,  109970,
            104850,  100000,  95400,   91030,   86890,   82960,   79220,   75680,   72310,   69100,   66060,   63170,   60420,   57800,   55310,   52930,
            50680,   48530,   46480,   44530,   42670,   40900,   39210,   37600,   36060,   34600,   33190,   31860,   30580,   29370,   28200,   27090,
            26030,   25010,   24040,   23110,   22220,   21370,   20560,   19780,   19040,   18320,   17640,   16990,   16360,   15760,   15180,   14630,
            14100,   13590,   13100,   12640,   12190,   11760,   11340,   10950,   10570,   10200,   9850,    9510,    9180,    8870,    8570,    8280,
            8010,    7740,    7480,    7230,    7000,    6770,    6550,    6340,    6130,    5930,    5740,    5560,    5380,    5210,    5050,    4890,
            4740,    4590,    4450,    4320,    4180,    4060,    3930,    3820,    3700,    3590,    3480,    3380,    3280,    3190,    3090,    3000,
            2920,    2830,    2750,    2670,    2600,    2520};
        const uint16_t num_rt = sizeof(rt_table) / sizeof(int32_t);
        int16_t temp = X38M4_WORK_MIN_TEMP - 1;
        for (int16_t ii = 0; ii < num_rt; ii++)
        {
            int32_t delta_rt_0 = 0;
            int32_t delta_rt_1 = 0;
            if (ii == 0)
            {
                delta_rt_1 = (rt_table[ii] - rt_table[ii + 1]) / 2;
                delta_rt_0 = delta_rt_1;
            }
            else if (ii == (num_rt - 1))
            {
                delta_rt_0 = (rt_table[ii - 1] - rt_table[ii]) / 2;
                delta_rt_1 = delta_rt_0;
            }
            else
            {
                delta_rt_0 = (rt_table[ii - 1] - rt_table[ii]) / 2;
                delta_rt_1 = (rt_table[ii] - rt_table[ii + 1]) / 2;
            }
            // LOG_INFO(TRACE_MODULE_APP, "[%d] %d %d %d\r\n", ii, rt_table[ii] + delta_rt_0, resistance_val, rt_table[ii] - delta_rt_1);
            // if ((rt_table[ii] + delta_rt_0) > resistance_val >= (rt_table[ii] - delta_rt_1))
            if (resistance_val >= (rt_table[ii] - delta_rt_1) && resistance_val < (rt_table[ii] + delta_rt_0))
            {
                temp = X38M4_WORK_MIN_TEMP + ii;
                break;
            }
        }
        // The crystal frequency offset is obtained by temperature
        if (temp >= X38M4_WORK_MIN_TEMP && (board_param.flag & (1 << BOARD_CALIB_X38M4_TEMPERATURE)))
        {
            int32_t ppm_calib = ppm_calculate(board_param.calib_x38m4_temperature);
            int32_t ppm = ppm_calculate(temp);
            if (p_ppm)
            {
                *p_ppm = ppm - ppm_calib;
            }
            LOG_INFO(TRACE_MODULE_APP, "ppm_get(%d) %d, ppm_calib(%d) %d\r\n", temp, ppm, board_param.calib_x38m4_temperature, ppm_calib);
        }
        else
        {
            ret = DRV_DEV_UNAVAILABLE;
        }
        LOG_INFO(TRACE_MODULE_APP, "board_x38m4_ppm_get average %d, volatage %d, resistance %d, temperature %d, ppm offset %d\r\n", adc_sum, tmp_mv,
                 resistance_val, temp, *p_ppm);
    }
    board_x38m4_ppm_detected_close();
    return ret;
#endif
#else
    return DRV_OK;
#endif
}
void board_button_init(GPIO_IRQ_HANDLER_T irq_handler)
{
    button_irq_handler = irq_handler;
    gpio_pin_set_dir(BOARD_SW_1, GPIO_DIR_IN, 0);
    io_pull_set(BOARD_SW_1, IO_PULL_UP, IO_PULL_UP_LEVEL3);
    io_pull_set(BOARD_SW_1, IO_PULL_UP, IO_PULL_UP_LEVEL4);
    gpio_enable_irq(BOARD_SW_1, GPIO_IRQ_TYPE_FALLING_EDGE, button_irq_handler);
    power_wakeup_enable((enum POWER_WAKEUP_SOURCE_T)BOARD_SW_1, POWER_WAKEUP_LEVEL_LOW);
@@ -447,7 +621,7 @@
void board_led_init(void)
{
    gpio_pin_set_dir(BOARD_LED_1, GPIO_DIR_OUT, 0);
    gpio_pin_set_dir(BOARD_LED_2, GPIO_DIR_OUT, 0);
//    gpio_pin_set_dir(BOARD_LED_2, GPIO_DIR_OUT, 0);
}
void board_led_on(enum IO_PIN_T idx)
@@ -464,16 +638,16 @@
{
    gpio_pin_toggle(idx);
}
void LED_output_init(void)
{
         //LEDgpio控制
      io_pin_mux_set(WS2812_PIN, IO_FUNC0);
    gpio_pin_set_dir(WS2812_PIN , GPIO_DIR_OUT, 0);
    io_pull_set(WS2812_PIN,IO_HIGH_Z,IO_PULL_UP_NONE);//3
}
void board_configure(void)
{
#if (X38M4_AUTO_TUNE_EN == 2)
    int32_t ppm_offset = 0;
    if (board_x38m4_ppm_get(&ppm_offset) == DRV_OK)
    {
        calib_xtal38m4_load_cap_auto_tune_to_center(ppm_offset + board_param.calib_x38m4_ppm, board_param.x38m4_load_cap);
    }
#endif
}
void board_prepare_for_power_down(void)
@@ -485,21 +659,14 @@
void board_restore_from_power_down(void)
{
   uart_open(UART_ID1, &test_uart_cfg);
   AIR780EUartInit();
   adc_open(&usr_adc_cfg);
   m_EUART_DMA_RXPtr = 0;//清空上次缓存器避免重复发
#if defined(UCI_INTF_PORT)
    uci_tl_resume();
#else
    // button - restore interrupt type
   gpio_enable_irq(_4G_USART_RX_Pin, GPIO_IRQ_TYPE_FALLING_EDGE, _4Gusart_irq_handler);
   gpio_enable_irq(ACCLERATE_DETECT_Pin, GPIO_IRQ_TYPE_RISING_EDGE, accelerate_irq_handler);
//    if (button_irq_handler)
//    {
//        gpio_enable_irq(BOARD_SW_1, GPIO_IRQ_TYPE_FALLING_EDGE, button_irq_handler);
//    }
    if (button_irq_handler)
    {
        gpio_enable_irq(BOARD_SW_1, GPIO_IRQ_TYPE_FALLING_EDGE, button_irq_handler);
    }
#endif
#if !defined(CELL_PHONE_EN)