| | |
| | | /* |
| | | * 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. |
| | |
| | | #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 | | |
| | | * |----------------------------------------------------------------------------| |
| | |
| | | * |----------------------------------------------------------------------------| |
| | | */ |
| | | |
| | | #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 */ |
| | |
| | | |
| | | 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, |
| | |
| | | } |
| | | } |
| | | |
| | | 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 |
| | |
| | | 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]; |
| | |
| | | */ |
| | | // 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) |
| | |
| | | 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 */ |
| | |
| | | /* 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))), |
| | |
| | | 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]; |
| | |
| | | /* 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))), |
| | |
| | | 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 |
| | |
| | | |
| | | 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); |
| | |
| | | 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*********************************************/ |
| | |
| | | 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); |
| | |
| | | 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); |