keil/include/drivers/mk_radar.c
@@ -1,5 +1,5 @@
/*
 * 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.
@@ -82,46 +82,43 @@
#endif
#if OVERLAY_FRAME_LENGTH == 256
#if (64 == N_SNAPSHOTS)
#elif (128 == N_SNAPSHOTS)
#elif (256 == N_SNAPSHOTS)
#else
#error "N_SNAPSHOTS is not supported"
#endif
#elif OVERLAY_FRAME_LENGTH == 128
#if (128 == N_SNAPSHOTS)
#elif (256 == N_SNAPSHOTS)
#elif (512 == N_SNAPSHOTS)
#else
#error "N_SNAPSHOTS is not supported"
#endif
#else
#error "Frame length is not supported"
#endif
/* Radar RX window, unit: us */
#define UWB_RADAR_RX_WINDOW (100)
/* Radar event prefetch time, unit: us */
#define UWB_RADAR_PREFETCH_TIME (100)
#if UWB_RADAR_1TNR_MODE == 1
#if UWB_RADAR_STS_LENGTH == 2
/* Radar RX window, unit: us */
#if UWB_RADAR_STS_LENGTH == 3
#define UWB_RADAR_RX_WINDOW 170
#define UWB_RADAR_RX_WINDOW2 98
#define UWB_RADAR_RX_WINDOW3 64
#elif UWB_RADAR_STS_LENGTH == 2
#define UWB_RADAR_RX_WINDOW 100
#define UWB_RADAR_RX_WINDOW2 64
#define UWB_RADAR_RX_WINDOW3 48
#else
#define UWB_RADAR_RX_WINDOW 68
#define UWB_RADAR_RX_WINDOW2 48
#define UWB_RADAR_RX_WINDOW3 40
#endif
#endif
/* 1TnR Frame interval for Overlay work mode, unit: us */
#define FRAME_INTERVAL 300
/* The factors influencing the peak index value are twofold:
/* 1ns per sample, 24 ~ 27 */
#define DISCARD_SYMBOLS 25
#if UWB_RADAR_2G_MODE_EN
/* There are two factors that affect the peak index value:
 * 1) the scheduled transmission time (The configuration of the low 2 bits of the 0x40000424 register)
 * 2) the value of the discard (0x40002040 bit8~19)
 * 2) the value of the discard symbols (0x40002040 bit8~19)
 */
/* The low 2 bits of the 0x40000424 register are set to 0
/*
 * |----------------------------------------------------------------------------|
 * | Discard Symbols(24/25/26/27/28/29)  | 24 | 25 | 26 | 27 | 28 | 29 |        |
 * |----------------------------------------------------------------------------|
@@ -141,20 +138,33 @@
 * |----------------------------------------------------------------------------|
 */
#if UWB_RADAR_2G_MODE_EN
/* 1ns per sample, 24 ~ 27 */
#define DISCARD_SYMBOLS 25
/* pusle peak postion table */
static const uint8_t peak_idx_table[5][4] = {{4, 12, 4, 12}, {20, 28, 4, 12}, {36, 44, 52, 60}, {100, 108, 116, 124}, {228, 236, 244, 252}};
#else
/* 2ns per sample, 12 ~ 15 */
#define DISCARD_SYMBOLS 12
/*
 * |----------------------------------------------------------------------------|
 * | Discard Symbols(24/25/26/27)        | 24 | 25 | 26 | 27 |                  |
 * |----------------------------------------------------------------------------|
 * | Pulse period 16ns (0 Delay Point)   |  0 |  4 |  0 |  4 |                  |
 * |----------------------------------------------------------------------------|
 * |----------------------------------------------------------------------------|
 * | Pulse period 32ns (0 Delay Point)   |  0 |  4 |  8 | 12 |                  |
 * |----------------------------------------------------------------------------|
 * |----------------------------------------------------------------------------|
 * | Pulse period 64ns (0 Delay Point)   | 24 | 28 |  0 |  4 |                  |
 * |----------------------------------------------------------------------------|
 * |----------------------------------------------------------------------------|
 * | Pulse period 128ns (0 Delay Point)  | 56 | 60 |  0 |  4 |                  |
 * |----------------------------------------------------------------------------|
 * |----------------------------------------------------------------------------|
 * | Pulse period 256ns (0 Delay Point)  | 120 | 124 |  0 |  4 |                |
 * |----------------------------------------------------------------------------|
 */
/* pusle peak postion table */
static const uint8_t peak_idx_table[5][4] = {{1, 5, 1, 5}, {0, 4, 8, 12}, {8, 12, 16, 20}, {8, 12, 16, 20}, {72, 76, 80, 84}};
static const uint8_t peak_idx_table[5][4] = {{0, 4, 0, 4}, {0, 4, 8, 12}, {24, 28, 0, 4}, {56, 60, 0, 4}, {120, 124, 0, 4}};
#endif
/* 1TnR Rx port list */
@@ -166,7 +176,7 @@
static struct UWB_RADAR_T default_radar_cfg = {
    .channel_num = 9,
    .rx_gain_level = 14,
    .filter_gain_level = 14,
    .lna_gain_level = 5,
    .pulse_period = UWB_RADAR_PULSE_PERIOD_64NS,
    .bandwidth = 0x02,
@@ -320,7 +330,7 @@
                }
            }
            calibration_peak_idx = calibration_peak_idx - ((calibration_peak_idx - 4) % 8);
            // calibration_peak_idx = calibration_peak_idx - ((calibration_peak_idx - 4) % 8);
            LOG_INFO(TRACE_MODULE_APP, "ANT%d Raw max index %d\n", n, calibration_peak_idx);
        }
#endif
@@ -329,7 +339,7 @@
        for (uint32_t i = 0; i < pulse_period_points; i++)
        {
            uint32_t idx = ((pulse_period_points - calibration_peak_idx + i) > (pulse_period_points - 1)) ? (i - calibration_peak_idx)
                           : (pulse_period_points - calibration_peak_idx + i);
                                                                                                          : (pulse_period_points - calibration_peak_idx + i);
            data_out[idx * 2] = period_samples_out[i * 2];
            data_out[idx * 2 + 1] = period_samples_out[i * 2 + 1];
@@ -364,7 +374,7 @@
    */
    // 8KW each block
    uint32_t seg_in_blk = 1024 * 8;
    if ((sts_seg_len == UWB_RADAR_STS_SEGLEN64) || (sts_seg_len == UWB_RADAR_STS_SEGLEN32))
    if ((sts_seg_len == UWB_RADAR_STS_SEGLEN128) || (sts_seg_len == UWB_RADAR_STS_SEGLEN64) || (sts_seg_len == UWB_RADAR_STS_SEGLEN32))
    {
        seg_in_blk = seg_in_blk >> (UWB_RADAR_RX_PORT_NUM - 1);
        if (seg_in_blk < 1024 * 2)
@@ -372,20 +382,32 @@
            return;
        }
    }
    else
    else if (UWB_RADAR_RX_PORT_NUM > 1)
    {
        return;
    }
    for (uint8_t i = 0; i < UWB_RADAR_RX_PORT_NUM; i++)
    {
#if UWB_RADAR_STS_LENGTH == 3
#if UWB_RADAR_RX_PORT_NUM == 3
        seg_in_blk = (i == 1) ? seg_in_blk >> (UWB_RADAR_RX_PORT_NUM - 2) : 0;
#elif UWB_RADAR_RX_PORT_NUM == 2
        seg_in_blk = 0;
#endif
#endif
        /* Find the start address of segment in block for each port */
        mem_data = &data_in[seg_in_blk * (UWB_RADAR_RX_PORT_NUM - 1 - i)];
        acc_out = &data_out[i * OVERLAY_FRAME_LENGTH * 2];
        /* Outer loop for the 4 banks, each bank will have 32 kbytes or 8 kwords */
        for (uint32_t blocks = 0; blocks < BANK_NUM; blocks++)
        {
#if UWB_RADAR_STS_LENGTH == 3
            offset = (i == 0) ? (blocks * 1024 * 8 + 1024 * 16) : (blocks * 1024 * 8);
#else
            offset = blocks * 1024 * 8;
#endif
            /* Inner loop for words in that bank, each word has 2 samples (IQ) */
            /* 1 snapshot will be 16 words, so accumulate every 16 words */
@@ -394,13 +416,35 @@
                /* Remove head 4KB and tail 2KB */
                for (uint32_t rows = CUT_OFF_LINES(HEAD_LEN); rows < (acc_columns - CUT_OFF_LINES(TAIL_LEN)); rows++)
                {
#if UWB_RADAR_STS_LENGTH == 3 && UWB_RADAR_RX_PORT_NUM == 1
                    if (rows == CUT_OFF_LINES(HEAD_LEN))
                    {
                        offset = blocks * 1024 * 8;
                    }
                    else if (rows == acc_columns >> 1)
                    {
                        offset = blocks * 1024 * 8 + 1024 * 8;
                    }
#endif
                    data_read = mem_data[offset + rows * (OVERLAY_FRAME_LENGTH / BANK_NUM / 2) + columns];
                    // Extract two samples from this word
                    samp_array_d1[rows] = (int16_t)((data_read) & (0xffff));
                    samp_array_d2[rows] = (int16_t)((data_read >> (16)) & (0xffff));
                }
                /*
                I = a, a1, a2...
                Q = b, b1, b2
                c = 1, 1, 1
                d = 0, 0, 0
                (a + jb) * (c - jd) = ac -jad + jbc + bd = a + jb
                (a1 + jb1) * (c - jd) = a1c -ja1d + jb1c + b1d = a1 + jb1
                (a2 + jb2) * (c - jd) = a2c -ja2d + jb2c + b2d = a2 + jb2
                a, b, a1, b1, a2, b2....
                1, 0, 1,  0,  1,  0 ...
                */
                /* Accumulate across snapshots , complex so will output 2 values */
                lsp_cmplx_inner_product_int8((const int8_t *)&samp_array_d1[CUT_OFF_LINES(HEAD_LEN)], (const int8_t *)allones,
                                             (int32_t *)(acc_out + (4 * (BANK_NUM * columns + blocks))),
@@ -488,7 +532,7 @@
    for (uint32_t i = 0; i < pulse_period_points; i++)
    {
        uint32_t idx = ((pulse_period_points - calibration_peak_idx + i) > (pulse_period_points - 1)) ? (i - calibration_peak_idx)
                       : (pulse_period_points - calibration_peak_idx + i);
                                                                                                      : (pulse_period_points - calibration_peak_idx + i);
        data_out[idx * 2] = period_samples_out[i * 2];
        data_out[idx * 2 + 1] = period_samples_out[i * 2 + 1];
@@ -515,13 +559,35 @@
            /* Discard the first 4KB data and the end 2KB data */
            for (uint32_t rows = CUT_OFF_LINES(HEAD_LEN); rows < acc_columns - CUT_OFF_LINES(TAIL_LEN); rows++)
            {
#if UWB_RADAR_STS_LENGTH == 3
                if (rows == CUT_OFF_LINES(HEAD_LEN))
                {
                    offset = blocks * 1024 * 8;
                }
                else if (rows == acc_columns >> 1)
                {
                    offset = blocks * 1024 * 8 + 1024 * 8;
                }
#endif
                data_read = mem_data[offset + rows * (OVERLAY_FRAME_LENGTH / BANK_NUM / 2) + columns];
                // Extract two samples from this word
                samp_array_d1[rows] = (int16_t)((data_read) & (0xffff));
                samp_array_d2[rows] = (int16_t)((data_read >> (16)) & (0xffff));
            }
            /*
            I = a, a1, a2...
            Q = b, b1, b2
            c = 1, 1, 1
            d = 0, 0, 0
            (a + jb) * (c - jd) = ac -jad + jbc + bd = a + jb
            (a1 + jb1) * (c - jd) = a1c -ja1d + jb1c + b1d = a1 + jb1
            (a2 + jb2) * (c - jd) = a2c -ja2d + jb2c + b2d = a2 + jb2
            a, b, a1, b1, a2, b2....
            1, 0, 1,  0,  1,  0 ...
            */
            /* Accumulate across up to 512 snapshots , complex so will output 2 values */
            lsp_cmplx_inner_product_int8((const int8_t *)&samp_array_d1[CUT_OFF_LINES(HEAD_LEN)], (const int8_t *)allones,
                                         (int32_t *)((uint32_t)accum_out + (16 * (BANK_NUM * columns + blocks))),
@@ -567,17 +633,13 @@
    default_radar_cfg.bandwidth = radar_cfg->bandwidth;
    default_radar_cfg.channel_num = radar_cfg->channel_num;
    default_radar_cfg.lna_gain_level = radar_cfg->lna_gain_level;
    default_radar_cfg.rx_gain_level = radar_cfg->rx_gain_level;
    default_radar_cfg.filter_gain_level = radar_cfg->filter_gain_level;
    default_radar_cfg.tx_power_level = radar_cfg->tx_power_level;
    default_radar_cfg.sts_len = radar_cfg->sts_len;
    default_radar_cfg.pulse_period = radar_cfg->pulse_period;
    default_radar_cfg.ranging_tx_power_level = radar_cfg->ranging_tx_power_level;
#if UWB_RADAR_2G_MODE_EN
    calibration_peak_idx = peak_idx_table[default_radar_cfg.pulse_period][DISCARD_SYMBOLS - 24];
#else
    calibration_peak_idx = peak_idx_table[default_radar_cfg.pulse_period][DISCARD_SYMBOLS - 12];
#endif
    // LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "Raw max index %d\n", calibration_peak_idx);
    // 1T1R mode, the ant id can be configured from host
@@ -599,40 +661,41 @@
    switch (default_radar_cfg.pulse_period)
    {
    case UWB_RADAR_PULSE_PERIOD_16NS:
        sts_key = 0x00000000;
        break;
        case UWB_RADAR_PULSE_PERIOD_16NS:
            sts_key = 0x00000000;
            break;
    case UWB_RADAR_PULSE_PERIOD_32NS:
        sts_key = 0x55555555;
        break;
        case UWB_RADAR_PULSE_PERIOD_32NS:
            sts_key = 0x55555555;
            break;
    case UWB_RADAR_PULSE_PERIOD_64NS:
        sts_key = 0xEEEEEEEE;
        break;
        case UWB_RADAR_PULSE_PERIOD_64NS:
            sts_key = 0xEEEEEEEE;
            break;
    case UWB_RADAR_PULSE_PERIOD_128NS:
        sts_key = 0xFEFEFEFE;
        break;
        case UWB_RADAR_PULSE_PERIOD_128NS:
            sts_key = 0xFEFEFEFE;
            break;
    case UWB_RADAR_PULSE_PERIOD_256NS:
        sts_key = 0xFFFEFFFE;
        break;
        case UWB_RADAR_PULSE_PERIOD_256NS:
            sts_key = 0xFFFEFFFE;
            break;
    }
    /**************************************SYS RADIO REG*********************************************/
    reg = 0x40000404;
    val = REG_READ(reg);
    reg_save.reg_count = 0;
    reg_save.reg_store[reg_save.reg_count][STORE_REG] = reg;
    reg_save.reg_store[reg_save.reg_count][STORE_VAL] = val;
    reg_save.reg_count = 1;
    reg_save.reg_count++;
    val = val & ~0xF0000U;
#if UWB_RADAR_2G_MODE_EN
    // Set LPF_BW 500M | RX ADC sample rate 2Gs/s | pulse width 0:2ns(500M), 1:0.92ns(1G), 2:0.75ns(1.3G)
    // Set LPF_BW 500M | RX ADC sample rate 2Gs/s | pulse width 0:2ns(500M), 3:0.92ns(900M), 2:0.75ns(1.3G)
    val |= ((1U << 18) | ((default_radar_cfg.bandwidth & 0x3U) << 16));
#else
    // Set LPF_BW 250M | RX ADC sample rate 1Gs/s | pulse width 0:2ns(500M), 1:0.92ns(1G), 2:0.75ns(1.3G)
    // Set LPF_BW 250M | RX ADC sample rate 1Gs/s | pulse width 0:2ns(500M), 3:0.92ns(900M), 2:0.75ns(1.3G)
    val |= ((1U << 19) | ((default_radar_cfg.bandwidth & 0x3U) << 16));
#endif
    REG_WRITE(reg, val);
@@ -689,7 +752,7 @@
    reg_save.reg_store[reg_save.reg_count][STORE_VAL] = val;
    reg_save.reg_count++;
    // Disable RX AGC, and use register to configure the gain of LNA and filter;
    val = (1U << 31) | ((default_radar_cfg.rx_gain_level & 0x1FU) << 16) | (default_radar_cfg.lna_gain_level & 0x7U);
    val = (1U << 31) | ((default_radar_cfg.filter_gain_level & 0x1FU) << 16) | (default_radar_cfg.lna_gain_level & 0x7U);
    REG_WRITE(reg, val);
    /******************************************TXBE REG*********************************************/
@@ -969,6 +1032,7 @@
    enter_debug_mode();
#if UWB_RADAR_1TNR_MODE == 1
    uint32_t val;
    static uint32_t loopback_anchor_point;
    uint32_t rx_win = US_TO_PHY_TIMER_COUNT(UWB_RADAR_RX_WINDOW);
@@ -990,8 +1054,10 @@
    uint32_t target = loopback_anchor_point + US_TO_PHY_TIMER_COUNT(FRAME_INTERVAL * ant_idx);
    // Delay discard_symbols, dump data
    uint32_t val = (uint32_t)(4 | (1 << 3) | (1 << 7) | ((DISCARD_SYMBOLS & 0xfff) << 8));
    REG_WRITE(0x40002040, val);
    // val = REG_READ(0x40002040);
    // val = val & ~(0xfffU << 8);
    // val |= (uint32_t)((DISCARD_SYMBOLS & 0xfff) << 8);
    // REG_WRITE(0x40002040, val);
    // TXSTS
    val = REG_READ(0x40001008);