From 5102fff8a13c0319d8125a51d3d2354e7aacdcea Mon Sep 17 00:00:00 2001 From: chen <15335560115@163.com> Date: 星期四, 31 七月 2025 16:40:06 +0800 Subject: [PATCH] 修改为2HZ发poll包,修改second task从原来2s一次为1s一次 --- keil/include/drivers/mk_uwb.c | 434 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 381 insertions(+), 53 deletions(-) diff --git a/keil/include/drivers/mk_uwb.c b/keil/include/drivers/mk_uwb.c index e7b82ee..caf76a1 100644 --- a/keil/include/drivers/mk_uwb.c +++ b/keil/include/drivers/mk_uwb.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. @@ -46,11 +46,14 @@ #include "mk_aes.h" #include "mk_lsp.h" #include "mk_power.h" +#if RANGING_EN +#include "lib_ranging.h" +#endif #include "board.h" #ifndef RSSI_EN -#define RSSI_EN 0 +#define RSSI_EN (0) #endif // single tone power range: -20dBm ~ 10dBm, step: 0.5dB (+/-0.2dB); tx power = -20dBm + 0.5 * power_level (+/- 1.5dB). @@ -137,45 +140,49 @@ static const uint8_t (*power_table)[5] = power_table_CH9; extern int16_t ranging_ant_delays_get(uint8_t ant_idx); -extern void ranging_ant_delays_set(uint8_t ant_idx, int16_t delay_ps); -extern int pdoa_ant_delays_get(int16_t *delays, uint8_t rx_ant_num); -extern int pdoa_ant_delays_set(int16_t *delays, uint8_t rx_ant_num); -extern int pdoa_ant_space_set(int16_t ant_space); -extern int pdoa_gain_set(int16_t *gain, uint8_t rx_ant_num); -extern int pdoa_angle_offset_set(int16_t *angle_offset); - __WEAK int16_t ranging_ant_delays_get(uint8_t ant_idx) { return 0; } -__WEAK void ranging_ant_delays_set(uint8_t ant_idx, int16_t delay_ps) +extern void ranging_ant_delays_set(uint8_t ant_idx, int16_t delay_rstu); +__WEAK void ranging_ant_delays_set(uint8_t ant_idx, int16_t delay_rstu) { } +extern int pdoa_ant_delays_get(int16_t *delays, uint8_t rx_ant_num); __WEAK int pdoa_ant_delays_get(int16_t *delays, uint8_t rx_ant_num) { return 0; } +extern int pdoa_ant_delays_set(int16_t *delays, uint8_t rx_ant_num); __WEAK int pdoa_ant_delays_set(int16_t *delays, uint8_t rx_ant_num) { return 0; } +extern int pdoa_ant_space_set(int16_t ant_space); __WEAK int pdoa_ant_space_set(int16_t ant_space) { return 0; } +extern int pdoa_gain_set(int16_t *gain, uint8_t rx_ant_num); __WEAK int pdoa_gain_set(int16_t *gain, uint8_t rx_ant_num) { return 0; } +extern int pdoa_angle_offset_set(int16_t *angle_offset); __WEAK int pdoa_angle_offset_set(int16_t *angle_offset) { return 0; +} + +extern void sts_lsp_store(void); +__WEAK void sts_lsp_store(void) +{ } int uwb_open(void) @@ -196,11 +203,15 @@ mac_init(IRQ_PRIORITY_HIGH, 3, 3, PHY_PAYLOAD_LEN_MAX); #endif +#ifdef XIP_EN + mac_ifs_set(PHY_LIFS_PERIOD_MACCLK_LONG, PHY_SIFS_PERIOD_MACCLK_LONG); +#endif + #if RSSI_EN mac_rssi_calculation_en(1); #endif - phy_init(IRQ_PRIORITY_NORMAL); + phy_init(IRQ_PRIORITY_NONE); phy_timer_open(1, IRQ_PRIORITY_HIGH); @@ -234,9 +245,6 @@ { // lna scan dis REG_WRITE(0x40000628, (1 << 6) | rx_ant_code[antenna_idx & 0x03]); -#ifndef RADAR_EN - LOG_INFO(TRACE_MODULE_DRIVER, "Open ANT%d\r\n", antenna_idx & 0x03); -#endif } } @@ -302,6 +310,31 @@ // low band power_table = power_table_CH2; } +} + +// 0x0 - Symmetrical Root-Raised-Cosine Pulse +// 0x1 - Precursor-Free Pulse (FiRa pulse) +// 0x2 - Precursor-Free Pulse +void uwb_pulse_shape_set(uint8_t pulse_shape) +{ + uint32_t value = REG_READ(0x40000404) & ~(0x3U << 16); + if (pulse_shape == 0) + { + REG_WRITE(0x40000404, value | (0x01 << 16)); + } + else + { + REG_WRITE(0x40000404, value); + } +} + +// 0x0 - 2ns(500M), 0x3 - 0.92ns(900M), 0x2 - 0.75ns(1.3G) +void uwb_pulse_width_set(uint8_t width) +{ + uint32_t val = REG_READ(0x40000404); + val = val & ~(0x3U << 16); + val |= (uint32_t)((width & 0x3) << 16); + REG_WRITE(0x40000404, val); } void uwb_tx_power_set(uint8_t tx_power_level) @@ -397,10 +430,12 @@ void uwb_calibration_params_set(uint8_t ch_num) { + LOG_INFO(TRACE_MODULE_DRIVER, "Vdd core %u Loopback time %u\r\n", board_param.vdd_core_vol, board_param.loopback_time); + uint8_t ch_idx = CALIB_CH(ch_num); for (uint8_t i = 0; i < 4; i++) { - ranging_ant_delays_set(i, board_param.ant_delays[ch_idx][i]); + ranging_ant_delays_set(i, board_param.ant_delays[ch_idx][i] + board_param.loopback_time); } LOG_INFO(TRACE_MODULE_DRIVER, "ToF ant delays %d %d %d %d\r\n", board_param.ant_delays[ch_idx][0], board_param.ant_delays[ch_idx][1], board_param.ant_delays[ch_idx][2], board_param.ant_delays[ch_idx][3]); @@ -420,55 +455,38 @@ LOG_INFO(TRACE_MODULE_DRIVER, "PDoA angle offsets %d %d\r\n", board_param.pdoa_offsets[0], board_param.pdoa_offsets[1]); } -void *uwb_configure(uint8_t mode, uint8_t tx_power_level, const struct UWB_CONFIG_T *ppdu_params) +void uwb_configure(uint8_t mode, uint8_t tx_power_level, struct UWB_CONFIG_T *ppdu_params) { // RF config uwb_channel_switch(ppdu_params->ch_num); - uwb_rx_antenna_open((enum UWB_RX_ANT_T)ppdu_params->rx_ant_id); + // Pulse shape + uwb_pulse_shape_set(ppdu_params->pulse_shape); + // Antenna + uwb_rx_antenna_open((enum UWB_RX_ANT_T)ppdu_params->rx_main_ant); + LOG_INFO(TRACE_MODULE_DRIVER, "Open ANT%d Pulseshape %d\r\n", ppdu_params->rx_main_ant & 0x03, ppdu_params->pulse_shape); - // Generate PHY configuration - void *sets_a = phy_params_generate(mode, HIGH_PERFORMANCE_MODE_EN, ppdu_params, NULL); - LOG_INFO(TRACE_MODULE_DRIVER, "PHY params sets %08x\r\n", (uint32_t)sets_a); -#if 0 - // Update ppdu_params to generate a new parameter sets - static uint32_t sets_b[128]; - phy_params_generate(mode, HIGH_PERFORMANCE_MODE_EN, ppdu_params, sets_b); -#endif - // Select a PHY parameter sets to configure - uwb_params_sets_switch(mode, sets_a); + // Configure PHY parameters + phy_params_configure(mode, HIGH_PERFORMANCE_MODE_EN, ppdu_params); + // PHY config if (mode & PHY_TX) { uwb_tx_init(tx_power_level); + phy_tx_params_set((void *)ppdu_params->phy_params_container); } if (mode & PHY_RX) { uwb_rx_init(); + phy_rx_params_set((void *)ppdu_params->phy_params_container); } // MAC config mac_crc_mode_configure(ppdu_params->fcs_type); - - return sets_a; -} - -void uwb_params_sets_switch(uint8_t mode, void *sets) -{ - phy_params_sets_enable(sets); - - if (mode & PHY_TX) - { - phy_tx_regs_config(sets); - } - - if (mode & PHY_RX) - { - phy_rx_regs_config(sets); - } } /* +scheduled_mode 0: Immediately 1: Defer to TX 2: CSMA-CA TX @@ -477,13 +495,13 @@ { int ret = 0; - if (scheduled_mode == 2) + if (scheduled_mode == TX_MODE_CSMACA) { // Power on radio power_on_radio(1, 1); ret = mac_tx(EVT_MODE_MAC_FIX_PHY_ASAP, target_time, 0, pkt_data, pkt_len); } - else if (scheduled_mode == 1) + else if (scheduled_mode == TX_MODE_DEFER) { power_on_radio(1, 0); ret = mac_tx(EVT_MODE_MAC_ASAP_PHY_FIX, target_time, 0, pkt_data, pkt_len); @@ -499,21 +517,23 @@ return ret; } -int uwb_rx(uint8_t scheduled_mode, uint32_t target_time, uint32_t timeout_us) +int uwb_rx(uint8_t scheduled_mode, uint32_t target_time, uint32_t timeout) { int ret = 0; + + sts_lsp_store(); // Power on radio power_on_radio(0, 1); uint32_t lock = int_lock(); - if (scheduled_mode) + if (scheduled_mode == RX_MODE_DEFER) { - ret = mac_rx(EVT_MODE_MAC_ASAP_PHY_FIX, target_time, US_TO_PHY_TIMER_COUNT(timeout_us)); + ret = mac_rx(EVT_MODE_MAC_ASAP_PHY_FIX, target_time, timeout); } else { - ret = mac_rx(EVT_MODE_MAC_PHY_ASAP, 0, US_TO_PHY_TIMER_COUNT(timeout_us)); + ret = mac_rx(EVT_MODE_MAC_PHY_ASAP, 0, timeout); } mac_start(); int_unlock(lock); @@ -522,24 +542,74 @@ return ret; } +/* +scheduled_mode +0: Immediately +1: Defer to TX +*/ +int uwb_loopback(uint8_t *pkt_data, uint16_t pkt_len, uint8_t scheduled_mode, uint32_t target_time) +{ + int ret = 0; + + // Enable loopback function + mac_loopback_mode_set(1); + +#if 0 + // Disable RX AGC, and use register to configure the gain of LNA and filter; + uint8_t rf_gain = 3; + uint8_t bb_gain = 0; + uint32_t val = (1U << 31) | ((bb_gain & 0x1FU) << 16) | (rf_gain & 0x7U); + REG_WRITE(0x40000700, val); + + val = REG_READ(0x40003040); + // Disable enAGC + val &= 0xFFFFFFFE; + REG_WRITE(0x40003040, val); +#endif + + // Power on radio + power_on_radio(1, 1); + + uint32_t lock = int_lock(); + + uint32_t target = REG_READ(0x40000418) + US_TO_PHY_TIMER_COUNT(100); + // Rx Timeout + REG_WRITE(0x40000408, target + US_TO_PHY_TIMER_COUNT(500)); + + if (scheduled_mode == TX_MODE_DEFER) + { + ret = mac_tx(EVT_MODE_MAC_ASAP_PHY_FIX, target_time, 0, pkt_data, pkt_len); + } + else + { + ret = mac_tx(EVT_MODE_MAC_PHY_ASAP, 0, 0, pkt_data, pkt_len); + } + mac_start(); + + int_unlock(lock); + + // LOG_INFO(TRACE_MODULE_DRIVER, "UWB Loopback %d\r\n", pkt_len); + return ret; +} + // cannot work at scheduled mode -void uwb_rx_force_off(uint8_t int_rpt_dis) +void uwb_rx_force_off(bool int_rpt_dis) { while ((REG_READ(0x40000400) & 0x0f) == 6) { } + uint32_t lock = int_lock(); if ((REG_READ(0x40000400) & 0x0f) == 7) { - uint32_t lock = int_lock(); uint32_t ts = phy_timer_count_get() + 250; /* 2us timeout */ REG_WRITE(0x40000408, ts); /* cfg the rx timeout */ if (int_rpt_dis) { mac_current_rx_report_discard(); } - int_unlock(lock); } + int_unlock(lock); } void uwb_tx_carrier_only(uint8_t on, uint8_t ch_num, uint8_t tx_power_level) @@ -548,6 +618,8 @@ if (on) { + power_on_radio(1, 0); + // start uwb_tx_init(tx_power_level); uwb_channel_switch(ch_num); @@ -570,6 +642,8 @@ // Disable datapath TX clock SYSCON->SYS_CMU &= ~(1U << CLOCK_TX); + + power_off_radio(); } } @@ -582,6 +656,9 @@ // Disable MAC interrupt NVIC_DisableIRQ(MAC_IRQn); + + uwb_rx(RX_MODE_IMMEDIATE, 0, MS_TO_PHY_TIMER_COUNT(10)); + delay_us(20); // MAC_MODE_CONTROL REG_WRITE(0x5000A004, 0x00000009); @@ -651,6 +728,7 @@ LOG_INFO(TRACE_MODULE_DRIVER, "uwb_blocking_tx_start exit\r\n"); + power_off_radio(); mac_restart(); } @@ -661,6 +739,8 @@ // Disable MAC interrupt NVIC_DisableIRQ(MAC_IRQn); + + power_on_radio(0, 1); // MAC_MODE_CONTROL - clear MAC (bug in software mode) REG_WRITE(0x5000A004, 0x00000009); @@ -736,6 +816,7 @@ LOG_INFO(TRACE_MODULE_DRIVER, "uwb_blocking_rx_start exit\r\n"); + power_off_radio(); mac_restart(); } @@ -744,3 +825,250 @@ flag_uwb_sw_trx_start = 0; LOG_INFO(TRACE_MODULE_DRIVER, "uwb_blocking_trx_stop\r\n"); } + +#if RANGING_EN +static volatile uint16_t loopback_num = 300; +static volatile uint16_t loopback_count = 0; + +static volatile uint16_t loopback_rx_timestamp_frac = 0; +static volatile int16_t loopback_time_min = 32767; +static volatile int16_t loopback_time_max = -32768; +static volatile int32_t loopback_time_sum = 0; +static volatile uint8_t loopback_cal_done = 0; + +static void uwb_loopback_tx_process(struct MAC_HW_REPORT_T *tx_report) +{ + int64_t tx_timestamp = 0; + uint16_t tx_timestamp_frac = 0; + // uint32_t tx_timestamp_int = 0; + int16_t loopback_time = 0; + + if ((tx_report->err_code == UWB_TX_OK) && (loopback_rx_timestamp_frac != 0x8000)) + { + tx_timestamp = ranging_tx_time(tx_report->timestamp); + tx_timestamp_frac = tx_timestamp & 0x1ff; + // tx_timestamp_int = (uint32_t)(tx_timestamp >> 9); + + loopback_time = (int16_t)(loopback_rx_timestamp_frac - tx_timestamp_frac); + + if (loopback_time > loopback_time_max) + { + loopback_time_max = loopback_time; + } + else if (loopback_time < loopback_time_min) + { + loopback_time_min = loopback_time; + } + + loopback_count++; + if (loopback_count >= loopback_num) + { + // Check later + loopback_cal_done = 1; + } + loopback_time_sum += loopback_time; + // LOG_INFO(TRACE_MODULE_APP, "Loopback time $%d;\r\n", loopback_time); + + // uint32_t val = REG_READ(0x40003050); + // uint8_t rf_gain = (val & 0x07); + // uint8_t bb_gain = ((val >> 3) & 0x1f); + // LOG_INFO(TRACE_MODULE_APP, "rf_gain %u bb_gain %u\r\n", rf_gain, bb_gain); + } +} + +static void uwb_loopback_rx_process(struct MAC_HW_REPORT_T *rx_report) +{ + power_off_radio(); + int64_t rx_timestamp = 0; + // uint32_t rx_timestamp_int = 0; + + if (rx_report->err_code == UWB_RX_OK) + { + rx_timestamp = ranging_rx_time(rx_report); + loopback_rx_timestamp_frac = rx_timestamp & 0x1ff; + // rx_timestamp_int = (uint32_t)(rx_timestamp >> 9); + } + else + { + // Loopback error + loopback_rx_timestamp_frac = 0x8000; + } +} + +void uwb_loopback_time_update(uint16_t count, struct UWB_CONFIG_T *ppdu_params) +{ + uint8_t tx_payload[20]; + uint16_t tx_len = 20; + + for (uint8_t i = 0; i < tx_len; i++) + { + tx_payload[i] = 0x55; + } + + // high Tx power will cause saturation + uwb_configure(PHY_TX | PHY_RX, 10, ppdu_params); + // init ranging lib for timestamp calculation + ranging_lib_init(ppdu_params->sts_pkt_cfg, CE_AUX_CH_PWR_NLOS_FOM); + + mac_callback_t bak_tx_cb; + mac_callback_t bak_rx_cb; + + uint32_t lock = int_lock(); + mac_get_process_handler(&bak_tx_cb, &bak_rx_cb); + mac_register_process_handler(uwb_loopback_tx_process, uwb_loopback_rx_process); + int_unlock(lock); + + loopback_num = count; + loopback_count = 0; + + loopback_cal_done = 0; + loopback_time_sum = 0; + loopback_time_min = 32767; + loopback_time_max = -32768; + + do + { + if (ppdu_params->sts_pkt_cfg == STS_PKT_CFG_3) + { + uwb_loopback(NULL, 0, 0, 0); + } + else + { + uwb_loopback(tx_payload, tx_len, 0, 0); + } + + delay_us(1800); + + // Check the MAC busy state + while (mac_is_busy()) + { + } + + } while (loopback_cal_done == 0); + + board_param.loopback_time = (int16_t)(loopback_time_sum / loopback_num); + + LOG_INFO(TRACE_MODULE_APP, "Loopback time [%d, %d] %d \r\n", loopback_time_min, loopback_time_max, board_param.loopback_time); + + // Restore MAC callback + mac_register_process_handler(bak_tx_cb, bak_rx_cb); +} + +void uwb_loopback_calibration(uint8_t wr_nvm_en, uint16_t count, struct UWB_CONFIG_T *ppdu_params) +{ + uint8_t tx_payload[20]; + uint16_t tx_len = 20; + + for (uint8_t i = 0; i < tx_len; i++) + { + tx_payload[i] = 0x55; + } + + // high Tx power will cause saturation + uwb_configure(PHY_TX | PHY_RX, 10, ppdu_params); + // init ranging lib for timestamp calculation + ranging_lib_init(ppdu_params->sts_pkt_cfg, CE_AUX_CH_PWR_NLOS_FOM); + + mac_callback_t bak_tx_cb; + mac_callback_t bak_rx_cb; + + uint32_t lock = int_lock(); + mac_get_process_handler(&bak_tx_cb, &bak_rx_cb); + mac_register_process_handler(uwb_loopback_tx_process, uwb_loopback_rx_process); + int_unlock(lock); + + uint16_t loopback_time_range[3] = {0xffff, 0xffff, 0xffff}; + int16_t loopback_time_avg[3]; + loopback_num = count; + + for (uint8_t j = 0; j < 3; j++) + { + // VDD_core voltage ranging [1, 2, 3] + board_param.vdd_core_vol = j + 1; + loopback_cal_done = 0; + loopback_count = 0; + loopback_time_sum = 0; + loopback_time_min = 32767; + loopback_time_max = -32768; + + do + { + if (ppdu_params->sts_pkt_cfg == STS_PKT_CFG_3) + { + uwb_loopback(NULL, 0, 0, 0); + } + else + { + uwb_loopback(tx_payload, tx_len, 0, 0); + } + + delay_us(1800); + + // Check the MAC busy state + while (mac_is_busy()) + { + } + + } while (loopback_cal_done == 0); + + loopback_time_range[j] = (uint16_t)(loopback_time_max - loopback_time_min); + loopback_time_avg[j] = (int16_t)(loopback_time_sum / loopback_num); +#if 0 + // Set a condition to speed up calibration + if (loopback_time_range[j] < 30) + { + break; + } +#endif + } + + uint8_t idx = 0; + if (loopback_time_range[2] > loopback_time_range[1]) + { + if (loopback_time_range[0] > loopback_time_range[1]) + { + // 2 > 0 > 1 + idx = 1; + } + else + { + // 2 > 1 >= 0 + idx = 0; + } + } + else + { + if (loopback_time_range[2] > loopback_time_range[0]) + { + // 1 >= 2 > 0 + idx = 0; + } + else + { + // 1 >= 0 >= 2 + idx = 2; + } + } + board_param.vdd_core_vol = idx + 1; + board_param.loopback_time = loopback_time_avg[idx]; + + LOG_INFO(TRACE_MODULE_APP, "Loopback %u %u %u [%d]%d\r\n", loopback_time_range[0], loopback_time_range[1], loopback_time_range[2], board_param.vdd_core_vol, + board_param.loopback_time); + + // Restore MAC callback + mac_register_process_handler(bak_tx_cb, bak_rx_cb); + // Write NVM + if (wr_nvm_en) + { + board_calibration_param_write(BOARD_VDD_CORE_VOL, &board_param.vdd_core_vol, sizeof(board_param.vdd_core_vol)); + board_calibration_param_write(BOARD_LOOPBACK_TIME, (uint8_t *)&board_param.loopback_time, sizeof(board_param.loopback_time)); + } +} +#else +void uwb_loopback_calibration(uint8_t wr_nvm_en, uint16_t count, struct UWB_CONFIG_T *ppdu_params) +{ + UNUSED(wr_nvm_en); + UNUSED(count); + UNUSED(ppdu_params); +} +#endif -- Gitblit v1.9.3