ISSDK  1.8
IoT Sensing Software Development Kit
pedometer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 /**
10  * @file pedometer.c
11 * @brief The pedometer.c file contains the interface definitions for
12 * pedometer application.
13 */
14 
15 /*******************************************************************************
16  * Includes
17  ******************************************************************************/
18 #include "pedometer.h"
19 
20 /*******************************************************************************
21  * Macros, globals
22  ******************************************************************************/
23 #define PEDOMETER_STATUS_ACTIVITY_BITNUM 0
24 #define PEDOMETER_STATUS_SUSPEND_BITNUM 3
25 #define PEDOMETER_STATUS_ACTCHG_BITNUM 4
26 #define PEDOMETER_STATUS_STEPCHG_BITNUM 5
27 #define PEDOMETER_STATUS_SUSPCHG_BITNUM 6
28 #define PEDOMETER_STATUS_MRGFLG_BITNUM 7
29 
30 #define PEDOMETER_STATUS_ACTIVITY_MASK (7 << PEDOMETER_STATUS_ACTIVITY_BITNUM)
31 #define PEDOMETER_STATUS_SUSPEND_MASK (1 << PEDOMETER_STATUS_SUSPEND_BITNUM)
32 #define PEDOMETER_STATUS_ACTCHG_MASK (1 << PEDOMETER_STATUS_ACTCHG_BITNUM)
33 #define PEDOMETER_STATUS_STEPCHG_MASK (1 << PEDOMETER_STATUS_STEPCHG_BITNUM)
34 #define PEDOMETER_STATUS_SUSPCHG_MASK (1 << PEDOMETER_STATUS_SUSPCHG_BITNUM)
35 #define PEDOMETER_STATUS_MRGFLG_MASK (1 << PEDOMETER_STATUS_MRGFLG_BITNUM)
36 
37 #define PEDOMETER_STATUS_CHG_MASK \
38  (PEDOMETER_STATUS_ACTCHG_MASK | PEDOMETER_STATUS_STEPCHG_MASK | PEDOMETER_STATUS_SUSPCHG_MASK)
39 #define SQUARED(x) ((x) * (x))
40 /* below values are the best set of value for the algorthm and computed during the algorithm definition.*/
41 /******************************************************************************
42  * Private Function Declarations
43  *****************************************************************************/
44 
45 /* Update status variables */
46 static void status_update(pedometer_t *pedometer, uint32_t events, bool suspend);
47 
48 /* Determine autonomous suspend state */
49 static bool suspend_compute(pedometer_t *pPedometer, ped_accel_t *pData);
50 
51 /* compute the debounce. */
52 static bool debounce_count(bool dbcntm, bool condition, debounce_count_t *count, debounce_count_t threshold);
53 
54 /* Cast uint32_t to uint16_t with saturate */
55 static uint16_t uint32_to_uint16(uint32_t val);
56 
57 /******************************************************************************
58  * Private Variable Definitions
59  ******************************************************************************/
60 
61 static const pedometer_t pedometer_default = {.status =
62  {
63  .version = 2,
64  },
65  .config = {
66  .sleepcount_threshold = 1,
67  .bits = {.config = 1},
68  .keynetik =
69  {
70  .height = 175,
71  .weight = 80,
72  .filtersteps = PEDO_FILTER_STEPS_DEFAULT,
73  .bits =
74  {
75  .filtertime = PEDO_FILTER_TIME_DEFAULT,
76  },
77  .speedperiod = PEDO_SPEED_PERIOD_DEFAULT,
78  .stepthreshold = PEDO_STEP_THRESHOLD_DEFAULT,
79  },
80  .stepcoalesce = 1,
81  .oneG = PEDO_ONEG_8G,
82  .frequency = PEDO_FREQHZ_DEFAULT,
83  }};
84 
85 /*******************************************************************************
86  * Code
87  ******************************************************************************/
88 
89 /*
90 ** ===================================================================
91 ** Method : pedometer_init
92 ** brief : The interface function initialize the pedometer.
93 ** params[in] : pedometer_t *pPedometer, handle to the pedometer.
94 **
95 ** ===================================================================
96 */
97 void pedometer_init(pedometer_t *pPedometer)
98 {
99  *pPedometer = pedometer_default;
100  KeynetikInitialize(pPedometer->config.oneG, pPedometer->config.frequency, &pPedometer->config.keynetik);
101  pPedometer->private.stepchg_stepcount = 0;
102 }
103 
104 /*** ===================================================================
105 ** Method : pedometer_configure
106 ** brief : The interface function to configure the pedometer
107 ** params[in] : pedometer_t *pPedometer, handle to the pedometer.
108 ** params[in] : pedometer_config_t configuration parameter.
109 ** ===================================================================
110 */
111 void pedometer_configure(pedometer_t *pPedometer, const pedometer_config_t *pConfig)
112 {
113  pPedometer->config = *pConfig;
114  KeynetikInitialize(pPedometer->config.oneG, pPedometer->config.frequency, &pPedometer->config.keynetik);
115  pPedometer->private.stepchg_stepcount = 0;
116 }
117 /*
118 ** ===================================================================
119 ** Method : pedometer_run
120 ** brief : The interface function excutes the pedometer algorithm.
121 ** params[in] : pedometer_t *pPedometer, handle to the pedometer.
122 ** params[in] : ped_accel_t data acceleration data.
123 ** ===================================================================
124 */
126 {
127  uint32_t events = 0;
128  /* if suspend, don't execute the alogrithm and save the power.*/
129  bool suspend = suspend_compute(pPedometer, pData);
130  if (!suspend)
131  {
132  events = KeynetikHandleIncomingEvent(pData->accel[0], pData->accel[1], pData->accel[2]);
133  }
134  status_update(pPedometer, events, suspend);
135  return events;
136 }
137 /*
138 ** ===================================================================
139 ** Method : status_update
140 ** brief : update the status of the pedometer output
141 ** params[in] : pedometer_t *pPedometer, handle to the pedometer.
142 ** params[in] : uint32_t events kynetic event
143 ** params[in] : bool suspend suspend flag
144 ** ===================================================================
145 */
146 static void status_update(pedometer_t *pPedometer, uint32_t events, bool suspend)
147 {
148  bool activity_stable =
149  debounce_count(pPedometer->config.bits.activity_dbcntm, !(events & KEYNETIK_ACTIVITYCHANGED),
150  &pPedometer->private.activitycount, pPedometer->config.activitycount_threshold);
151 
152  activitylevel_t activity = activity_stable ? keynetikActivityLevel : pPedometer->status.status.bits.activity;
153  uint16_t stepcount = uint32_to_uint16(keynetikStepCount);
154  uint8_t newstatus = (activity << PEDOMETER_STATUS_ACTIVITY_BITNUM) & PEDOMETER_STATUS_ACTIVITY_MASK;
155 
156  if ((newstatus ^ pPedometer->status.status.byte) & PEDOMETER_STATUS_ACTIVITY_MASK)
157  newstatus |= PEDOMETER_STATUS_ACTCHG_MASK;
158 
159  if (pPedometer->config.stepcoalesce &&
160  (stepcount - pPedometer->private.stepchg_stepcount >= pPedometer->config.stepcoalesce))
161  {
162  pPedometer->private.stepchg_stepcount = stepcount;
163  newstatus |= PEDOMETER_STATUS_STEPCHG_MASK;
164  }
165 
166  if (suspend)
167  newstatus |= PEDOMETER_STATUS_SUSPEND_MASK;
168 
169  if ((newstatus ^ pPedometer->status.status.byte) & PEDOMETER_STATUS_SUSPEND_MASK)
170  newstatus |= PEDOMETER_STATUS_SUSPCHG_MASK;
171 
172  if (newstatus & PEDOMETER_STATUS_CHG_MASK)
173  newstatus |= PEDOMETER_STATUS_MRGFLG_MASK;
174  /* Update the status such stepcount, distance, speed etc..*/
175  pPedometer->status.stepcount = uint32_to_uint16(keynetikStepCount);
176  pPedometer->status.distance = uint32_to_uint16(keynetikDistance);
177  pPedometer->status.speed = keynetikSpeed;
178  pPedometer->status.calories = uint32_to_uint16(keynetikCalories);
179  pPedometer->status.status.byte = newstatus;
180 }
181 /*
182 ** ===================================================================
183 ** Method : suspend_compute
184 ** brief : compute the suspend status.
185 ** params[in] : pedometer_t *pPedometer, handle to the pedometer.
186 ** params[in] : ped_accel_t data acceleration data.
187 ** ===================================================================
188 */
189 static bool suspend_compute(pedometer_t *pPedometer, ped_accel_t *pData)
190 {
191  /* compute the magnitude*/
192  uint32_t mag2 = SQUARED(pData->accel[0]) + SQUARED(pData->accel[1]) + SQUARED(pData->accel[2]);
193  bool stationary =
194  (mag2 > SQUARED(pPedometer->config.sleepminimum)) && (mag2 < SQUARED(pPedometer->config.sleepmaximum));
195  bool suspend = debounce_count(pPedometer->config.bits.sleep_dbcntm, stationary, &pPedometer->status.sleepcount,
196  pPedometer->config.sleepcount_threshold);
197  return (suspend);
198 }
199 /*
200 ** ===================================================================
201 ** Method : uint32_to_uint16
202 ** brief : conversion function from 32 to 16.
203 ** params[in] : uint32_t x, imput
204 ** params[in] : ped_accel_data data acceleration data.
205 ** ===================================================================
206 */
207 uint16_t uint32_to_uint16(uint32_t val)
208 {
209  if (val > 0x0000FFFF)
210  return (0xFFFF);
211  return ((uint16_t)val);
212 }
213 /*
214 ** ===================================================================
215 ** Method : debounce_count
216 ** brief : compute the debouct status.
217 ** params[in] : bool dbcntm,
218 ** params[in] : bool condition
219 ** params[in] : debounce_count_t *count,
220 ** params[in] : debounce_count_t threshold, debouce threshold
221 ** ===================================================================
222 */
223 static bool debounce_count(bool dbcntm, bool condition, debounce_count_t *count, debounce_count_t threshold)
224 {
225  if (condition)
226  {
227  /* increment count up to, but not above the threshold */
228  *count = (*count + 1) < threshold ? *count + 1 : threshold;
229  }
230  else
231  {
232  if (dbcntm)
233  *count = 0;
234  else
235  /* decrement count down to, but not below zero */
236  *count = (*count - 1) > 0 ? *count - 1 : 0;
237  }
238  return ((bool)(*count >= threshold));
239 }
struct pedometer_t::pedometer_status_tag status
#define PEDO_ONEG_8G
Definition: pedometer.h:28
void pedometer_configure(pedometer_t *pPedometer, const pedometer_config_t *pConfig)
The interface function to configure the pedometer.
Definition: pedometer.c:111
KeynetikConfig keynetik
Definition: pedometer.h:61
#define PEDOMETER_STATUS_MRGFLG_MASK
Definition: pedometer.c:35
#define PEDOMETER_STATUS_SUSPEND_MASK
Definition: pedometer.c:31
KeynetikActivityLevel activitylevel_t
Definition: pedometer.h:26
#define PEDOMETER_STATUS_ACTIVITY_MASK
Definition: pedometer.c:30
The pedometer.h file contains the interface and structure definitions for pedometer application...
uint8_t stepcoalesce
Definition: pedometer.h:63
#define PEDOMETER_STATUS_CHG_MASK
Definition: pedometer.c:37
#define PEDO_FILTER_STEPS_DEFAULT
Definition: pedometer.h:35
#define PEDOMETER_STATUS_SUSPCHG_MASK
Definition: pedometer.c:34
This defines the configuration structure of the pedometer.
Definition: pedometer.h:46
#define PEDOMETER_STATUS_STEPCHG_MASK
Definition: pedometer.c:33
debounce_count_t sleepcount_threshold
Definition: pedometer.h:50
typedef int32_t(DATA_FORMAT_Append_t))(void *pData
The interface function to append the data on the formated stream.
struct pedometer_t::pedometer_status_tag::@351::@352 bits
#define PEDO_FREQHZ_DEFAULT
Definition: pedometer.h:31
debounce_count_t activitycount_threshold
Definition: pedometer.h:62
This defines the pedometer instance.
Definition: pedometer.h:73
This defines the acceleration input data for the pedometer.
Definition: pedometer.h:39
#define PEDO_FILTER_TIME_DEFAULT
Definition: pedometer.h:34
uint16_t frequency
Definition: pedometer.h:67
uint16_t sleepminimum
Definition: pedometer.h:48
struct pedometer_t::pedometer_private_tag private
pedometer_config_t config
Definition: pedometer.h:97
uint16_t debounce_count_t
Definition: pedometer.h:27
uint16_t sleepmaximum
Definition: pedometer.h:49
#define PEDO_SPEED_PERIOD_DEFAULT
Definition: pedometer.h:33
union pedometer_t::pedometer_status_tag::@351 status
#define SQUARED(x)
Definition: pedometer.c:39
#define PEDOMETER_STATUS_ACTCHG_MASK
Definition: pedometer.c:32
int32_t pedometer_run(pedometer_t *pPedometer, ped_accel_t *pData)
The interface function excutes the pedometer algorithm.
Definition: pedometer.c:125
#define PEDO_STEP_THRESHOLD_DEFAULT
Definition: pedometer.h:32
int16_t accel[3]
Definition: pedometer.h:41
struct pedometer_config_t::@350 bits
#define PEDOMETER_STATUS_ACTIVITY_BITNUM
Definition: pedometer.c:23
void pedometer_init(pedometer_t *pPedometer)
The interface function initialize the pedometer.
Definition: pedometer.c:97