yincheng.zhong
2024-08-20 7744fffacb03dc81cc9dbaf9f5d86a0f21e79c03
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
/*
 * 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.
 */
 
#ifndef RANGING_LIB_H
#define RANGING_LIB_H
#include "mk_mac.h"
#include "mk_phy.h"
 
/**
 * @addtogroup MK8000_ALGO_Ranging
 * @{
 */
 
#ifndef CHEST_DUMP_EN
#define CHEST_DUMP_EN (1)
#endif
 
/* When debugging offline channel estimation, enable this macro */
#ifndef OFFLINE_CHEST_EN
#define OFFLINE_CHEST_EN (0)
#endif
 
// total channel tap length
#define MLAGS_LENGTH 160
// output channel tap length
#define CH_LEN_DEFAULT (128)
 
/** Ranging channel status information */
struct RANGING_CSI_T
{
    uint32_t session_id;
    uint32_t sts_index;
    uint16_t ranging_status;
    uint16_t block_index;
    uint16_t round_index;
    uint16_t distance_cm;
    int16_t azimuth;
    uint8_t ranging_fom;
    uint8_t azimuth_fom;
    uint8_t frame_idx;
    uint8_t rframe_idx;
    uint16_t reserved;
 
    // pre-poll | poll | final | final-data
    struct FRAME_INF_T
    {
        int8_t rssi;
        int8_t snr;
        uint8_t rf_gain;
        uint8_t bb_gain;
        uint16_t bd_cnt;
        uint16_t sfd_cnt;
        uint16_t error_code;
    } frame[4];
 
    // poll | final
    struct RFRAME_INF_T
    {
        int32_t freq_offset;
        float kfactor;
        uint32_t channel_power;
        uint32_t noise_power;
        int8_t main_tap_power;
        int8_t first_tap_power;
        uint8_t main_tap;
        uint8_t first_tap;
        uint8_t sts_main_tap;
        uint8_t sts_first_tap;
        uint8_t nlos;
        uint8_t fom;
        int8_t cir[128][2];
        float sts_taps[11];
    } rframe[2];
};
 
typedef struct
{
    int16_t tap1_loc;
    int16_t tap2_loc;
    int16_t tap3_loc;
    float tap1_re;
    float tap1_im;
    float tap2_re;
    float tap2_im;
    float tap3_re;
    float tap3_im;
    int16_t fap_loc;
    float fap_pow;
} ranging_aux_t;
 
typedef struct
{
    float Kfactor;          ///> ratio of the main tap to the total energy
    int16_t loc_deviation;  ///> Deviation in main tap location from the expected one
    float fom1;             ///> Mean excess delay spread
    float fom2;             ///> RMS delay spread
    float fom3;             ///> Channel type: 0/1 : LoS, 2: Multipath, 3: NLos
    ranging_aux_t aux_data; ///> First path location and energy
    float mean_npwr;        ///> Mean noise power (in offline CE mode) -- linear scale
    float max_npwr;         ///> Max noise power (in offline CE mode) -- linear scale
    float chpwr;            ///> Total channel power (in offline CE mode) -- linear scale
} ranging_FoM_t;
 
struct RANGING_TAPS_INF_T
{
    int16_t fap_loc;
    int16_t tap1_loc;
    int16_t tap2_loc;
    int16_t tap3_loc;
    float fap_pow;
    float tap1_pow;
    float tap2_pow;
    float tap3_pow;
    float Kfactor;         // ratio of the main tap to the total energy
    int16_t loc_deviation; // Deviation in main tap location from the expected one
    uint8_t NLoS;          // 0/1: LoS, 2: Multipath, 3: NLoS
    uint8_t FoM;           // 0 ~ 100
};
 
#ifdef __cplusplus
extern "C" {
#endif
 
#if CHEST_DUMP_EN
#define CIR_LEN 128
#define CE_WIN 16
 
#define PWR_TH 100
#define TAP_MARGIN 4
 
extern struct RANGING_CSI_T debug_csi;
uint8_t first_path_align(uint8_t *ce_chest_gaps, uint8_t *ce_chest_gaps_num, int8_t ce_chest[CIR_LEN][2], uint8_t ce_fap, uint8_t th, uint8_t margin);
uint8_t ranging_fom_calculate(struct RANGING_CSI_T *csi, uint8_t response_fom, uint8_t *response_tap_gaps, uint8_t response_tap_gaps_num);
void dump_preamble_cir(uint8_t idx, uint8_t taps_num);
void dump_sts_cir(uint8_t idx);
void print_preamble_chest(uint8_t rx_pkt_num, uint8_t rframe_num);
void print_sts_ch_taps(uint8_t rframe_num);
void calculate_first_tap_power(uint8_t rx_pkt_num, uint8_t rframe_num);
int8_t calculate_noise_floor(uint8_t rf_gain, uint8_t bb_gain);
#endif
 
/**
 * @brief Initialize all the global variables that will be used in the ranging lib.
 */
void ranging_lib_init(void);
 
/**
 * @brief Enable or disable ranging debug CSI output
 * @param[in] en        Enable or disable
 */
void ranging_debug_csi_en_set(uint8_t en);
 
/**
 * @brief Get ranging debug CSI output status
 * @return ranging debug CSI output status
 */
uint8_t ranging_debug_csi_en_get(void);
 
/**
 * @brief Set ranging frame type.
 * @param[in] type    ranging frame type, SP0 ~ SP3
 */
void ranging_frame_type_set(uint8_t type);
 
/**
 * @brief Get ranging frame type.
 * @return ranging frame type SP0 ~ SP3
 */
uint8_t ranging_frame_type_get(void);
 
/**
 * @brief Detect the fisrt path of ranging frame.
 * @param[in] rssi    Rx packet RSSI
 * @return delta of the first path
 */
int32_t ranging_first_path_detect(int8_t rssi);
 
/**
 * @brief Calculate TX timestamp of the ranging frame.
 *
 * @param[in] timestamp    PHY timer count of TX
 * @return TX timestamp (unit: 15.65ps)
 */
int64_t ranging_tx_time(uint32_t timestamp);
 
/**
 * @brief Calculate RX timestamp of the ranging frame.
 *
 * @param[in] ind    MAC RX report
 * @return RX timestamp (unit: 15.65ps)
 */
int64_t ranging_rx_time(const struct MAC_HW_REPORT_T *ind);
 
/**
 * @brief Get ranging FAP FoM.
 *
 * @param[out] NLoS     Non-Line of sight flag, 0/1: LoS, 2: Multipath, 3: NLoS
 * @param[out] FoM      FAP confidence measure, 0 ~ 100
 */
void ranging_fom_get(uint8_t *NLoS, uint8_t *FoM);
 
/**
 * @brief Get multi-taps information.
 *
 * @param[out] inf    multi-taps information
 */
void ranging_taps_inf_get(struct RANGING_TAPS_INF_T *inf);
 
/**
 * @brief Get multi-taps I/Q result.
 *
 * @param[out] chtaps_re pointer of output buffer of multi-taps real part
 * @param[out] chtaps_im pointer of output buffer of multi-taps imagine part
 * @param[in] taps_num number of taps to be get, the maximum value is 128
 */
void ranging_multi_taps_iq_get(float *chtaps_re, float *chtaps_im, uint8_t taps_num);
 
#if OFFLINE_CHEST_EN
/**
 * @brief Enable offline channel estimate.
 *
 * @param[in] en enable or disable
 */
void ranging_offline_chest_enable(uint8_t en);
#endif
 
/**
 * @brief Set antenna delay for ranging.
 *
 * @param[in] ant_idx       antenna port index, from 0 to 3
 * @param[in] delay_ps      antenna delay, unit 15.6ps
 */
void ranging_ant_delays_set(uint8_t ant_idx, int16_t delay_ps);
 
/**
 * @brief Get antenna delay for ranging.
 *
 * @param[in] ant_idx       antenna port index, from 0 to 3
 * @return antenna delay of the specified port, unit 15.6ps
 */
int16_t ranging_ant_delays_get(uint8_t ant_idx);
 
/**
 * @brief Select aux information output
 *
 * @param [in] len       Length of samples to be processed (64, 32)
 * @param [in] opt       Options for aux information
 *    0 (000)    -    No auxiliary data is generated
 *    1 (001)    -    combo 1 (Kfactor, location deviation, LoS/NLoS)
 *    2 (010)    -    combo 2 (3 largest taps info)
 *    4 (100)    -    combo 3 (Mean excess delay, RMS excess delay)
 *    3 (011)    -    combo 1 and combo 2
 *    5 (101)    -    combo 1 and combo 3
 *    7 (111)    -    combo 1, 2 and 3
 *
 */
void ranging_aux_out_opt_set(uint8_t len, uint8_t opt);
 
/**
 * @brief Get UWB RX RSSI.
 *
 * @param[out] rssi    RSSI (-110 ~ -10) dBm
 * @param[out] snr     SNR (-21 ~ 20) dB
 */
void ranging_rssi_get(int8_t *rssi, int8_t *snr);
 
/**
 * @brief Compute expected RSSI based on TX power and ranging distance result
 *
 * @param[in] uwb_tx_power      Ranging UWB TX power in dBm
 * @param[in] distance          Ranging distance result in cm
 * @param[in] path_loss_exp     Ranges from 2 to 5 (including fractional values, simplified here) 2 - for outdoor, 3 or 4 for multipath channels
 * @param[in] ant_gain_loss     Antenna gain or loss in dB
 */
int8_t ranging_expected_rssi_get(int8_t uwb_tx_power, uint16_t distance, uint8_t path_loss_exp, int8_t ant_gain_loss);
 
/**
 * @brief Get ranging library version.
 *
 * @return String of ranging library version
 */
const char *MK8000_get_rangelib_version(void);
 
#ifdef __cplusplus
}
#endif
 
/**
 * @}
 */
 
#endif // RANGING_LIB_H