29 #define RETURN_ON_ERROR(status) if(status) \
31 RD_ERROR_CHECK(RD_ERROR_SELFTEST, ~RD_ERROR_FATAL); \
34 #define BITFIELD_MASK (1U)
35 #define MAX_LOG_BUFFER_SIZE (128U)
36 #define MAX_SENSOR_NAME_LEN (20U)
37 #define MAX_BITS_PER_BYTE (8U)
38 #define MAX_SENSORS (sizeof(rd_sensor_data_fields_t)* MAX_BITS_PER_BYTE)
39 #define MAX_RETRIES (50U)
40 #define MAX_FIFO_DEPTH (32U)
41 #define MAX_SENSOR_PROVIDED_FIELDS (4U)
43 #define LOG_PRINT_DELAY_MS (10U)
46 static inline void LOG (
const char *
const msg)
52 static volatile bool fifo_int =
false;
53 static volatile bool level_int =
false;
55 static bool initialize_sensor_once (
rd_sensor_t * DUT,
57 const rd_bus_t bus,
const uint8_t handle)
60 err_code = init (DUT, bus, handle);
72 const rd_bus_t bus,
const uint8_t handle)
75 err_code = DUT->
uninit (DUT, bus, handle);
85 static bool initialize_sensor_twice (
rd_sensor_t * DUT,
87 const rd_bus_t bus,
const uint8_t handle)
90 err_code = init (DUT, bus, handle);
91 err_code = init (DUT, bus, handle);
102 static bool validate_sensor_setup (
rd_sensor_t * DUT)
105 if (DUT->
init == NULL ||
133 static bool validate_sensor_teardown (
rd_sensor_t * DUT)
139 NULL)) ?
true :
false;
141 NULL)) ?
true :
false;
147 false)) ?
true :
false;
149 NULL)) ?
true :
false;
151 NULL)) ?
true :
false;
164 static bool validate_sensor_mode_after_init (
rd_sensor_t * DUT)
178 static bool test_sensor_init_on_null (
rd_sensor_t * DUT,
180 const rd_bus_t bus,
const uint8_t handle)
218 const rd_bus_t bus,
const uint8_t handle)
223 failed |= initialize_sensor_once (&DUT, init, bus, handle);
224 RETURN_ON_ERROR (failed);
226 failed |= validate_sensor_setup (&DUT);
228 failed |= uninitialize_sensor (&DUT, init, bus, handle);
230 failed |= validate_sensor_teardown (&DUT);
232 failed |= initialize_sensor_twice (&DUT, init, bus, handle);
234 failed |= uninitialize_sensor (&DUT, init, bus, handle);
236 failed |= initialize_sensor_once (&DUT, init, bus, handle);
238 failed |= validate_sensor_mode_after_init (&DUT);
240 failed |= test_sensor_init_on_null (&DUT, init, bus, handle);
242 DUT.
uninit (&DUT, bus, handle);
246 static bool test_sensor_setup_set_get (
const rd_sensor_t * DUT,
252 uint8_t original = 0;
256 for (
size_t ii = 0; ii <
sizeof (cfg_constants); ii++)
258 config = cfg_constants[ii];
259 err_code = set (&config);
261 err_code |= get (&config);
263 if (config != original ||
279 err_code |= set (&config);
290 for (uint8_t ii = 1; ii < 200; ii++)
294 err_code = set (&config);
305 err_code |= get (&config);
307 if (config != original &&
328 err_code = set (NULL);
335 err_code = get (NULL);
362 const rd_bus_t bus,
const uint8_t handle)
366 memset (&DUT, 0,
sizeof (DUT));
368 failed |= init (&DUT, bus, handle);
383 DUT.
uninit (&DUT, bus, handle);
395 if (old->
data[ii] != new_d->
data[ii]) { change =
true; }
403 static bool sensor_sleeps_after_init (
const rd_sensor_t *
const DUT)
417 static bool sensor_returns_invalid_before_sampling (
const rd_sensor_t *
const DUT)
420 float values_new[MAX_SENSOR_PROVIDED_FIELDS];
426 err_code = DUT->
data_get (&new_data);
437 static bool sensor_returns_to_sleep (
const rd_sensor_t *
const DUT)
453 static bool sensor_returns_valid_data (
const rd_sensor_t *
const DUT)
458 float values [MAX_SENSOR_PROVIDED_FIELDS];
476 static bool single_sample_stays_valid (
const rd_sensor_t *
const DUT)
480 float old_values[MAX_SENSOR_PROVIDED_FIELDS] = {0};
481 float new_values[MAX_SENSOR_PROVIDED_FIELDS] = {0};
489 err_code |= DUT->
data_get (&old_data);
491 err_code |= DUT->
data_get (&new_data);
495 0 != memcmp (old_values, new_values,
sizeof (old_values)))
504 static bool sensor_remains_continuous (
const rd_sensor_t *
const DUT)
521 static bool sensor_rejects_single_on_continuous (
const rd_sensor_t *
const DUT)
536 static bool sensor_mode_cannot_be_null (
const rd_sensor_t *
const DUT)
556 static bool sensor_returns_continuous_data (
const rd_sensor_t *
const DUT)
560 float old_values[MAX_SENSOR_PROVIDED_FIELDS];
561 float new_values[MAX_SENSOR_PROVIDED_FIELDS];
569 err_code |= DUT->
data_get (&old_data);
571 err_code |= DUT->
data_get (&new_data);
577 uint32_t interval = (1000 / (samplerate + 1));
579 err_code |= DUT->
data_get (&old_data);
582 for (; retries < MAX_RETRIES; retries++)
587 err_code |= DUT->
data_get (&new_data);
595 err_code |= DUT->
data_get (&new_data);
606 if (value_has_changed (&old_data, &new_data)) {
break; }
609 if (MAX_RETRIES == retries)
639 const rd_bus_t bus,
const uint8_t handle)
643 memset (&DUT, 0,
sizeof (DUT));
644 initialize_sensor_once (&DUT, init, bus, handle);
646 failed |= sensor_sleeps_after_init (&DUT);
648 failed |= sensor_returns_invalid_before_sampling (&DUT);
650 failed |= sensor_returns_to_sleep (&DUT);
652 failed |= sensor_returns_valid_data (&DUT);
654 failed |= single_sample_stays_valid (&DUT);
656 failed |= sensor_remains_continuous (&DUT);
658 failed |= sensor_rejects_single_on_continuous (&DUT);
660 failed |= sensor_mode_cannot_be_null (&DUT);
662 failed |= sensor_returns_continuous_data (&DUT);
664 failed |= DUT.
uninit (&DUT, bus, handle);
689 static bool test_sensor_interrupts_setup (
rd_sensor_t * DUT,
691 const rd_bus_t bus,
const uint8_t handle,
711 err_code |= init (DUT, bus, handle);
719 static void test_sensor_interrupts_teardown (
rd_sensor_t *
const DUT,
721 const rd_bus_t bus,
const uint8_t handle,
728 DUT->
uninit (DUT, bus, handle);
735 float threshold_g = APP_MOTION_THRESHOLD;
743 uint32_t timeout = 0;
744 uint32_t max_time = 5U * 1000U * 1000U;
746 while ( (!level_int) && (timeout < max_time))
752 if (timeout >= max_time)
757 return (level_int) ? false :
true;
771 float old_values[MAX_SENSOR_PROVIDED_FIELDS];
772 old.
data = old_values;
774 size_t num_samples = MAX_FIFO_DEPTH;
776 float values[num_samples][MAX_SENSOR_PROVIDED_FIELDS];
777 uint32_t max_time = 4U * 1000U * 1000U;
779 for (
size_t ii = 0; ii < num_samples; ii++)
781 data[ii].
data = values[ii];
785 bool valid_data =
false;
787 uint32_t timeout = 0;
789 while ( (!fifo_int) && (timeout < max_time))
795 if (timeout >= max_time)
802 if (10U > num_samples)
808 value_has_changed (&old, & (data[0]));
810 for (
size_t iii = 1; iii < num_samples; iii++)
812 if (value_has_changed (&old, & (data[iii])))
819 return (valid_data) ? false :
true;
844 const rd_bus_t bus,
const uint8_t handle,
845 const bool interactive,
854 status = test_sensor_interrupts_setup (&DUT, init, bus, handle, interrupt_table, fifo_pin,
859 printfp (
"{\r\n\"level\":");
860 status |= test_sensor_level_enable (&DUT);
864 printfp (
"\"fail\",\r\n");
868 printfp (
"\"pass\",\r\n");
871 test_sensor_interrupts_teardown (&DUT, init, bus, handle, fifo_pin,
873 status = test_sensor_interrupts_setup (&DUT, init, bus, handle, interrupt_table, fifo_pin,
875 printfp (
"\"fifo\":");
876 status |= test_sensor_fifo_enable (&DUT);
880 printfp (
"\"fail\"\r\n");
884 printfp (
"\"pass\"\r\n");
890 test_sensor_interrupts_teardown (&DUT, init, bus, handle, fifo_pin,
895 static bool sensor_returns_valid_data_print (
const rd_sensor_t *
const DUT,
901 float values [MAX_SENSOR_PROVIDED_FIELDS];
919 const rd_bus_t bus,
const uint8_t handle,
924 memset (&DUT, 0,
sizeof (DUT));
926 failed |= init (&DUT, bus, handle);
931 printfp (
"\"data\":\"fail\",\r\n");
935 failed |= sensor_returns_valid_data_print (&DUT, printfp);
936 DUT.
uninit (&DUT, bus, handle);
947 printfp (
"\": {\r\n");
948 printfp (
"\"init\":");
956 err_code |= p_sensor_ctx->
init (&p_sensor_ctx->
sensor,
963 printfp (
"\"skip\"\r\n");
971 status = test_sensor_init (p_sensor_ctx->
init, p_sensor_ctx->
bus, p_sensor_ctx->
handle);
975 printfp (
"\"fail\",\r\n");
979 printfp (
"\"pass\",\r\n");
982 printfp (
"\"modes\":");
986 status = test_sensor_modes (p_sensor_ctx->
init, p_sensor_ctx->
bus, p_sensor_ctx->
handle);
991 printfp (
"\"fail\",\r\n");
995 printfp (
"\"pass\",\r\n");
998 printfp (
"\"configuration\":");
1002 status = test_sensor_setup (p_sensor_ctx->
init, p_sensor_ctx->
bus, p_sensor_ctx->
handle);
1007 printfp (
"\"fail\",\r\n");
1011 printfp (
"\"pass\",\r\n");
1014 printfp (
"\"interrupts\":");
1020 status = test_sensor_interrupts (p_sensor_ctx->
init, p_sensor_ctx->
bus,
1021 p_sensor_ctx->
handle,
false,
1028 printfp (
"\"skipped\",\r\n");
1031 status = test_sensor_data_print (p_sensor_ctx->
init, p_sensor_ctx->
bus,
1032 p_sensor_ctx->
handle, printfp);
1042 uint8_t data_counter = 0;
1043 uint8_t data_available = 0;
1045 char sensors_name[MAX_SENSORS][MAX_SENSOR_NAME_LEN] =
1072 for (
int i = 0; i < MAX_SENSORS; i++)
1074 if (data_check & BITFIELD_MASK)
1075 { data_available++; }
1077 data_check = data_check >> 1;
1082 printfp (
"\"data\":{\r\n");
1083 char msg[MAX_LOG_BUFFER_SIZE];
1087 snprintf (msg,
sizeof (msg),
"\"timestamp_ms\": \"RD_UINT64_INVALID\",\n");
1092 snprintf (msg,
sizeof (msg),
"\"timestamp_ms\": \"%ld\",\n",
1098 for (uint8_t i = 0; i < MAX_SENSORS; i++)
1103 char msg[MAX_LOG_BUFFER_SIZE];
1108 if (0 == isnan (* ( (
float *) (&p_data->
data[data_counter]))))
1110 snprintf (msg,
sizeof (msg),
1112 (
char *) &sensors_name[i][0],
1113 * ( (
float *) (&p_data->
data[data_counter])));
1117 snprintf (msg,
sizeof (msg),
1119 (
char *) &sensors_name[i][0]);
1126 snprintf (msg,
sizeof (msg),
1128 (
char *) &sensors_name[i][0]);
1131 if (data_counter == data_available)
1133 char * str =
"\r\n";
1134 strncat (msg, str,
sizeof (str));
1138 char * str =
",\r\n";
1139 strncat (msg, str,
sizeof (str));
#define RD_ERROR_NULL
Null Pointer.
#define RD_ERROR_NOT_INITIALIZED
Driver is not initialized.
#define RD_ERROR_FATAL
Program should always reset after this.
uint32_t rd_status_t
bitfield for representing errors
#define RD_STATUS_MORE_AVAILABLE
Driver has more data queued.
#define RD_ERROR_CHECK(error, mask)
Shorthand macro for calling the rd_error_check with current file & line.
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_TIMEOUT
Operation timed out.
#define RD_ERROR_SELFTEST
Self-test fail.
#define RD_ERROR_NOT_FOUND
Not found.
#define RD_UINT64_INVALID
Signal that value should not be used.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_ERROR_INTERNAL
Internal Error.
rd_status_t ri_gpio_interrupt_enable(const ri_gpio_id_t pin, const ri_gpio_slope_t slope, const ri_gpio_mode_t mode, const ri_gpio_interrupt_fp_t handler)
Enable interrupt on a pin.
#define RI_GPIO_INTERRUPT_TEST_TABLE_SIZE
Fixed 64 interrupt table size, adjust this if some device has more than 2 ports with 32 gpios each.
rd_status_t ri_gpio_interrupt_init(ri_gpio_interrupt_fp_t *const interrupt_table, const uint16_t max_interrupts)
Initialize interrupt functionality to GPIO. Takes address of interrupt table as a pointer to avoid ty...
void(* ri_gpio_interrupt_fp_t)(const ri_gpio_evt_t)
rd_status_t ri_gpio_interrupt_uninit(void)
Uninitialize interrupt functionality of GPIO.
rd_status_t ri_gpio_interrupt_disable(const ri_gpio_id_t pin)
Disable interrupt on a pin.
bool ri_gpio_interrupt_is_init(void)
Check if interrupt module is initialized.
void ri_log(const ri_log_severity_t severity, const char *const message)
Queues messages into log.
rd_status_t(* rd_sensor_init_fp)(rd_sensor_t *const p_sensor, const rd_bus_t bus, const uint8_t handle)
Initialize and uninitialize sensor. Init and uninit will setup sensor with function pointers....
#define RD_SENSOR_CFG_SLEEP
Sensor should go to sleep immediately.
#define RD_SENSOR_CFG_MAX
Configure largest supported and implemented value.
#define RD_SENSOR_CFG_DEFAULT
Default value, always valid for the sensor.
uint8_t rd_sensor_data_fieldcount(const rd_sensor_data_t *const target)
Count number of floats required for this data structure.
#define RD_SENSOR_INVALID_TIMSTAMP
Signal this timestamp value is erroneous.
rd_status_t(* rd_sensor_setup_fp)(uint8_t *parameter)
Setup a parameter of a sensor. The function will modify the pointed data to the actual value which wa...
#define RD_SENSOR_CFG_MIN
Configure smallest supported and implemented value.
#define RD_SENSOR_CFG_CONTINUOUS
Sensor will keep sampling at defined sample rate.
#define RD_SENSOR_CFG_NO_CHANGE
Do not change configured value.
rd_bus_t
Type of bus sensor uses.
#define RD_SENSOR_CFG_SINGLE
Sensor should go to sleep after single measurement.
#define RD_HANDLE_UNUSED
Mark sensor as unused with this handle.
void rd_sensor_data_print(const rd_sensor_data_t *const p_data, const rd_test_print_fp printfp)
Print Ruuvi Sensor data in human readable JSON.
bool rd_sensor_run_integration_test(const rd_test_print_fp printfp, rt_sensor_ctx_t *p_sensor_ctx)
void(* rd_test_print_fp)(const char *const msg)
function pointer to print test information
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
rd_status_t test_sensor_status(size_t *total, size_t *passed)
void test_sensor_run(void)
Run sensor integration tests.
uint16_t ri_gpio_id_t
port<<8 + pin
#define RI_GPIO_ID_UNUSED
Enable implementation selected by application.
@ RI_GPIO_MODE_INPUT_PULLUP
Input, can be read. Pulled up by internal resistor, value depends on IC.
rd_status_t ri_delay_us(uint32_t time)
Delay a given number of microseconds.
rd_status_t ri_delay_ms(uint32_t time)
Delay a given number of milliseconds.
All sensors must implement configuration functions which accept this struct.
uint8_t mode
Mode, RD_SENSOR_SLEEP, _SINGLE, _CONTINOUS.
uint8_t samplerate
Samplerate, in Hz.
Generic sensor data struct.
float * data
Data of sensor. Must contain as many elements as fields has bits set.
uint64_t timestamp_ms
Timestamp of the event, rd_sensor_timestamp_get.
rd_sensor_data_fields_t valid
Listing of valid data in this sample.
rd_sensor_data_fields_t fields
Description of datafields which may be contained in this sample.
Interface to sensor. Some sensors can implement additional functions. The additional functions are de...
rd_sensor_data_fp data_get
rd_sensor_data_fp
rd_configuration_fp configuration_set
rd_configuration_fp
rd_sensor_setup_fp samplerate_get
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_get
rd_sensor_setup_fp
rd_sensor_init_fp uninit
rd_sensor_init_fp
rd_configuration_fp configuration_get
rd_configuration_fp
rd_sensor_dsp_fp dsp_get
rd_sensor_dsp_fp
rd_sensor_data_fields_t provides
Description of data fields the sensor is able to provide.
rd_sensor_dsp_fp dsp_set
rd_sensor_dsp_fp
rd_sensor_setup_fp mode_set
rd_sensor_setup_fp
const char * name
Sensor human-readable name. Should be at most 8 bytes long.
rd_sensor_fifo_read_fp fifo_read
rd_sensor_level_interrupt_use_fp
rd_sensor_fifo_enable_fp fifo_interrupt_enable
rd_sensor_level_interrupt_use_fp
rd_sensor_level_interrupt_use_fp level_interrupt_set
rd_sensor_level_interrupt_use_fp
rd_sensor_setup_fp mode_get
rd_sensor_setup_fp
rd_sensor_setup_fp samplerate_set
rd_sensor_setup_fp
rd_sensor_fifo_enable_fp fifo_enable
rd_sensor_fifo_enable_fp
rd_sensor_init_fp init
rd_sensor_init_fp
rd_sensor_setup_fp scale_set
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_set
rd_sensor_setup_fp
rd_sensor_setup_fp scale_get
rd_sensor_setup_fp
rd_sensor_t sensor
Control structure for sensor.
uint8_t handle
Handle of sensor.
ri_gpio_id_t level_pin
Level interrupt.
ri_gpio_id_t fifo_pin
FIFO full interrupt.
rd_sensor_init_fp init
Initialization function.
rd_bus_t bus
Bus of sensor.
uint32_t bitfield
Bitfield used to access sensor data.