ISSDK  1.8
IoT Sensing Software Development Kit
DecodeCommandBytes.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 /*! \file DecodeCommandBytes.c
10  \brief Command interpreter which interfaces to the Sensor Fusion Toolbox
11 */
12 
13 #include "sensor_fusion.h"
14 #include "control.h"
15 #include "fusion.h"
16 #include "calibration_storage.h"
17 // All commands for the command interpreter are exactly 4 characters long.
18 // The command interpeter converts the incoming packet to a 32-bit integer, which is then
19 // the index into a large switch statement for processing commands.
20 // The following block of #define statements are responsible for the conversion from 4-characters
21 // into an easier to use integer format.
22 #define cmd_VGplus (((((('V' << 8) | 'G') << 8) | '+') << 8) | ' ') // "VG+ " = enable angular velocity packet transmission
23 #define cmd_VGminus (((((('V' << 8) | 'G') << 8) | '-') << 8) | ' ') // "VG- " = disable angular velocity packet transmission
24 #define cmd_DBplus (((((('D' << 8) | 'B') << 8) | '+') << 8) | ' ') // "DB+ " = enable debug packet transmission
25 #define cmd_DBminus (((((('D' << 8) | 'B') << 8) | '-') << 8) | ' ') // "DB- " = disable debug packet transmission
26 #define cmd_Q3 (((((('Q' << 8) | '3') << 8) | ' ') << 8) | ' ') // "Q3 " = transmit 3-axis accelerometer quaternion in standard packet
27 #define cmd_Q3M (((((('Q' << 8) | '3') << 8) | 'M') << 8) | ' ') // "Q3M " = transmit 3-axis magnetic quaternion in standard packet
28 #define cmd_Q3G (((((('Q' << 8) | '3') << 8) | 'G') << 8) | ' ') // "Q3G " = transmit 3-axis gyro quaternion in standard packet
29 #define cmd_Q6MA (((((('Q' << 8) | '6') << 8) | 'M') << 8) | 'A') // "Q6MA" = transmit 6-axis mag/accel quaternion in standard packet
30 #define cmd_Q6AG (((((('Q' << 8) | '6') << 8) | 'A') << 8) | 'G') // "Q6AG" = transmit 6-axis accel/gyro quaternion in standard packet
31 #define cmd_Q9 (((((('Q' << 8) | '9') << 8) | ' ') << 8) | ' ') // "Q9 " = transmit 9-axis quaternion in standard packet (default)
32 #define cmd_RPCplus (((((('R' << 8) | 'P') << 8) | 'C') << 8) | '+') // "RPC+" = Roll/Pitch/Compass on
33 #define cmd_RPCminus (((((('R' << 8) | 'P') << 8) | 'C') << 8) | '-') // "RPC-" = Roll/Pitch/Compass off
34 #define cmd_ALTplus (((((('A' << 8) | 'L') << 8) | 'T') << 8) | '+') // "ALT+" = Altitude packet on
35 #define cmd_ALTminus (((((('A' << 8) | 'L') << 8) | 'T') << 8) | '-') // "ALT-" = Altitude packet off
36 #define cmd_RST (((((('R' << 8) | 'S') << 8) | 'T') << 8) | ' ') // "RST " = Soft reset
37 #define cmd_RINS (((((('R' << 8) | 'I') << 8) | 'N') << 8) | 'S') // "RINS" = Reset INS inertial navigation velocity and position
38 #define cmd_SVAC (((((('S' << 8) | 'V') << 8) | 'A') << 8) | 'C') // "SVAC" = save all calibrations to Kinetis flash
39 #define cmd_SVMC (((((('S' << 8) | 'V') << 8) | 'M') << 8) | 'C') // "SVMC" = save magnetic calibration to Kinetis flash
40 #define cmd_SVYC (((((('S' << 8) | 'V') << 8) | 'Y') << 8) | 'C') // "SVYC" = save gyroscope calibration to Kinetis flash
41 #define cmd_SVGC (((((('S' << 8) | 'V') << 8) | 'G') << 8) | 'C') // "SVGC" = save precision accelerometer calibration to Kinetis flash
42 #define cmd_ERAC (((((('E' << 8) | 'R') << 8) | 'A') << 8) | 'C') // "ERAC" = erase all calibrations from Kinetis flash
43 #define cmd_ERMC (((((('E' << 8) | 'R') << 8) | 'M') << 8) | 'C') // "ERMC" = erase magnetic calibration from Kinetis flash
44 #define cmd_ERYC (((((('E' << 8) | 'R') << 8) | 'Y') << 8) | 'C') // "ERYC" = erase gyro offset calibration from Kinetis flash
45 #define cmd_ERGC (((((('E' << 8) | 'R') << 8) | 'G') << 8) | 'C') // "ERGC" = erase precision accelerometer calibration from Kinetis flash
46 #define cmd_180X (((((('1' << 8) | '8') << 8) | '0') << 8) | 'X') // "180X" perturbation
47 #define cmd_180Y (((((('1' << 8) | '8') << 8) | '0') << 8) | 'Y') // "180Y" perturbation
48 #define cmd_180Z (((((('1' << 8) | '8') << 8) | '0') << 8) | 'Z') // "180Z" perturbation
49 #define cmd_M90X (((((('M' << 8) | '9') << 8) | '0') << 8) | 'X') // "M90X" perturbation
50 #define cmd_P90X (((((('P' << 8) | '9') << 8) | '0') << 8) | 'X') // "P90X" perturbation
51 #define cmd_M90Y (((((('M' << 8) | '9') << 8) | '0') << 8) | 'Y') // "M90Y" perturbation
52 #define cmd_P90Y (((((('P' << 8) | '9') << 8) | '0') << 8) | 'Y') // "P90Y" perturbation
53 #define cmd_M90Z (((((('M' << 8) | '9') << 8) | '0') << 8) | 'Z') // "M90Z" perturbation
54 #define cmd_P90Z (((((('P' << 8) | '9') << 8) | '0') << 8) | 'Z') // "P90Z" perturbation
55 #define cmd_PA00 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '0') // "PA00" average precision accelerometer location 0
56 #define cmd_PA01 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '1') // "PA01" average precision accelerometer location 1
57 #define cmd_PA02 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '2') // "PA02" average precision accelerometer location 2
58 #define cmd_PA03 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '3') // "PA03" average precision accelerometer location 3
59 #define cmd_PA04 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '4') // "PA04" average precision accelerometer location 4
60 #define cmd_PA05 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '5') // "PA05" average precision accelerometer location 5
61 #define cmd_PA06 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '6') // "PA06" average precision accelerometer location 6
62 #define cmd_PA07 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '7') // "PA07" average precision accelerometer location 7
63 #define cmd_PA08 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '8') // "PA08" average precision accelerometer location 8
64 #define cmd_PA09 (((((('P' << 8) | 'A') << 8) | '0') << 8) | '9') // "PA09" average precision accelerometer location 9
65 #define cmd_PA10 (((((('P' << 8) | 'A') << 8) | '1') << 8) | '0') // "PA10" average precision accelerometer location 10
66 #define cmd_PA11 (((((('P' << 8) | 'A') << 8) | '1') << 8) | '1') // "PA11" average precision accelerometer location 11
67 
68 void DecodeCommandBytes(SensorFusionGlobals *sfg, char iCommandBuffer[], uint8 sUART_InputBuffer[], uint16 nbytes)
69 {
70  int32 isum; // 32 bit command identifier
71  int16 i, j; // loop counters
72 
73  // parse all received bytes in sUARTInputBuf into the iCommandBuffer delay line
74  for (i = 0; i < nbytes; i++) {
75  // shuffle the iCommandBuffer delay line and add the new command byte
76  for (j = 0; j < 3; j++)
77  iCommandBuffer[j] = iCommandBuffer[j + 1];
78  iCommandBuffer[3] = sUART_InputBuffer[i];
79 
80  // check if we have a valid command yet
81  isum = ((((((int32)iCommandBuffer[0] << 8) | iCommandBuffer[1]) << 8) | iCommandBuffer[2]) << 8) | iCommandBuffer[3];
82  switch (isum) {
83  case cmd_VGplus: // "VG+ " = enable angular velocity packet transmission
85  iCommandBuffer[3] = '~';
86  break;
87 
88  case cmd_VGminus: // "VG- " = disable angular velocity packet transmission
90  iCommandBuffer[3] = '~';
91  break;
92 
93  case cmd_DBplus: // "DB+ " = enable debug packet transmission
94  sfg->pControlSubsystem->DebugPacketOn = true;
95  iCommandBuffer[3] = '~';
96  break;
97 
98  case cmd_DBminus: // "DB- " = disable debug packet transmission
99  sfg->pControlSubsystem->DebugPacketOn = false;
100  iCommandBuffer[3] = '~';
101  break;
102 
103  case cmd_Q3: // "Q3 " = transmit 3-axis accelerometer quaternion in standard packet
104 #if F_3DOF_G_BASIC
106 #endif
107  iCommandBuffer[3] = '~';
108  break;
109 
110  case cmd_Q3M: // "Q3M " = transmit 3-axis magnetometer quaternion in standard packet
111 #if F_3DOF_B_BASIC
113 #endif
114  iCommandBuffer[3] = '~';
115  break;
116 
117  case cmd_Q3G: // "Q3G " = transmit 3-axis gyro quaternion in standard packet
118 #if F_3DOF_Y_BASIC
120 #endif
121  iCommandBuffer[3] = '~';
122  break;
123 
124  case cmd_Q6MA: // "Q6MA" = transmit 6-axis mag/accel quaternion in standard packet
125 #if F_6DOF_GB_BASIC
127 #endif
128  iCommandBuffer[3] = '~';
129  break;
130 
131  case cmd_Q6AG: // "Q6AG" = transmit 6-axis accel/gyro quaternion in standard packet
132 #if F_6DOF_GY_KALMAN
134 #endif
135  iCommandBuffer[3] = '~';
136  break;
137 
138  case cmd_Q9: // "Q9 " = transmit 9-axis quaternion in standard packet (default)
139 #if F_9DOF_GBY_KALMAN
141 #endif
142  iCommandBuffer[3] = '~';
143  break;
144 
145  case cmd_RPCplus: // "RPC+" = Roll/Pitch/Compass on
146  sfg->pControlSubsystem->RPCPacketOn = true;
147  iCommandBuffer[3] = '~';
148  break;
149 
150  case cmd_RPCminus: // "RPC-" = Roll/Pitch/Compass off
151  sfg->pControlSubsystem->RPCPacketOn = false;
152  iCommandBuffer[3] = '~';
153  break;
154 
155  case cmd_ALTplus: // "ALT+" = Altitude packet on
156  sfg->pControlSubsystem->AltPacketOn = true;
157  iCommandBuffer[3] = '~';
158  break;
159 
160  case cmd_ALTminus: // "ALT-" = Altitude packet off
161  sfg->pControlSubsystem->AltPacketOn = false;
162  iCommandBuffer[3] = '~';
163  break;
164 
165  case cmd_RST: // "RST " = Soft reset
166  // reset sensor fusion
167  fInitializeFusion(sfg);
168 
169  // reset magnetic calibration and magnetometer data buffer
170 #if F_USING_MAG
172 #endif
173  // reset precision accelerometer calibration and accelerometer measurements
174 #if F_USING_ACCEL
175  fInitializeAccelCalibration(&sfg->AccelCal, &sfg->AccelBuffer, &(sfg->pControlSubsystem->AccelCalPacketOn)) ;
176 #endif
177  iCommandBuffer[3] = '~';
178  break;
179 
180  case cmd_RINS: // "RINS" = Reset INS inertial navigation velocity and position
181 #if F_9DOF_GBY_KALMAN
182  for (i = CHX; i <= CHZ; i++) {
183  sfg->SV_9DOF_GBY_KALMAN.fVelGl[i] = 0.0F;
184  sfg->SV_9DOF_GBY_KALMAN.fDisGl[i] = 0.0F;
185  }
186 #endif
187  iCommandBuffer[3] = '~';
188  break;
189 
190  case cmd_SVAC: // "SVAC" = save all calibrations to Kinetis flash
194  iCommandBuffer[3] = '~';
195  break;
196 
197  case cmd_SVMC: // "SVMC" = save magnetic calibration to Kinetis flash
199  iCommandBuffer[3] = '~';
200  break;
201 
202  case cmd_SVYC: // "SVYC" = save gyroscope calibration to Kinetis flash
204  iCommandBuffer[3] = '~';
205  break;
206 
207  case cmd_SVGC: // "SVGC" = save precision accelerometer calibration to Kinetis flash
209  iCommandBuffer[3] = '~';
210  break;
211 
212  case cmd_ERAC: // "ERAC" = erase all calibrations from Kinetis flash
216  iCommandBuffer[3] = '~';
217  break;
218 
219  case cmd_ERMC: // "ERMC" = erase magnetic calibration offset 0 bytes from Kinetis flash
221  iCommandBuffer[3] = '~';
222  break;
223 
224  case cmd_ERYC: // "ERYC" = erase gyro offset calibrationoffset 128 bytes from Kinetis flash
226  iCommandBuffer[3] = '~';
227  break;
228 
229  case cmd_ERGC: // "ERGC" = erase precision accelerometer calibration offset 192 bytesfrom Kinetis flash
231  iCommandBuffer[3] = '~';
232  break;
233 
234  case cmd_180X: // "180X" perturbation
235  sfg->iPerturbation = 1;
236  iCommandBuffer[3] = '~';
237  break;
238 
239  case cmd_180Y: // "180Y" perturbation
240  sfg->iPerturbation = 2;
241  iCommandBuffer[3] = '~';
242  break;
243 
244  case cmd_180Z: // "180Z" perturbation
245  sfg->iPerturbation = 3;
246  iCommandBuffer[3] = '~';
247  break;
248 
249  case cmd_M90X: // "M90X" perturbation
250  sfg->iPerturbation = 4;
251  iCommandBuffer[3] = '~';
252  break;
253 
254  case cmd_P90X: // "P90X" perturbation
255  sfg->iPerturbation = 5;
256  iCommandBuffer[3] = '~';
257  break;
258 
259  case cmd_M90Y: // "M90Y" perturbation
260  sfg->iPerturbation = 6;
261  iCommandBuffer[3] = '~';
262  break;
263 
264  case cmd_P90Y: // "P90Y" perturbation
265  sfg->iPerturbation = 7;
266  iCommandBuffer[3] = '~';
267  break;
268 
269  case cmd_M90Z: // "M90Z" perturbation
270  sfg->iPerturbation = 8;
271  iCommandBuffer[3] = '~';
272  break;
273 
274  case cmd_P90Z: // "P90Z" perturbation
275  sfg->iPerturbation = 9;
276  iCommandBuffer[3] = '~';
277  break;
278 
279 #if F_USING_ACCEL
280  case cmd_PA00: // "PA00" average precision accelerometer location 0
281  sfg->AccelBuffer.iStoreLocation = 0;
282  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
283  iCommandBuffer[3] = '~';
284  break;
285 
286  case cmd_PA01: // "PA01" average precision accelerometer location 1
287  sfg->AccelBuffer.iStoreLocation = 1;
288  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
289  iCommandBuffer[3] = '~';
290  break;
291 
292  case cmd_PA02: // "PA02" average precision accelerometer location 2
293  sfg->AccelBuffer.iStoreLocation = 2;
294  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
295  iCommandBuffer[3] = '~';
296  break;
297 
298  case cmd_PA03: // "PA03" average precision accelerometer location 3
299  sfg->AccelBuffer.iStoreLocation = 3;
300  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
301  iCommandBuffer[3] = '~';
302  break;
303 
304  case cmd_PA04: // "PA04" average precision accelerometer location 4
305  sfg->AccelBuffer.iStoreLocation = 4;
306  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
307  iCommandBuffer[3] = '~';
308  break;
309 
310  case cmd_PA05: // "PA05" average precision accelerometer location 5
311  sfg->AccelBuffer.iStoreLocation = 5;
312  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
313  iCommandBuffer[3] = '~';
314  break;
315 
316  case cmd_PA06: // "PA06" average precision accelerometer location 6
317  sfg->AccelBuffer.iStoreLocation = 6;
318  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
319  iCommandBuffer[3] = '~';
320  break;
321 
322  case cmd_PA07: // "PA07" average precision accelerometer location 7
323  sfg->AccelBuffer.iStoreLocation = 7;
324  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
325  iCommandBuffer[3] = '~';
326  break;
327 
328  case cmd_PA08: // "PA08" average precision accelerometer location 8
329  sfg->AccelBuffer.iStoreLocation = 8;
330  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
331  iCommandBuffer[3] = '~';
332  break;
333 
334  case cmd_PA09: // "PA09" average precision accelerometer location 9
335  sfg->AccelBuffer.iStoreLocation = 9;
336  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
337  iCommandBuffer[3] = '~';
338  break;
339 
340  case cmd_PA10: // "PA10" average precision accelerometer location 10
341  sfg->AccelBuffer.iStoreLocation = 10;
342  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
343  iCommandBuffer[3] = '~';
344  break;
345 
346  case cmd_PA11: // "PA11" average precision accelerometer location 11
347  sfg->AccelBuffer.iStoreLocation = 11;
348  sfg->AccelBuffer.iStoreCounter = (ACCEL_CAL_AVERAGING_SECS * FUSION_HZ);
349  iCommandBuffer[3] = '~';
350  break;
351 #endif // precision accelerometer calibration
352 
353  default:
354  // no action
355  break;
356  }
357  } // end of loop over received characters
358 
359  return;
360 }
#define cmd_PA03
volatile uint8_t RPCPacketOn
flag to enable roll, pitch, compass packet
Definition: control.h:47
#define cmd_P90X
volatile uint8_t iPerturbation
test perturbation to be applied
#define cmd_180Y
volatile uint8_t AngularVelocityPacketOn
flag to enable angular velocity packet
Definition: control.h:45
int32_t int32
Definition: sensor_fusion.h:41
#define ACCEL_CAL_AVERAGING_SECS
calibration constants
#define cmd_180X
#define CHZ
Used to access Z-channel entries in various data data structures.
Definition: sensor_fusion.h:62
void EraseAccelCalibrationFromNVM(void)
#define cmd_P90Z
Quaternion derived from 3-axis accel + 3 axis mag (eCompass)
Definition: sensor_fusion.h:52
#define cmd_PA05
#define cmd_DBminus
Defines control sub-system.
void SaveGyroCalibrationToNVM(SensorFusionGlobals *sfg)
The top level fusion structure.
volatile uint8_t DebugPacketOn
flag to enable debug packet
Definition: control.h:46
#define cmd_RST
void fInitializeAccelCalibration(struct AccelCalibration *pthisAccelCal, struct AccelBuffer *pthisAccelBuffer, volatile int8 *AccelCalPacketOn)
Initialize the accelerometer calibration functions.
#define cmd_PA09
#define cmd_Q3M
#define cmd_Q6AG
#define cmd_DBplus
#define cmd_RPCplus
Quaternion derived from 3-axis accel (tilt)
Definition: sensor_fusion.h:49
#define cmd_Q6MA
#define cmd_SVAC
Quaternion derived from 3-axis mag only (auto compass algorithm)
Definition: sensor_fusion.h:50
#define cmd_PA00
volatile quaternion_type QuaternionPacketType
quaternion type transmitted over UART
Definition: control.h:44
int16_t int16
Definition: sensor_fusion.h:40
struct MagCalibration MagCal
mag cal storage
struct MagBuffer MagBuffer
mag cal constellation points
#define cmd_PA07
#define cmd_SVYC
Quaternion derived from full 9-axis sensor fusion.
Definition: sensor_fusion.h:54
#define cmd_VGplus
#define cmd_ERYC
void DecodeCommandBytes(SensorFusionGlobals *sfg, char iCommandBuffer[], uint8 sUART_InputBuffer[], uint16 nbytes)
#define cmd_VGminus
#define cmd_ERGC
The sensor_fusion.h file implements the top level programming interface.
void SaveMagCalibrationToNVM(SensorFusionGlobals *sfg)
#define cmd_P90Y
#define cmd_ERMC
void EraseMagCalibrationFromNVM(void)
volatile uint8_t AltPacketOn
flag to enable altitude packet
Definition: control.h:48
#define cmd_ALTplus
#define cmd_ERAC
#define cmd_PA02
#define cmd_PA08
void fInitializeMagCalibration(struct MagCalibration *pthisMagCal, struct MagBuffer *pthisMagBuffer)
Definition: magnetic.c:24
#define cmd_Q3
SensorFusionGlobals sfg
#define FUSION_HZ
(int) actual rate of fusion algorithm execution and sensor FIFO reads
#define cmd_SVMC
struct ControlSubsystem * pControlSubsystem
#define cmd_Q3G
#define cmd_ALTminus
Quaternion derived from 3-axis gyro only (rotation)
Definition: sensor_fusion.h:51
#define cmd_SVGC
#define cmd_RINS
#define CHX
Used to access X-channel entries in various data data structures.
Definition: sensor_fusion.h:60
#define cmd_M90Y
#define cmd_M90Z
void fInitializeFusion(SensorFusionGlobals *sfg)
Definition: fusion.c:33
uint8_t uint8
Definition: sensor_fusion.h:42
Quaternion derived from 3-axis accel + 3-axis gyro (gaming)
Definition: sensor_fusion.h:53
uint16_t uint16
Definition: sensor_fusion.h:43
#define cmd_RPCminus
#define cmd_PA01
#define cmd_PA10
#define cmd_Q9
#define cmd_180Z
#define cmd_M90X
void SaveAccelCalibrationToNVM(SensorFusionGlobals *sfg)
#define cmd_PA04
void EraseGyroCalibrationFromNVM(void)
#define cmd_PA11
Provides functions to store calibration to NVM.
Lower level sensor fusion interface.
volatile int8_t AccelCalPacketOn
variable used to coordinate accelerometer calibration
Definition: control.h:49
#define cmd_PA06