Skip to content

Commit c00ed8f

Browse files
maje-embrlubos
authored andcommitted
dm: Add support for high-precision distance calculations
Add support for high-precision distance estimation from nrf_dm. Estimate the distance with more computation-intensive higher precision algorithm. Ref: WRLS-1421 Signed-off-by: Marcin Jeliński <marcin.jelinski@nordicsemi.no>
1 parent ce5a25a commit c00ed8f

File tree

5 files changed

+79
-42
lines changed

5 files changed

+79
-42
lines changed

include/dm.h

+5
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ struct dm_result {
9393

9494
/** Best effort distance estimate. */
9595
float best;
96+
97+
#ifdef CONFIG_DM_HIGH_PRECISION_CALC
98+
/* MCPD: Distance estimate based on advanced algorithms */
99+
float high_precision;
100+
#endif
96101
} mcpd;
97102
struct rtt {
98103
/** RTT: Distance estimate based on RTT measurement. */

subsys/dm/Kconfig

+18-8
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,41 @@ if DM_MODULE
1515

1616
menu "nRF DM (Distance Measurement)"
1717

18-
choice NRF_DM_TIMER
19-
default NRF_DM_TIMER2
20-
prompt "Timer to use for the nrf_dm library"
18+
choice DM_TIMER
19+
default DM_TIMER2
20+
prompt "Timer to use for the nrf_dm library."
2121

22-
config NRF_DM_TIMER0
22+
config DM_TIMER0
2323
depends on HAS_HW_NRF_TIMER0
2424
bool "TIMER0"
2525

26-
config NRF_DM_TIMER1
26+
config DM_TIMER1
2727
depends on HAS_HW_NRF_TIMER1
2828
bool "TIMER1"
2929

30-
config NRF_DM_TIMER2
30+
config DM_TIMER2
3131
depends on HAS_HW_NRF_TIMER2
3232
bool "TIMER2"
3333

34-
config NRF_DM_TIMER3
34+
config DM_TIMER3
3535
depends on HAS_HW_NRF_TIMER3
3636
bool "TIMER3"
3737

38-
config NRF_DM_TIMER4
38+
config DM_TIMER4
3939
depends on HAS_HW_NRF_TIMER4
4040
bool "TIMER4"
4141

4242
endchoice
4343

44+
config DM_HIGH_PRECISION_CALC
45+
# Due to memory limitations, functionality is not provided for nrf52832.
46+
depends on !SOC_NRF52832
47+
default n
48+
bool "Use high-precision distance estimation"
49+
help
50+
"Use a more compute-intensive algorithm for the distance estimation.
51+
Only works with MCPD ranging mode"
52+
4453
config DM_TIMESLOT_RESCHEDULE
4554
bool "Timeslot reschedule"
4655
default n
@@ -55,6 +64,7 @@ config DM_INITIATOR_DELAY_US
5564

5665
config DM_MIN_TIME_BETWEEN_TIMESLOTS_US
5766
int "Minimum time between two timeslots"
67+
default 180000 if DM_HIGH_PRECISION_CALC
5868
default 8000
5969
help
6070
"Minimum time between two timeslots.

subsys/dm/dm.c

+35-23
Original file line numberDiff line numberDiff line change
@@ -37,29 +37,35 @@
3737

3838
LOG_MODULE_REGISTER(nrf_dm, CONFIG_DM_MODULE_LOG_LEVEL);
3939

40-
#ifdef CONFIG_NRF_DM_TIMER0
41-
#define NRF_DM_TIMER NRF_TIMER0
40+
#ifdef CONFIG_DM_TIMER0
41+
#define DM_TIMER NRF_TIMER0
4242
#endif
43-
#ifdef CONFIG_NRF_DM_TIMER1
44-
#define NRF_DM_TIMER NRF_TIMER1
43+
#ifdef CONFIG_DM_TIMER1
44+
#define DM_TIMER NRF_TIMER1
4545
#endif
46-
#ifdef CONFIG_NRF_DM_TIMER2
47-
#define NRF_DM_TIMER NRF_TIMER2
46+
#ifdef CONFIG_DM_TIMER2
47+
#define DM_TIMER NRF_TIMER2
4848
#endif
49-
#ifdef CONFIG_NRF_DM_TIMER3
50-
#define NRF_DM_TIMER NRF_TIMER3
49+
#ifdef CONFIG_DM_TIMER3
50+
#define DM_TIMER NRF_TIMER3
5151
#endif
52-
#ifdef CONFIG_NRF_DM_TIMER4
53-
#define NRF_DM_TIMER NRF_TIMER4
52+
#ifdef CONFIG_DM_TIMER4
53+
#define DM_TIMER NRF_TIMER4
5454
#endif
5555

5656
#define PPI_CH_COUNT 2
5757

5858
#define MPSL_THREAD_PRIO CONFIG_MPSL_THREAD_COOP_PRIO
59-
#define STACKSIZE CONFIG_MAIN_STACK_SIZE
60-
#define DM_THREAD_PRIORITY K_HIGHEST_APPLICATION_THREAD_PRIO
59+
#define MPSL_THREAD_STACK_SIZE CONFIG_MAIN_STACK_SIZE
60+
#define DM_THREAD_PRIORITY 0
6161
#define TIMESLOT_TIMEOUT_STEP_MS 120000
6262

63+
#if CONFIG_DM_HIGH_PRECISION_CALC && !defined(NRF5340_XXAA)
64+
#define DM_THREAD_STACK_SIZE 2560
65+
#else
66+
#define DM_THREAD_STACK_SIZE 1536
67+
#endif
68+
6369
#define DM_TIMESLOT_OVERHEAD_US 400
6470
#define DM_REFLECTOR_OVERHEAD_US 2000
6571

@@ -176,6 +182,7 @@ static mpsl_timeslot_signal_return_param_t *mpsl_timeslot_callback(
176182
dm_io_set(DM_IO_RANGING);
177183

178184
if (atomic_get(&timeslot_ctx.state) == TIMESLOT_STATE_EARLY_PENDING) {
185+
dm_io_clear(DM_IO_RANGING);
179186
return p_ret_val;
180187
}
181188

@@ -258,7 +265,7 @@ static void mpsl_nonpreemptible_thread(void)
258265
}
259266
}
260267

261-
static void process_data(const nrf_dm_report_t *data)
268+
static void process_data(const nrf_dm_report_t *data, float high_precision_estimate)
262269
{
263270
if (!data) {
264271
result.status = false;
@@ -287,6 +294,9 @@ static void process_data(const nrf_dm_report_t *data)
287294
result.dist_estimates.mcpd.best = data->distance_estimates.mcpd.best;
288295
result.dist_estimates.mcpd.rssi_openspace =
289296
data->distance_estimates.mcpd.rssi_openspace;
297+
#ifdef CONFIG_DM_HIGH_PRECISION_CALC
298+
result.dist_estimates.mcpd.high_precision = high_precision_estimate;
299+
#endif
290300
}
291301
}
292302

@@ -350,11 +360,6 @@ static void dm_start_ranging(void)
350360
timeslot_queue_remove_first();
351361

352362
uint32_t distance = time_distance_get(timeslot_ctx.last_start, req->start_time);
353-
uint32_t distance_now = time_distance_get(timeslot_ctx.last_start, time_now());
354-
355-
if (distance_now > distance) {
356-
goto out;
357-
}
358363

359364
atomic_set(&timeslot_ctx.state, TIMESLOT_STATE_PENDING);
360365
err = timeslot_request(TICKS_TO_US(distance));
@@ -378,7 +383,7 @@ static void dm_reschedule(void)
378383
timeslot_len_us = timeslot_ctx.curr_req.timeslot_length_us;
379384

380385
err = timeslot_queue_append(&timeslot_ctx.curr_req.dm_req,
381-
timeslot_ctx.last_start, window_len_us, timeslot_len_us);
386+
time_now(), window_len_us, timeslot_len_us);
382387
if (err) {
383388
LOG_DBG("Timeslot allocator failed (err %d)", err);
384389
}
@@ -400,11 +405,17 @@ static void calculation(void)
400405
}
401406
} else {
402407
static nrf_dm_report_t report;
408+
float high_precision_estimate = 0;
403409

404410
nrf_dm_populate_report(&report);
405411
nrf_dm_calc(&report);
406-
process_data(&report);
407412

413+
#ifdef CONFIG_DM_HIGH_PRECISION_CALC
414+
if (report.ranging_mode == NRF_DM_RANGING_MODE_MCPD) {
415+
high_precision_estimate = nrf_dm_high_precision_calc(&report);
416+
}
417+
#endif
418+
process_data(&report, high_precision_estimate);
408419
if (dm_context.cb->data_ready != NULL) {
409420
dm_context.cb->data_ready(&result);
410421
}
@@ -506,7 +517,7 @@ int dm_init(struct dm_init_param *init_param)
506517
ppi_ch[i] = (uint8_t)channel;
507518
}
508519

509-
nrf_dm_init(&ppi_conf, &ant_conf, NRF_DM_TIMER);
520+
nrf_dm_init(&ppi_conf, &ant_conf, DM_TIMER);
510521

511522
ver = nrf_dm_version_string_get();
512523
LOG_DBG("Initialized NRF_DM version %s", ver);
@@ -522,7 +533,8 @@ int dm_init(struct dm_init_param *init_param)
522533
return 0;
523534
}
524535

525-
K_THREAD_DEFINE(dm_thread_id, STACKSIZE, dm_thread, NULL, NULL, NULL, DM_THREAD_PRIORITY, 0, 0);
536+
K_THREAD_DEFINE(dm_thread_id, DM_THREAD_STACK_SIZE,
537+
dm_thread, NULL, NULL, NULL, DM_THREAD_PRIORITY, 0, 0);
526538

527-
K_THREAD_DEFINE(mpsl_nonpreemptible_thread_id, STACKSIZE,
539+
K_THREAD_DEFINE(mpsl_nonpreemptible_thread_id, MPSL_THREAD_STACK_SIZE,
528540
mpsl_nonpreemptible_thread, NULL, NULL, NULL, K_PRIO_COOP(MPSL_THREAD_PRIO), 0, 0);

subsys/dm/rpc/client/dm_rpc_client.c

+17-7
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ int dm_init(struct dm_init_param *init_param)
6969
return result;
7070
}
7171

72-
static void process_data(const struct dm_rpc_process_data *data, struct dm_result *result)
72+
static void process_data(const struct dm_rpc_process_data *data, struct dm_result *result,
73+
float high_precision_estimate)
7374
{
7475
if (!data || !result) {
7576
return;
@@ -99,6 +100,9 @@ static void process_data(const struct dm_rpc_process_data *data, struct dm_resul
99100
result->dist_estimates.mcpd.best = data->report.distance_estimates.mcpd.best;
100101
result->dist_estimates.mcpd.rssi_openspace =
101102
data->report.distance_estimates.mcpd.rssi_openspace;
103+
#ifdef CONFIG_DM__HIGH_PRECISION_CALC
104+
result->dist_estimates.mcpd.high_precision = high_precision_estimate;
105+
#endif
102106
}
103107
}
104108

@@ -133,12 +137,18 @@ static void data_handler(struct k_work *work)
133137
{
134138
int ret;
135139
enum dm_rpc_cmd cmd;
136-
struct dm_result result;
140+
struct dm_result result = {0};
141+
float high_precision_estimate = 0;
137142

138143
struct dm_rpc_process_data *dm_data = (struct dm_rpc_process_data *)recv_data;
139144

140145
nrf_dm_calc(&dm_data->report);
141-
process_data(dm_data, &result);
146+
#ifdef CONFIG_DM_HIGH_PRECISION_CALC
147+
if (dm_data->report.ranging_mode == NRF_DM_RANGING_MODE_MCPD) {
148+
high_precision_estimate = nrf_dm_high_precision_calc(&dm_data->report);
149+
}
150+
#endif
151+
process_data(dm_data, &result, high_precision_estimate);
142152
if (init_param_cb->data_ready) {
143153
init_param_cb->data_ready(&result);
144154
}
@@ -159,17 +169,17 @@ static int ipc_init(const struct device *dev)
159169
ARG_UNUSED(dev);
160170

161171
int err;
162-
const struct device *ipc0_instance;
172+
const struct device *ipc_instance;
163173

164-
ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
174+
ipc_instance = DEVICE_DT_GET(DT_NODELABEL(ipc1));
165175

166-
err = ipc_service_open_instance(ipc0_instance);
176+
err = ipc_service_open_instance(ipc_instance);
167177
if ((err < 0) && (err != -EALREADY)) {
168178
LOG_ERR("IPC service instance initialization failed with err: %d", err);
169179
return err;
170180
}
171181

172-
err = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg);
182+
err = ipc_service_register_endpoint(ipc_instance, &ep, &ep_cfg);
173183
if (err < 0) {
174184
LOG_ERR("Registering endpoint failed with err: %d", err);
175185
return err;

subsys/dm/rpc/host/dm_rpc_host.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -128,17 +128,17 @@ static int ipc_init(const struct device *dev)
128128
ARG_UNUSED(dev);
129129

130130
int err;
131-
const struct device *ipc0_instance;
131+
const struct device *ipc_instance;
132132

133-
ipc0_instance = DEVICE_DT_GET(DT_NODELABEL(ipc0));
133+
ipc_instance = DEVICE_DT_GET(DT_NODELABEL(ipc1));
134134

135-
err = ipc_service_open_instance(ipc0_instance);
135+
err = ipc_service_open_instance(ipc_instance);
136136
if ((err < 0) && (err != -EALREADY)) {
137137
LOG_ERR("IPC service instance initialization failed with err: %d", err);
138138
return err;
139139
}
140140

141-
err = ipc_service_register_endpoint(ipc0_instance, &ep, &ep_cfg);
141+
err = ipc_service_register_endpoint(ipc_instance, &ep, &ep_cfg);
142142
if (err < 0) {
143143
LOG_ERR("Registering endpoint failed with err: %d", err);
144144
return err;

0 commit comments

Comments
 (0)