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 calibration_storage.c
11     \brief Provides functions to store calibration to NVM
12 
13     Users who are not using NXP hardware will need to supply their own drivers
14     in place of those defined here.
15 */
16 #include <stdio.h>
17 #include "sensor_fusion.h"
18 #include "driver_KSDK_NVM.h"
19 #include "calibration_storage.h"
20 
SaveMagCalibrationToNVM(SensorFusionGlobals * sfg)21 void SaveMagCalibrationToNVM(SensorFusionGlobals *sfg)
22 {
23 #if F_USING_MAG
24 	uint8_t *pSrc, *pDst;					// scratch pointers
25 	int16_t i;						// loop counter
26 	uint8_t iNVMBuffer[256];				// NVM write buffer (smallest size writeable to flash)
27         uint32_t itmp32;
28 
29 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
30 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
31 	pDst = iNVMBuffer;
32 	for (i = 0; i < 256; i++)
33 		*(pDst++) = *(pSrc++);
34 	// default to no magnetic calibration in header
35 	iNVMBuffer[MAG_NVM_OFFSET] = iNVMBuffer[MAG_NVM_OFFSET + 1] = iNVMBuffer[MAG_NVM_OFFSET + 2] = iNVMBuffer[MAG_NVM_OFFSET + 3] = 0xFF;
36 
37 	// fill the buffer with the magnetic calibration in bytes 0 to 67 (total 68 bytes)
38 	// [0-3]: four byte header denoting magnetic calibration present
39 	itmp32 = 0x12345678;
40 	pSrc = (uint8 *) &itmp32;
41 	pDst = iNVMBuffer + MAG_NVM_OFFSET;
42 	for (i = 0; i < 4; i++)
43 		*(pDst++) = *(pSrc++);
44 	// [4-67]: magnetic calibration: 15x float + 1x int32 total 64 bytes
45 	pSrc = (uint8 *) &(sfg->MagCal);
46 	for (i = 0; i < 64; i++)
47 		*(pDst++) = *(pSrc++);
48 
49 	// write the whole buffer contents to NVM
50 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
51 #endif // if F_USING_MAG
52 	return;
53 }
54 
SaveGyroCalibrationToNVM(SensorFusionGlobals * sfg)55 void SaveGyroCalibrationToNVM(SensorFusionGlobals *sfg)
56 {
57 #if F_USING_GYRO && (F_9DOF_GBY_KALMAN || F_6DOF_GY_KALMAN)
58 	uint8_t *pSrc, *pDst;					// scratch pointers
59 	int16_t i;						// loop counter
60 	uint8_t iNVMBuffer[256];				// NVM write buffer
61         uint32_t itmp32;
62 
63 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
64 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
65 	pDst = iNVMBuffer;
66 	for (i = 0; i < 256; i++)
67 		*(pDst++) = *(pSrc++);
68 	// default to no gyroscope calibration in header
69 	iNVMBuffer[GYRO_NVM_OFFSET] = iNVMBuffer[GYRO_NVM_OFFSET + 1] = iNVMBuffer[GYRO_NVM_OFFSET + 2] = iNVMBuffer[GYRO_NVM_OFFSET + 3] = 0xFF;
70 
71 	// define the four header bytes
72 	// [0-3]: four byte header denoting gyro calibration present
73 	itmp32 = 0x12345678;
74 	pSrc = (uint8 *) &itmp32;
75 	pDst = iNVMBuffer + GYRO_NVM_OFFSET;
76 	for (i = 0; i < 4; i++)
77 		*(pDst++) = *(pSrc++);
78 
79 	// [4-15]: 3 gyro offset floats totalling 12 bytes
80 #if F_9DOF_GBY_KALMAN
81 	pSrc = (uint8 *) sfg->SV_9DOF_GBY_KALMAN.fbPl;
82 #elif F_6DOF_GY_KALMAN
83 	pSrc = (uint8 *) sfg->SV_6DOF_GY_KALMAN.fbPl;
84 #endif
85 	for (i = 0; i < 12; i++)
86 		*(pDst++) = *(pSrc++);
87 
88 	// write the buffer contents to NVM
89 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
90 #endif
91 	return;
92 }
93 
SaveAccelCalibrationToNVM(SensorFusionGlobals * sfg)94 void SaveAccelCalibrationToNVM(SensorFusionGlobals *sfg)
95 {
96 #if F_USING_ACCEL
97 	uint8_t *pSrc, *pDst;					// scratch pointers
98 	int16_t i;							// loop counter
99 	uint8_t iNVMBuffer[256];				// NVM write buffer
100         uint32_t itmp32;
101 
102 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
103 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
104 	pDst = iNVMBuffer;
105 	for (i = 0; i < 256; i++)
106 		*(pDst++) = *(pSrc++);
107 	// default to no accelerometer calibration in header
108 	iNVMBuffer[ACCEL_NVM_OFFSET] = iNVMBuffer[ACCEL_NVM_OFFSET + 1] = iNVMBuffer[ACCEL_NVM_OFFSET + 2] = iNVMBuffer[ACCEL_NVM_OFFSET + 3] = 0xFF;
109 
110 	// [0-3]: four byte header denoting accelerometer calibration present
111 	itmp32 = 0x12345678;
112 	pSrc = (uint8 *) &itmp32;
113 	pDst = iNVMBuffer + ACCEL_NVM_OFFSET;
114 	for (i = 0; i < 4; i++)
115 		*(pDst++) = *(pSrc++);
116 
117 	// [4-87]: 21 precision accelerometer calibration floats totalling 84 bytes
118 	pSrc = (uint8 *) &(sfg->AccelCal);
119 	for (i = 0; i < 84; i++)
120 		*(pDst++) = *(pSrc++);
121 
122 	// write the buffer contents to NVM
123 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
124 #endif
125 	return;
126 }
127 
EraseMagCalibrationFromNVM(void)128 void EraseMagCalibrationFromNVM(void)
129 {
130 	uint8_t *pSrc, *pDst;					// scratch pointers
131 	int16_t i;						// loop counter
132 	uint8_t iNVMBuffer[256];				// NVM write buffer
133 
134 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
135 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
136 	pDst = iNVMBuffer;
137 	for (i = 0; i < 256; i++)
138 		*(pDst++) = *(pSrc++);
139 
140 	// set no magnetic calibration in header
141 	iNVMBuffer[MAG_NVM_OFFSET] = iNVMBuffer[MAG_NVM_OFFSET + 1] = iNVMBuffer[MAG_NVM_OFFSET + 2] = iNVMBuffer[MAG_NVM_OFFSET + 3] = 0xFF;
142 
143 	// write the buffer to flash
144 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
145 
146 	return;
147 }
148 
EraseGyroCalibrationFromNVM(void)149 void EraseGyroCalibrationFromNVM(void)
150 {
151 	uint8_t *pSrc, *pDst;					// scratch pointers
152 	int16_t i;							// loop counter
153 	uint8_t iNVMBuffer[256];				// NVM write buffer
154 
155 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
156 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
157 	pDst = iNVMBuffer;
158 	for (i = 0; i < 256; i++)
159 		*(pDst++) = *(pSrc++);
160 
161 	// set no gyroscope calibration in header
162 	iNVMBuffer[GYRO_NVM_OFFSET] = iNVMBuffer[GYRO_NVM_OFFSET + 1] = iNVMBuffer[GYRO_NVM_OFFSET + 2] = iNVMBuffer[GYRO_NVM_OFFSET + 3] = 0xFF;
163 
164 	// write the buffer to flash
165 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
166 
167 	return;
168 }
169 
EraseAccelCalibrationFromNVM(void)170 void EraseAccelCalibrationFromNVM(void)
171 {
172 	uint8_t *pSrc, *pDst;					// scratch pointers
173 	int16_t i;							// loop counter
174 	uint8_t iNVMBuffer[256];				// NVM write buffer
175 
176 	// copy existing magnetic, gyro and accelerometer calibrations to buffer
177 	pSrc = (uint8 *) CALIBRATION_NVM_ADDR;
178 	pDst = iNVMBuffer;
179 	for (i = 0; i < 256; i++)
180 		*(pDst++) = *(pSrc++);
181 
182 	// set no gyroscope calibration in header
183 	iNVMBuffer[ACCEL_NVM_OFFSET] = iNVMBuffer[ACCEL_NVM_OFFSET + 1] = iNVMBuffer[ACCEL_NVM_OFFSET + 2] = iNVMBuffer[ACCEL_NVM_OFFSET + 3] = 0xFF;
184 
185 	// write the buffer to flash
186 	NVM_SetBlockFlash(iNVMBuffer, CALIBRATION_NVM_ADDR, 256);
187 
188 	return;
189 }
190