ref_app_breathing_main.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2023-2024
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6 
7 #include <stdint.h>
8 #include <stdio.h>
9 
10 #include "acc_definitions_a121.h"
11 #include "acc_definitions_common.h"
14 #include "acc_integration.h"
15 #include "acc_processing.h"
16 #include "acc_rss_a121.h"
17 #include "acc_sensor.h"
18 #include "acc_version.h"
19 
20 #include "ref_app_breathing.h"
21 
22 typedef enum
23 {
28 
29 #define SENSOR_ID (1U)
30 #define SENSOR_TIMEOUT_MS (1000U)
31 
32 #define DEFAULT_PRESET_CONFIG BREATHING_PRESET_SITTING
33 
35 
37 
39 
40 static bool measure(acc_sensor_t *sensor, void *buffer, uint32_t buffer_size);
41 
42 static bool enter_hibernate(acc_sensor_t *sensor);
43 
44 static bool exit_hibernate(acc_sensor_t *sensor);
45 
47 
49 
54  void *buffer,
55  uint32_t buffer_size,
56  acc_detector_presence_result_t *presence_result);
57 
58 int acconeer_main(int argc, char *argv[]);
59 
60 int acconeer_main(int argc, char *argv[])
61 {
62  (void)argc;
63  (void)argv;
66  acc_sensor_t *sensor = NULL;
68  void *buffer = NULL;
69  uint32_t buffer_size = 0U;
71 
72  printf("Acconeer software version %s\n", acc_version_get());
73 
75 
76  if (!acc_rss_hal_register(hal))
77  {
78  return EXIT_FAILURE;
79  }
80 
82 
83  if (config == NULL)
84  {
85  printf("Failed to create config\n");
87  return EXIT_FAILURE;
88  }
89 
91 
93 
94  if (handle == NULL)
95  {
96  printf("Failed to create handle\n");
98  return EXIT_FAILURE;
99  }
100 
102  {
103  printf("ref_app_breathing_get_buffer_size() failed\n");
105  return EXIT_FAILURE;
106  }
107 
109  if (buffer == NULL)
110  {
111  printf("Failed to allocate buffer\n");
113  return EXIT_FAILURE;
114  }
115 
116  float frame_rate = acc_detector_presence_config_frame_rate_get(config->presence_config);
117  uint32_t sleep_time_ms = (uint32_t)(1000.0f / frame_rate);
119 
122 
124  if (sensor == NULL)
125  {
126  printf("acc_sensor_create() failed\n");
128  return EXIT_FAILURE;
129  }
130 
132  {
133  printf("Sensor calibration failed\n");
135  return EXIT_FAILURE;
136  }
137 
139  {
140  printf("ref_app_breathing_prepare() failed\n");
142  return EXIT_FAILURE;
143  }
144 
146 
147  if (!enter_hibernate(sensor))
148  {
149  printf("enter_hibernate failed\n");
151  return EXIT_FAILURE;
152  }
153 
154  while (true)
155  {
157  {
159  return EXIT_FAILURE;
160  }
161 
163  {
164  printf("ref_app_breathing_process() failed\n");
166  return EXIT_FAILURE;
167  }
168 
170  {
172  return EXIT_FAILURE;
173  }
174 
175  if (!result.presence_result.processing_result.calibration_needed)
176  {
177  print_result(&result, prev_app_state);
178  prev_app_state = result.app_state;
179  }
180 
182  }
183 
185 
186  printf("Application finished OK\n");
187 
188  return EXIT_SUCCESS;
189 }
190 
192 {
195 
196  if (config != NULL)
197  {
199  }
200 
201  if (sensor != NULL)
202  {
204  }
205 
206  if (buffer != NULL)
207  {
209  }
210 
212 }
213 
215 {
216  acc_detector_presence_config_t *presence_config = config->presence_config;
217 
218  switch (preset)
219  {
221  // Add custom configuration of the reference application here
222  break;
224  acc_detector_presence_config_end_set(presence_config, 1.5f);
226  break;
228  acc_detector_presence_config_end_set(presence_config, 1.0f);
230  break;
231  }
232 
234 }
235 
237 {
238  bool status = false;
239  bool cal_complete = false;
240  const uint16_t calibration_retries = 1U;
241 
242  // Random disturbances may cause the calibration to fail. At failure, retry at least once.
243  for (uint16_t i = 0; !status && (i <= calibration_retries); i++)
244  {
245  // Reset sensor before calibration by disabling/enabling it
248 
249  do
250  {
251  status = acc_sensor_calibrate(sensor, &cal_complete, sensor_cal_result, buffer, buffer_size);
252 
253  if (status && !cal_complete)
254  {
256  }
257  } while (status && !cal_complete);
258  }
259 
260  if (status)
261  {
262  /* Reset sensor after calibration by disabling/enabling it */
265  }
266  else
267  {
268  printf("acc_sensor_calibrate() failed\n");
270  }
271 
272  return status;
273 }
274 
275 static bool measure(acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
276 {
277  if (!exit_hibernate(sensor))
278  {
279  printf("exit_hibernate failed\n");
280  return EXIT_FAILURE;
281  }
282 
284  {
285  printf("acc_sensor_measure failed\n");
287  return false;
288  }
289 
291  {
292  printf("Sensor interrupt timeout\n");
294  return false;
295  }
296 
298  {
299  printf("acc_sensor_read() failed\n");
301  return false;
302  }
303 
304  if (!enter_hibernate(sensor))
305  {
306  printf("enter_hibernate failed\n");
307  return EXIT_FAILURE;
308  }
309 
310  return true;
311 }
312 
314 {
315  bool status = true;
316 
318  {
319  printf("acc_sensor_hibernate_on failed\n");
321  status = false;
322  }
323 
325  return status;
326 }
327 
329 {
330  bool status = true;
331 
334  {
335  printf("acc_sensor_hibernate_off failed\n");
337  status = false;
338  }
339 
340  return status;
341 }
342 
344 {
345  switch (result->app_state)
346  {
348  break;
350  printf("NO_PRESENCE_DETECTED\n");
351  break;
353  printf("INTRA_PRESENCE_DETECTED\n");
354  break;
356  printf("DETERMINE_DISTANCE_ESTIMATE\n");
357  break;
359  printf("ESTIMATE_BREATHING_RATE\n");
360  break;
361  default:
362  break;
363  }
364 }
365 
367 {
368  if (prev_app_state != result->app_state)
369  {
371  }
372 
373  if (result->result_ready)
374  {
375  printf("Breaths: %" PRIu16 " bpm\n", (uint16_t)result->breathing_rate);
376  }
377 }
378 
383  void *buffer,
384  uint32_t buffer_size,
385  acc_detector_presence_result_t *presence_result)
386 {
387  if (presence_result->processing_result.data_saturated)
388  {
389  printf("Data saturated. The detector result is not reliable.\n");
390  }
391 
392  if (presence_result->processing_result.frame_delayed)
393  {
394  printf("Frame delayed. Could not read data fast enough.\n");
395  printf("Try lowering the frame rate or call 'acc_sensor_read' more frequently.\n");
396  }
397 
398  if (presence_result->processing_result.calibration_needed)
399  {
400  printf("Sensor recalibration needed ... \n");
401 
402  if (!exit_hibernate(sensor))
403  {
404  printf("exit_hibernate failed\n");
405  return EXIT_FAILURE;
406  }
407 
409  {
410  printf("Sensor calibration failed\n");
411  return false;
412  }
413 
414  printf("Sensor recalibration done!\n");
415 
416  // Before measuring again, the sensor needs to be prepared through the detector
418  {
419  printf("acc_detector_presence_prepare() failed\n");
420  return false;
421  }
422 
423  if (!enter_hibernate(sensor))
424  {
425  printf("enter_hibernate failed\n");
426  return EXIT_FAILURE;
427  }
428  }
429 
430  return true;
431 }
REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
@ REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
Definition: ref_app_breathing.h:66
enter_hibernate
static bool enter_hibernate(acc_sensor_t *sensor)
Definition: ref_app_breathing_main.c:313
acc_hal_integration_sensor_supply_off
void acc_hal_integration_sensor_supply_off(acc_sensor_id_t sensor_id)
Power off sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:104
ref_app_breathing_prepare
bool ref_app_breathing_prepare(ref_app_breathing_handle_t *handle, ref_app_breathing_config_t *config, acc_sensor_t *sensor, const acc_cal_result_t *sensor_cal_result, void *buffer, uint32_t buffer_size)
Prepare the application to do a measurement.
Definition: ref_app_breathing.c:358
acc_rss_a121.h
cargo_result_t::calibration_needed
bool calibration_needed
Definition: example_cargo.h:112
acc_hal_integration_sensor_supply_on
void acc_hal_integration_sensor_supply_on(acc_sensor_id_t sensor_id)
Power on sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:99
REF_APP_BREATHING_APP_STATE_INIT
@ REF_APP_BREATHING_APP_STATE_INIT
Definition: ref_app_breathing.h:62
sensor_calibration
static bool sensor_calibration(acc_sensor_t *sensor, acc_cal_result_t *sensor_cal_result, void *buffer, uint32_t buffer_size)
Definition: ref_app_breathing_main.c:236
acc_sensor_read
bool acc_sensor_read(const acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
Read out radar data.
buffer
void * buffer
Definition: i2c_example_cargo.c:40
acc_version.h
cleanup
static void cleanup(ref_app_breathing_handle_t *handle, ref_app_breathing_config_t *config, acc_sensor_t *sensor, void *buffer)
Definition: ref_app_breathing_main.c:191
sensor_cal_result
acc_cal_result_t sensor_cal_result
Definition: i2c_example_cargo.c:36
SENSOR_TIMEOUT_MS
#define SENSOR_TIMEOUT_MS
Definition: ref_app_breathing_main.c:30
exit_hibernate
static bool exit_hibernate(acc_sensor_t *sensor)
Definition: ref_app_breathing_main.c:328
SENSOR_ID
#define SENSOR_ID
Definition: ref_app_breathing_main.c:29
ref_app_breathing_get_buffer_size
bool ref_app_breathing_get_buffer_size(ref_app_breathing_handle_t *handle, uint32_t *buffer_size)
Get the buffer size needed for the provided ref app breathing handle.
Definition: ref_app_breathing.c:353
acc_detector_presence_result_t::processing_result
acc_processing_result_t processing_result
Definition: acc_detector_presence.h:82
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
ref_app_breathing_create
ref_app_breathing_handle_t * ref_app_breathing_create(ref_app_breathing_config_t *config)
Create a handle for the ref app breathing.
Definition: ref_app_breathing.c:156
handle_indications
static bool handle_indications(ref_app_breathing_handle_t *handle, ref_app_breathing_config_t *config, acc_sensor_t *sensor, acc_cal_result_t *sensor_cal_result, void *buffer, uint32_t buffer_size, acc_detector_presence_result_t *presence_result)
Definition: ref_app_breathing_main.c:379
ref_app_breathing.h
ref_app_breathing_result_t
Breathing application results container.
Definition: ref_app_breathing.h:72
ref_app_breathing_destroy
void ref_app_breathing_destroy(ref_app_breathing_handle_t *handle)
Destroy a handle for the ref app breathing.
Definition: ref_app_breathing.c:265
acc_integration.h
print_result
static void print_result(ref_app_breathing_result_t *result, ref_app_breathing_app_state_t prev_app_state)
Definition: ref_app_breathing_main.c:366
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
acc_hal_rss_integration_get_implementation
const acc_hal_a121_t * acc_hal_rss_integration_get_implementation(void)
Get hal implementation reference.
Definition: acc_hal_integration_stm32cube_xm.c:152
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: ref_app_breathing_main.c:60
REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
@ REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
Definition: ref_app_breathing.h:64
acc_detector_presence_config_intra_detection_threshold_set
void acc_detector_presence_config_intra_detection_threshold_set(acc_detector_presence_config_t *presence_config, float intra_detection_threshold)
Set the detection threshold for the intra-frame presence detection.
acc_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:592
ref_app_breathing_config_create
ref_app_breathing_config_t * ref_app_breathing_config_create(void)
Create a configuration for the ref app breathing.
Definition: ref_app_breathing.c:100
acc_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_rss_hal_register
bool acc_rss_hal_register(const acc_hal_a121_t *hal)
Register an integration.
acc_integration_set_periodic_wakeup
void acc_integration_set_periodic_wakeup(uint32_t time_msec)
Set up a periodic timer used to wake up the system from sleep.
Definition: acc_integration_stm32.c:496
acc_sensor.h
acc_detector_presence_result_t
Presence detector results container.
Definition: acc_detector_presence.h:46
buffer_size
uint32_t buffer_size
Definition: i2c_example_cargo.c:41
sensor
acc_sensor_t * sensor
Definition: i2c_example_cargo.c:33
measure
static bool measure(acc_sensor_t *sensor, void *buffer, uint32_t buffer_size)
Definition: ref_app_breathing_main.c:275
ref_app_breathing_process
bool ref_app_breathing_process(ref_app_breathing_handle_t *handle, void *buffer, ref_app_breathing_result_t *result)
Process the data.
Definition: ref_app_breathing.c:368
acc_hal_integration_wait_for_sensor_interrupt
bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms)
Wait for a sensor interrupt.
Definition: acc_hal_integration_stm32cube_xm.c:130
acc_hal_integration_a121.h
acc_detector_presence_config_end_set
void acc_detector_presence_config_end_set(acc_detector_presence_config_t *presence_config, float end)
Set the end point of measurement interval in meters.
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
acc_sensor_hibernate_off
bool acc_sensor_hibernate_off(const acc_sensor_t *sensor)
Restore sensor after exiting hibernation.
result
cargo_result_t result
Definition: i2c_example_cargo.c:43
acc_version_get
const char * acc_version_get(void)
Get the version of the Acconeer software.
printf
#define printf
Definition: printf.h:60
REF_APP_BREATHING_APP_STATE_NO_PRESENCE
@ REF_APP_BREATHING_APP_STATE_NO_PRESENCE
Definition: ref_app_breathing.h:63
acc_hal_integration_sensor_enable
void acc_hal_integration_sensor_enable(acc_sensor_id_t sensor_id)
Enable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:109
ref_app_breathing_config_destroy
void ref_app_breathing_config_destroy(ref_app_breathing_config_t *config)
Destory a configuration for the ref app breathing.
Definition: ref_app_breathing.c:143
acc_hal_definitions_a121.h
print_app_state
static void print_app_state(ref_app_breathing_result_t *result)
Definition: ref_app_breathing_main.c:343
breathing_preset_t
breathing_preset_t
Definition: ref_app_breathing_main.c:22
acc_processing_result_t::frame_delayed
bool frame_delayed
Definition: acc_processing.h:80
acc_hal_integration_sensor_disable
void acc_hal_integration_sensor_disable(acc_sensor_id_t sensor_id)
Disable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:119
acc_detector_presence_config_t
struct acc_detector_presence_config acc_detector_presence_config_t
Definition: acc_detector_presence.h:41
acc_sensor_hibernate_on
bool acc_sensor_hibernate_on(acc_sensor_t *sensor)
Prepare sensor for entering hibernation.
acc_sensor_status
void acc_sensor_status(const acc_sensor_t *sensor)
Check the status of the sensor.
REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
@ REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
Definition: ref_app_breathing.h:65
set_config
static void set_config(ref_app_breathing_config_t *config, breathing_preset_t preset)
Definition: ref_app_breathing_main.c:214
acc_detector_presence_config_frame_rate_get
float acc_detector_presence_config_frame_rate_get(const acc_detector_presence_config_t *presence_config)
Get the frame rate.
DEFAULT_PRESET_CONFIG
#define DEFAULT_PRESET_CONFIG
Definition: ref_app_breathing_main.c:32
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
acc_integration_sleep_until_periodic_wakeup
void acc_integration_sleep_until_periodic_wakeup(void)
Put the system in sleep until the periodic timer triggers.
Definition: acc_integration_stm32.c:552
acc_definitions_common.h
BREATHING_PRESET_SITTING
@ BREATHING_PRESET_SITTING
Definition: ref_app_breathing_main.c:25
ref_app_breathing_handle
Definition: ref_app_breathing.c:23
acc_processing_result_t::data_saturated
bool data_saturated
Definition: acc_processing.h:76
acc_sensor_calibrate
bool acc_sensor_calibrate(acc_sensor_t *sensor, bool *cal_complete, acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Calibrate a sensor.
ref_app_breathing_config_t
Breathing application config container.
Definition: ref_app_breathing.h:25
acc_processing_result_t::calibration_needed
bool calibration_needed
Definition: acc_processing.h:84
BREATHING_PRESET_INFANT
@ BREATHING_PRESET_INFANT
Definition: ref_app_breathing_main.c:26
acc_sensor_measure
bool acc_sensor_measure(acc_sensor_t *sensor)
Start a radar measurement with previously prepared configuration.
acc_processing.h
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
ref_app_breathing_app_state_t
ref_app_breathing_app_state_t
State of the application.
Definition: ref_app_breathing.h:60
acc_sensor_destroy
void acc_sensor_destroy(acc_sensor_t *sensor)
Destroy a sensor instance freeing any resources allocated.
acc_definitions_a121.h
BREATHING_PRESET_NONE
@ BREATHING_PRESET_NONE
Definition: ref_app_breathing_main.c:24
acc_detector_presence_config_frame_rate_app_driven_set
void acc_detector_presence_config_frame_rate_app_driven_set(acc_detector_presence_config_t *presence_config, bool enable)
Set if the application should maintain the requested frame rate.
acc_sensor_create
acc_sensor_t * acc_sensor_create(acc_sensor_id_t sensor_id)
Create a sensor instance.