/*
|
* Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and
|
* its subsidiaries and affiliates (collectly called MKSEMI).
|
*
|
* All rights reserved.
|
*
|
* Redistribution and use in source and binary forms, with or without
|
* modification, are permitted provided that the following conditions are met:
|
*
|
* 1. Redistributions of source code must retain the above copyright notice,
|
* this list of conditions and the following disclaimer.
|
*
|
* 2. Redistributions in binary form, except as embedded into an MKSEMI
|
* integrated circuit in a product or a software update for such product,
|
* must reproduce the above copyright notice, this list of conditions and
|
* the following disclaimer in the documentation and/or other materials
|
* provided with the distribution.
|
*
|
* 3. Neither the name of MKSEMI nor the names of its contributors may be used
|
* to endorse or promote products derived from this software without
|
* specific prior written permission.
|
*
|
* 4. This software, with or without modification, must only be used with a
|
* MKSEMI integrated circuit.
|
*
|
* 5. Any software provided in binary form under this license must not be
|
* reverse engineered, decompiled, modified and/or disassembled.
|
*
|
* THIS SOFTWARE IS PROVIDED BY MKSEMI "AS IS" AND ANY EXPRESS OR IMPLIED
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
* MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
* DISCLAIMED. IN NO EVENT SHALL MKSEMI OR CONTRIBUTORS BE LIABLE FOR ANY
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
*/
|
|
#include "mk_trace.h"
|
#include "mk_clock.h"
|
#include "mk_power.h"
|
#include "mk_uwb.h"
|
#include "mk_radar.h"
|
#include "mk_sleep_timer.h"
|
#include "mk_misc.h"
|
#include "uwb_api.h"
|
#include "uwb_radar_task.h"
|
#include "uwb_radar.h"
|
#if UWB_RADAR_DETECT_PROCESS_EN
|
#include "mk8000_present_interface.h"
|
#endif
|
// #include "board.h"
|
|
#define DEBUG_MEM_ADDR 0x02010000
|
#define RADAR_PRINT_EN 0
|
|
/*************************************************************************************************/
|
/*!
|
* \brief WSF event handler for uwb radar task.
|
*
|
* \param event WSF event mask.
|
* \param msg WSF message.
|
*
|
* \return None.
|
*/
|
/*************************************************************************************************/
|
|
#if UWB_RADAR_DETECT_PROCESS_EN
|
static float ref_out[256] = {0.0};
|
static struct Cf_sto cf_data[64] = {0};
|
|
static struct Present_sto present = {
|
.cf_data = cf_data,
|
.Y = ref_out,
|
.index = 0,
|
.flag = 0,
|
};
|
|
static struct Pres_para_sto pre_para = {
|
.cp_para =
|
{
|
// choose cfar threshold in each section
|
.sec_alp = {35, 33, 20, 10, 10, 15, 15},
|
// Choose cfar solution in each section,0:so cfar 1:ca cfar 2:go cfar
|
.sec_sol = {1, 1, 0, 0, 0, 1, 1},
|
// range index:[start,end,multi taget num in each section]
|
.range = {2, 36, 0},
|
// the safe section,the reference section
|
.ref_x = {5, 4, 2},
|
// Apart the range into sen_len sections
|
.sec_len = 5,
|
// 0:choose max power target
|
// 1:choose max power target in each section
|
// 2:choose max power target in first section
|
.tar_num = 3,
|
.nbor = 1,
|
.ma_val = 1000,
|
},
|
// 1:adaptive,High Freq 20/30/80Hz 0:not adaptive 1Hz
|
.train = 1,
|
// 0: no calibration,
|
// 1: take last pulse as reference, >1: take mean(rep pulses) as reference, from frame=0 to frame = rep
|
.rep = 1,
|
// Number of learning frame
|
.frame = 0,
|
.norm = 1000,
|
.apole = 0.3f,
|
.acc = 3,
|
};
|
#endif
|
|
struct sample16_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[PULSE_PERIOD_POINTS(0) * 2];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
struct sample32_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[PULSE_PERIOD_POINTS(1) * 2];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
struct sample64_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[PULSE_PERIOD_POINTS(2) * 2];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
struct sample128_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[PULSE_PERIOD_POINTS(3) * 2];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
struct sample256_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[PULSE_PERIOD_POINTS(4) * 2];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
struct sample_1tnr_pack
|
{
|
uint16_t header;
|
uint16_t length;
|
uint32_t seq;
|
float acd_out[OUT_FRAME_LEN * UWB_RADAR_RX_PORT_NUM];
|
uint16_t check_num;
|
uint16_t end;
|
};
|
|
union xfer_sample_pack
|
{
|
#define SAMPLE_PACK_FIX_LENGTH 12
|
struct sample16_pack sample16;
|
struct sample32_pack sample32;
|
struct sample64_pack sample64;
|
struct sample128_pack sample128;
|
struct sample256_pack sample256;
|
struct sample_1tnr_pack sample_1tnr;
|
};
|
|
static union xfer_sample_pack xfer_pack = {
|
.sample_1tnr.header = 0x5555,
|
};
|
|
#if UWB_RADAR_DETECT_PROCESS_EN == 0 && UWB_RADAR_UCI_EN == 0
|
static void xfer_done(void *dev, uint32_t err_code)
|
{
|
// board_led_off(BOARD_LED_1);
|
}
|
#endif
|
|
void uwb_radar_handler(wsfEventMask_t event, const void *param)
|
{
|
// const wsfMsgHdr_t *msg = (const wsfMsgHdr_t *)param;
|
// board_led_on(BOARD_LED_2);
|
|
if (uwb_is_radar_mode())
|
{
|
uint16_t data_len;
|
|
switch (uwb_app_config.session_type)
|
{
|
case SESSION_TYPE_VENDOR_RANGING_AND_RADAR:
|
{
|
switch (event)
|
{
|
case UWB_RADAR_START_SAMPLING_EVT:
|
{
|
/* Creat radar event */
|
uwb_radar_creat_event();
|
phy_sts_pkt_cfg_set(3);
|
radar_enable();
|
power_on_radio(1, 1);
|
radar_start(radar_env.rx_ant_idx);
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_SLEEP);
|
}
|
break;
|
|
case UWB_RADAR_SAMPLING_COMPLETE_EVT:
|
{
|
/* Data preprocessing, XIP 19.8ms */
|
power_off_radio();
|
radar_disable();
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_POWER_DOWN);
|
|
radar_data_process((uint32_t *)DEBUG_MEM_ADDR, xfer_pack.sample_1tnr.acd_out, &data_len);
|
uwb_radar_destroy_event();
|
|
#if UWB_RADAR_UCI_EN
|
uwbapi_report_radar_raw_data(data_len, (uint8_t *)xfer_pack.sample_1tnr.acd_out);
|
#else
|
#if UWB_RADAR_DETECT_PROCESS_EN
|
// board_led_on(BOARD_LED_1);
|
mcu_target_detect_process(xfer_pack.sample_1tnr.acd_out, PULSE_PERIOD_POINTS(UWB_RADAR_PULSE_PERIOD), &pre_para, &present);
|
/* Object detection, the result shows */
|
if (present.flag)
|
{
|
uint16_t distance = (uint16_t)(((float)present.index * 0.15f) * 100);
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "Presence: YES, Radar Distance: %ucm\r\n", distance);
|
}
|
else
|
{
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "Presence: NO, Radar Distance: 0cm\r\n");
|
}
|
// board_led_off(BOARD_LED_1);
|
|
#else
|
// board_led_on(BOARD_LED_1);
|
LOG_INFO(TRACE_MODULE_APP, "Radar output data len: %u\r\n", data_len);
|
xfer_pack.sample_1tnr.length = data_len + SAMPLE_PACK_FIX_LENGTH;
|
xfer_pack.sample_1tnr.seq = radar_env.rx_ant_idx;
|
uint16_t check_num = uwb_radar_data_checksum((const uint8_t *)xfer_pack.sample_1tnr.acd_out, data_len);
|
|
#if UWB_RADAR_1TNR_MODE == 1
|
xfer_pack.sample_1tnr.check_num = check_num;
|
xfer_pack.sample_1tnr.end = 0xAAAA;
|
#else
|
if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_16NS)
|
{
|
xfer_pack.sample16.check_num = check_num;
|
xfer_pack.sample16.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_32NS)
|
{
|
xfer_pack.sample32.check_num = check_num;
|
xfer_pack.sample32.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_64NS)
|
{
|
xfer_pack.sample64.check_num = check_num;
|
xfer_pack.sample64.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_128NS)
|
{
|
xfer_pack.sample128.check_num = check_num;
|
xfer_pack.sample128.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_256NS)
|
{
|
xfer_pack.sample256.check_num = check_num;
|
xfer_pack.sample256.end = 0xAAAA;
|
}
|
#endif
|
uart_send(DUMP_DATA_PORT, (uint8_t *)(&xfer_pack), xfer_pack.sample_1tnr.length, xfer_done);
|
#endif
|
#endif
|
}
|
break;
|
}
|
}
|
break;
|
|
case SESSION_TYPE_VENDOR_ALONE_RADAR:
|
{
|
const wsfMsgHdr_t *msg = (const wsfMsgHdr_t *)param;
|
if (msg != NULL)
|
{
|
if (msg->event == UWB_RADAR_ALONE_WAKEUP_MSG)
|
{
|
uwb_radar_alone_continue_trigger();
|
}
|
}
|
else
|
{
|
switch (event)
|
{
|
case UWB_RADAR_START_SAMPLING_EVT:
|
{
|
phy_sts_pkt_cfg_set(3);
|
radar_enable();
|
power_on_radio(1, 1);
|
radar_start(radar_env.rx_ant_idx);
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_SLEEP);
|
}
|
break;
|
|
case UWB_RADAR_SAMPLING_COMPLETE_EVT:
|
{
|
/* Data preprocessing, XIP 19.8ms */
|
power_off_radio();
|
radar_disable();
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_POWER_DOWN);
|
|
radar_data_process((uint32_t *)DEBUG_MEM_ADDR, xfer_pack.sample_1tnr.acd_out, &data_len);
|
|
#if UWB_RADAR_UCI_EN
|
uwbapi_report_radar_raw_data(data_len, (uint8_t *)xfer_pack.sample_1tnr.acd_out);
|
#else
|
#if RADAR_PRINT_EN
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "--------------%u--------------\r\n", data_len);
|
for (uint8_t i = 0; i < PULSE_PERIOD_POINTS(UWB_RADAR_PULSE_PERIOD); i++)
|
{
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "%.2f %.2f\n", xfer_pack.sample_1tnr.acd_out[i * 2],
|
xfer_pack.sample_1tnr.acd_out[i * 2 + 1]);
|
}
|
#endif
|
#if UWB_RADAR_DETECT_PROCESS_EN
|
// board_led_on(BOARD_LED_1);
|
mcu_target_detect_process(xfer_pack.sample_1tnr.acd_out, PULSE_PERIOD_POINTS(UWB_RADAR_PULSE_PERIOD), &pre_para, &present);
|
/* Object detection, the result shows */
|
if (present.flag)
|
{
|
uint16_t distance = (uint16_t)(((float)present.index * 0.15f) * 100);
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "\r\nPresence: YES, Radar Distance: %ucm\r\n", distance);
|
}
|
else
|
{
|
LOG_INFO(TRACE_MODULE_APP | TRACE_NO_OPTION, "\r\nPresence: NO, Radar Distance: 0cm\r\n");
|
}
|
// board_led_off(BOARD_LED_1);
|
#else
|
// board_led_on(BOARD_LED_1);
|
LOG_INFO(TRACE_MODULE_APP, "Radar output data len: %u\r\n", data_len);
|
xfer_pack.sample_1tnr.length = data_len + SAMPLE_PACK_FIX_LENGTH;
|
xfer_pack.sample_1tnr.seq = radar_env.rx_ant_idx;
|
uint16_t check_num = uwb_radar_data_checksum((const uint8_t *)xfer_pack.sample_1tnr.acd_out, data_len);
|
#if UWB_RADAR_1TNR_MODE == 1
|
xfer_pack.sample_1tnr.check_num = check_num;
|
xfer_pack.sample_1tnr.end = 0xAAAA;
|
#else
|
if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_16NS)
|
{
|
xfer_pack.sample16.check_num = check_num;
|
xfer_pack.sample16.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_32NS)
|
{
|
xfer_pack.sample32.check_num = check_num;
|
xfer_pack.sample32.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_64NS)
|
{
|
xfer_pack.sample64.check_num = check_num;
|
xfer_pack.sample64.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_128NS)
|
{
|
xfer_pack.sample128.check_num = check_num;
|
xfer_pack.sample128.end = 0xAAAA;
|
}
|
else if (uwb_app_config.session_param.uwb_radar_pulse_period == UWB_RADAR_PULSE_PERIOD_256NS)
|
{
|
xfer_pack.sample256.check_num = check_num;
|
xfer_pack.sample256.end = 0xAAAA;
|
}
|
#endif
|
uart_send(DUMP_DATA_PORT, (uint8_t *)(&xfer_pack), xfer_pack.sample_1tnr.length, xfer_done);
|
#endif
|
#endif
|
}
|
break;
|
}
|
}
|
}
|
break;
|
}
|
}
|
else
|
{
|
radar_disable();
|
power_off_radio();
|
power_mode_request(POWER_UNIT_APP, POWER_MODE_POWER_DOWN);
|
uwb_radar_force_destroy_event();
|
if (SESSION_TYPE_VENDOR_ALONE_RADAR == uwb_app_config.session_type)
|
{
|
uwb_radar_alone_timer_clr();
|
}
|
}
|
// board_led_off(BOARD_LED_2);
|
}
|