NNP STM Generic Remote Module git-main
Loading...
Searching...
No Matches
acceltemp.c
Go to the documentation of this file.
1
8#include "main.h"
9#include "acceltemp.h"
10#include "ObjDict.h"
11
12#include "app.h"
13// -------- DEFINITIONS ----------
14
15
16// -------- DATA ------------
17
18
19// -------- PROTOTYPES ----------
20
21static void enableISPU();
22static void configISPU( UNS8 memsel, UNS16 addr, const UNS8* data, UNS16 len);
23static void confirmISPU( UNS8 memsel, UNS16 addr, const UNS8* data, UNS16 len);
24
25static UNS8 atanT( UNS16 x);
26static UNS8 intsqrt( UNS16 x);
27
28static UNS8 modeIMU = IMU_ACC_ENABLED;
29static UNS8 configureISPU = 1; //0=don't configure, 1=configure data and program, 2=configure data
30
31//============================
32// GLOBAL CODE
33//============================
34
35void putAccelRegSingle(UNS8 regNo, UNS8 data){
36 HAL_I2C_Mem_Write(&hi2c2, ACC_ADDR, regNo, 1, &data, 1, 25);
37}
38
39UNS8 getAccelRegSingle(UNS8 regNo){
40 UNS8 data;
41
42 HAL_I2C_Mem_Read(&hi2c2, ACC_ADDR, regNo, 1, &data, 1, 25);
43 return data;
44}
45
46void putAccelReg(UNS8 regNo, UNS8 data, UNS8 length){
47 HAL_I2C_Mem_Write(&hi2c2, ACC_ADDR, regNo, 1, &data, length, 25);
48}
49
50void getAccelReg(UNS8 regNo, UNS8* data, UNS8 length){
51 HAL_I2C_Mem_Read(&hi2c2, ACC_ADDR, regNo, 1, data, length, 25);
52}
53
54
60{
61 putAccelRegSingle(CTRL1_XL, 0x00); // Accel
62 putAccelRegSingle(CTRL2_G, 0x00); // Gyro
63 putAccelRegSingle(CTRL9_C, 0); // ISPU
64}
65
71void changeModeIMU (UNS8 mode){
72 if(mode & IMU_ISPU_ENABLED)
73 {
74 if(mode & IMU_RELOAD_ISPU)
75 {
76 configureISPU = 1;
77 }
78 else if(mode & IMU_RELOAD_ISPU_DATA)
79 {
80 configureISPU = 2;
81 }
82 else if(mode & IMU_ISPU_RST)
83 {
84 configureISPU = 3;
85 }
86 enableISPU();
87 }
88 else
89 {
90 putAccelRegSingle( FUNC_CFG_ACCESS, 0x00 ); //restore normal register access
91
92 putAccelRegSingle( CTRL9_C, 0 ); //powerdown ISPU
93 putAccelRegSingle( CTRL6_C, 0x10 ); //low power mode Acc
94 putAccelRegSingle( CTRL7_G, 0x80 ); //low power mode Gyro
95 if(mode & IMU_ACC_ENABLED)
96 {
97 putAccelRegSingle( CTRL1_XL, 0x20); //26Hz, 2g, Acc
98 }
99 else
100 {
101 putAccelRegSingle( CTRL1_XL, 0x00); //Powerdown Acc
102 }
103 if(mode & IMU_GYRO_ENABLED)
104 {
105 putAccelRegSingle( CTRL2_G, 0x20); //26Hz, +/-250dps, Gyro
106 }
107 else
108 {
109 putAccelRegSingle( CTRL2_G, 0x00); //Powerdown Gyro
110 }
111 }
112 modeIMU = mode;
113}
114
120 changeModeIMU(modeIMU);
121}
122
128{
129 //takes 2.9ms without average depth
130 // 4.0ms average depth =1
131 // 6.1ms average depth=20
132 // 8.4ms tilt calculation with average depth = 1
133 static UNS8 taskDelayMSecs = 50;
134 static UNS32 tDelayRef = 0; //JML: set to 0, so timesout first time through
135
136 if( !isTimedOut( &tDelayRef, TIMEOUT_ms( taskDelayMSecs ) ) )
137 {
138 return;
139 }
140
141 //ELSE.. reading delay is over
142
143 resetTimeOut( &tDelayRef );
144 /* read accelerometer and gyro x,y,z */
145
146 UNS8 accelData[6];
147 UNS8 tempData[2];
148 UNS8 gyroData[6];
149 UNS8 ispuData[16];
150
151 static INTEGER8 xBuf[ACCEL_BUFFER_LENGTH];
152 static INTEGER8 yBuf[ACCEL_BUFFER_LENGTH];
153 static INTEGER8 zBuf[ACCEL_BUFFER_LENGTH];
154 static UNS8 cnt = 0;
155
156 UNS8 depth = AccelerometerSettings & ACCEL_AVERAGE_DEPTH_BITS;
157
158 if ((modeIMU & IMU_ISPU_ENABLED) && ((modeIMU & IMU_ACC_ENABLED) || (modeIMU & IMU_GYRO_ENABLED) || (modeIMU & IMU_TEMP_ENABLED)))
159 {
160 /* restore normal register access */
161 putAccelRegSingle( FUNC_CFG_ACCESS, 0x00 );
162 }
163 if (modeIMU & IMU_ACC_ENABLED)
164 {
165 /* read accelerometer x,y,z (lowbyte highbyte each)*/
166 getAccelReg( OUTX_L_A, accelData, 6 );
167 }
168 if (modeIMU & IMU_GYRO_ENABLED)
169 {
170 /* read gyro x,y,z (lowbyte highbyte each)*/
171 getAccelReg( OUTX_L_G, gyroData, 6 );
172 }
173 if (modeIMU & IMU_TEMP_ENABLED)
174 {
175 /* read gyro x,y,z (lowbyte highbyte each)*/
176 getAccelReg( OUT_TEMP_L, tempData, 2 );
177 }
178
179 if ((modeIMU & IMU_ISPU_ENABLED) && ((modeIMU & IMU_ACC_ENABLED) || (modeIMU & IMU_GYRO_ENABLED) || (modeIMU & IMU_TEMP_ENABLED)))
180 {
181 /* ISPU register access */
182 putAccelRegSingle( FUNC_CFG_ACCESS, 0x80 );
183 }
184 if (modeIMU & IMU_ISPU_ENABLED)
185 {
186 /* read quaternion from ISPU (4 byte each x,y,z,w)*/
187 getAccelReg( ISPU_DOUT_00_L, ispuData, 16 );
188 }
189
190 //JML TODO: use all 16-bits - currently just high bytefor backwards compatibility
191 if (modeIMU & IMU_ACC_ENABLED)
192 {
193 Accelerometers[0] = accelData[1] * (modeIMU & IMU_ISPU_ENABLED ? 4 : 1) + 128; //ISPU Changes from 2g range to 8g range, so the output needs to be multiplied by 4 (loses precision)
194 Accelerometers[1] = accelData[3] * (modeIMU & IMU_ISPU_ENABLED ? 4 : 1) + 128;
195 Accelerometers[2] = accelData[5] * (modeIMU & IMU_ISPU_ENABLED ? 4 : 1) + 128;
196 Accelerometers[3]++;
197 }
198 if (modeIMU & IMU_GYRO_ENABLED)
199 {
200 memcpy(&Gyroscopes, gyroData, sizeof(gyroData));
201 }
202 if (modeIMU & IMU_TEMP_ENABLED)
203 {
204 memcpy(&TemperatureIMU, tempData, sizeof(tempData));
205 }
206 if (modeIMU & IMU_ISPU_ENABLED)
207 {
208 memcpy(&Quaternion, ispuData, sizeof(ispuData));
209 }
210
211 if (depth > 0)
212 {
213 UNS8 i;
214 INTEGER16 sumX=0, sumY=0, sumZ=0;
215 INTEGER8 x=0,y=0,z=0;
216
217 if(depth > ACCEL_BUFFER_LENGTH)
218 depth = ACCEL_BUFFER_LENGTH;
219
220 //Shift values in buffer
221 //destination, source
222 memmove( &xBuf[1], &xBuf[0], depth-1);
223 memmove( &yBuf[1], &yBuf[0], depth-1);
224 memmove( &zBuf[1], &zBuf[0], depth-1);
225
226 //Accelerometers is 0 to 256
227 //Add new value at beginning of buffer
228 //ignore bottom two bits and convert to signed (-32 to 31 range)
229 xBuf[0]=(INTEGER8)(Accelerometers[0]>>2) - 32;
230 yBuf[0]=(INTEGER8)(Accelerometers[1]>>2) - 32;
231 zBuf[0]=(INTEGER8)(Accelerometers[2]>>2) - 32;
232
233 if(cnt<depth) //if we haven't yet reached sampled depth
234 {
235 cnt++;
236 depth = cnt;
237 }
238
239 for(i=0; i<depth; i++)
240 {
241 sumX += xBuf[i];
242 sumY += yBuf[i];
243 sumZ += zBuf[i];
244 }
245 x =(INTEGER8)((sumX<<2)/depth);
246 y =(INTEGER8)((sumY<<2)/depth);
247 z =(INTEGER8)((sumZ<<2)/depth);
248 //in order to make the division more accurate we shift the sum left two bits before dividing
249 //outcome is now -128 to 127
250 AccelerometersFiltered[0] = (UNS8)(x + 128);
251 AccelerometersFiltered[1] = (UNS8)(y + 128);
252 AccelerometersFiltered[2] = (UNS8)(z + 128);
253 AccelerometersFiltered[3] = Accelerometers[3];
254
255
256
257 if(AccelerometerSettings & ACCEL_CALC_TILT_BIT)
258 {
259 //calculate squares in advance
260 UNS16 xx = x*x;
261 UNS16 yy = y*y;
262 UNS16 zz = z*z;
263
264 UNS16 yyzz = yy+zz;
265 UNS16 xxzz = xx+zz;
266 UNS16 xxyy = xx+yy;
267
268
269 if( x < 0 )
270 {
271 if(yyzz==0) //avoid divide by zero
272 AccelerometersTilt[0] = -90;
273 else
274 AccelerometersTilt[0] = - (INTEGER8) atanT( ((UNS16)(-x)<<8) / intsqrt(yyzz));
275 }
276 else
277 {
278 if(yyzz==0) //avoid divide by zero
279 AccelerometersTilt[0] = 90;
280 else
281 AccelerometersTilt[0] = (INTEGER8) atanT( ((UNS16)( x)<<8) / intsqrt(yyzz));
282 }
283 if( y < 0 )
284 {
285 if(xxzz==0) //avoid divide by zero
286 AccelerometersTilt[1] = -90;
287 else
288 AccelerometersTilt[1] = - (INTEGER8) atanT( ((UNS16)(-y)<<8) / intsqrt(xxzz));
289 }
290 else
291 {
292 if(xxzz==0) //avoid divide by zero
293 AccelerometersTilt[1] = 90;
294 else
295 AccelerometersTilt[1] = (INTEGER8) atanT( ((UNS16)( y)<<8) / intsqrt(xxzz));
296 }
297 if(z == 0) //avoid divide by zero
298 AccelerometersTilt[2] = 90;
299 else if(z < 0)
300 AccelerometersTilt[2] = - (INTEGER8) atanT( ((UNS16)intsqrt(xxyy)<<8) / (UNS8)(-z) );
301 else
302 AccelerometersTilt[2] = (INTEGER8) atanT( ((UNS16)intsqrt(xxyy)<<8) / (UNS8)( z) );
303
304 AccelerometersTilt[3] = Accelerometers[3];
305 }
306 }
307}
308
309void configISPU( UNS8 memsel, UNS16 addr, const UNS8* data, UNS16 len)
310{
311 putAccelRegSingle( ISPU_MEM_SEL, memsel ); //select data (0) or program mem (1)
312 putAccelRegSingle( ISPU_MEM_ADDR1, (UNS8) (addr >> 8)); //high byte
313 putAccelRegSingle( ISPU_MEM_ADDR0, (UNS8) (addr & 0xFF) ); //low byte
314
315 HAL_I2C_Mem_Write(&hi2c2, ACC_ADDR, ISPU_MEM_DATA, 1, data, len, 100);
316}
317
318void confirmISPU( UNS8 memsel, UNS16 addr, const UNS8* data, UNS16 len)
319{
320 return; //XXX: Currently returns becaue this function does nothing useful
321
322 UNS8 d = 0;
323 //TODO: confirm ISPU access, and combine writes below into single write
324 putAccelRegSingle( ISPU_MEM_SEL, 0x40+memsel ); //select data (0) or program mem (1) and read mem enabled
325 putAccelRegSingle( ISPU_MEM_ADDR1, (UNS8) (addr >> 8)); //high byte
326 putAccelRegSingle( ISPU_MEM_ADDR0, (UNS8) (addr & 0xFF) ); //low byte
327
328 while(len--)
329 {
330 d = getAccelRegSingle( ISPU_MEM_DATA); //TODO: do something with the output
331 }
332}
333
334
335void enableISPU(){
336
337 if(configureISPU == 1)
338 {
339 if(getAccelRegSingle( WHO_AM_I) == 0x22) //
340 {
341 putAccelRegSingle( CTRL3_C, 0x04 ); //enable BDU, IF_INC
342 putAccelRegSingle( CTRL3_C, 0x44 ); //enable BDU, IF_INC
343 getAccelRegSingle( CTRL3_C); //expect 0x44
344
345 //clear
346 putAccelRegSingle( CTRL6_C, 0 ); //reg0x15
347 putAccelRegSingle( CTRL1_XL, 0); //reg0x10
348 putAccelRegSingle( CTRL2_G, 0); //reg0x11
349 putAccelRegSingle( CTRL7_G, 0); //reg0x17
350 putAccelRegSingle( INT1_CTRL, 0 ); //reg0x0D
351
352 putAccelRegSingle( CTRL2_G, 0x48); //104Hz, 1000dps Gyro
353 putAccelRegSingle( CTRL1_XL, 0x4C ); //104Hz, 8g Accel
354
355 getAccelRegSingle( CTRL1_XL ); //expect 0x4C
356 getAccelRegSingle( CTRL6_C ); //expect 0
357 getAccelRegSingle( CTRL2_G ); //expect 0x48
358 getAccelRegSingle( CTRL7_G); //expect 0
359 }
360 else
361 {
362 configureISPU = 0;
363 }
364 }
365 if(configureISPU == 1 || configureISPU == 2 || configureISPU == 3)
366 {
367 //ISPU Config
368 putAccelRegSingle( FUNC_CFG_ACCESS, 2 ); //reset ISPU
369 }
370 if(configureISPU == 1 || configureISPU == 2)
371 {
372 putAccelRegSingle( FUNC_CFG_ACCESS, 0 ); //clear
373 putAccelRegSingle( FUNC_CFG_ACCESS, 0x80 ); //ISPU register access
374 configISPU(0, 0x0000, ispu_data, sizeof(ispu_data));
375 }
376 if(configureISPU == 1)
377 {
378 configISPU(1, 0x0000, ispu_bank1, sizeof(ispu_bank1));
379 configISPU(1, 0x2000, ispu_bank2, sizeof(ispu_bank2));
380 configISPU(1, 0x4000, ispu_bank3, sizeof(ispu_bank3));
381
382 //Read back all registers
383 confirmISPU(0, 0x0000, ispu_data, sizeof(ispu_data));
384 confirmISPU(1, 0x0000, ispu_bank1, sizeof(ispu_bank1));
385 confirmISPU(1, 0x2000, ispu_bank2, sizeof(ispu_bank2));
386 confirmISPU(1, 0x4000, ispu_bank3, sizeof(ispu_bank3));
387 }
388
389 configureISPU = 0;
390
391 putAccelRegSingle( FUNC_CFG_ACCESS, 0); //restore normal register access
392 putAccelRegSingle( CTRL9_C, 0 ); //powerdown ISPU
393 putAccelRegSingle( CTRL10_C, 0 );
394 putAccelRegSingle( CTRL1_XL, 0x10 );
395
396 putAccelRegSingle( FUNC_CFG_ACCESS, 0x80 ); //ISPU register access
397 putAccelRegSingle( ISPU_CONFIG, 0x01 ); //ISPU_RST_N
398
399 putAccelRegSingle( FUNC_CFG_ACCESS, 0 ); //restore normal register access
400
401 //Delay 5ms?
402
403 putAccelRegSingle( CTRL1_XL, 0 ); //powerdown acc
404 //putAccelRegSingle( INT2_CTRL, 0x80); //ISPU sleep state
405 putAccelRegSingle( INT2_CTRL, 0x00); //ISPU sleep state JML FIX for GND-INT2 errata
406 putAccelRegSingle( CTRL6_C, 0 ); //high performance mode Acc
407 putAccelRegSingle( CTRL7_G, 0 ); //high performance mode Gyro
408 putAccelRegSingle( CTRL9_C, 0x40); //ISPU rate = 104Hz
409 putAccelRegSingle( MD1_CFG, 0x02); //INT1_ISPU
410
411 putAccelRegSingle( FUNC_CFG_ACCESS, 0x80); //ISPU register access
412 putAccelRegSingle( ISPU_CONFIG, 0x01); //ISPU_RST_N
413 //putAccelRegSingle( ISPU_INT1_CTRL0, 0x01); //#1
414 putAccelRegSingle( ISPU_INT1_CTRL0, 0x00); //JML FIX for GND-INT2 errata
415 putAccelRegSingle( ISPU_INT2_CTRL0, 0x00); //JML FIX for GND-INT2 errata
416 putAccelRegSingle( ISPU_ALGO0, 0x01); //#1
417
418 putAccelRegSingle( FUNC_CFG_ACCESS, 0 ); //restore normal register access
419 putAccelRegSingle( CTRL1_XL, 0x4C); //104Hz, 8g, A
420 putAccelRegSingle( CTRL2_G, 0x4C); //104Hz, 2000dps, G
421
422 putAccelRegSingle( FUNC_CFG_ACCESS, 0x80); //ISPU register access
423}
424
431{
432 UNS8 sendData = 1;
433 HAL_I2C_Mem_Write(&hi2c2, TEMP_ADDR, T_CONF_REG, 1, &sendData, 1, 50);
434}
435
441void initTemperature( void )
442{
443
444}
445
451{
452 static UNS8 taskDelaySecs = 1; //^^fornow. later read from ObjDict; 0=off
453 static UNS32 tDelayRef = 0;//JML: set to 0, so timesout first time through;
454 UNS8 tempData[2];
455 INTEGER16 degrC;
456
457 if( !isTimedOut( &tDelayRef, TIMEOUT_sec( taskDelaySecs ) ) )
458 {
459 return;
460 }
461
462 //ELSE.. reading delay is over
463
464 resetTimeOut( &tDelayRef );
465
466 /* read temp */
467 if(HAL_I2C_Mem_Read(&hi2c2, TEMP_ADDR, T_TEMP_REG, 1, tempData, 2, 25) != HAL_OK)
468 {
469 return;
470 }
471
472 /* temp is measured in 1/16 degC above 0deg C */
473
474 /* save temperature reading in 10ths degC */
475
476 //Temperature = ((UNS16)tempData[0] << 4) + ((UNS16)tempData[1] >> 4 ); //Raw Reading
477
478 degrC = ( ( (INTEGER32)( ((UNS16)tempData[0] << 4) + ((UNS16)tempData[1] >> 4 ) ) )* 160 ) >> 8 ;
479
480 if( degrC > MAX_TEMPR )
481 {
482 degrC = MAX_TEMPR;
483 }
484 else if( degrC < MIN_TEMPR )
485 {
486 degrC = MIN_TEMPR;
487 }
488
489 Temperature = (UNS16)degrC;
490}
491
492void initDiagnostics(void){
493
494}
495
496
502{
503 static UNS8 taskDelayMSecs = 100;
504 static UNS32 tDelayRef = 0; //JML: set to 0, so timesout first time through
505 uint8_t ADCres[4];
506
507 if(DiagnosticsEnabled)
508 {
509 if( !isTimedOut( &tDelayRef, TIMEOUT_ms( taskDelayMSecs ) ) )
510 {
511 return;
512 }
513
514 //ELSE.. reading delay is over
515 resetTimeOut( &tDelayRef );
516
517 HAL_ADC_Start_DMA(&hadc1, &ADCres, 4); // Sample 4 enabled ADC channels and transfer results to ADCres through DMA
518 HAL_ADC_PollForConversion(&hadc1, 1); // Need time for DMA to transfer
519
520 Diagnostic_VOS = ADCres[0]; // Channel 1
521 Diagnostic_VIN = ADCres[1]; // Channel 2
522 Diagnostic_VIC = ADCres[2]; // Channel 3
523 Diagnostic_VDD = ADCres[3]; // Channel 4
524
525 }
526}
527
528//============================
529// LOCAL CODE
530//============================
531
532static UNS8 atanT( UNS16 x)
533{
534 UNS8 imax=NTAN;
535 UNS8 imin=0;
536 UNS8 i=0;
537 UNS8 delta=NTAN;
538
539 while(delta>1)
540 {
541 i=imin+(delta>>1);
542
543 if(x==TAN[i])
544 return i;//-TAN_IOFFSET;
545 else if(x<TAN[i])
546 imax = i;
547 else
548 imin = i;
549
550 delta = imax-imin;
551 }
552 return imin;//-TAN_IOFFSET;
553}
554
555static UNS8 intsqrt(UNS16 val) {
556 UNS8 mulMask = 0x0040;
557 UNS8 retVal = 0;
558 if (val > 8100)
559 return 90;
560
561 while (mulMask != 0) {
562 retVal |= mulMask;
563 if ((retVal * retVal) > val) {
564 retVal &= ~mulMask;
565 }
566
567 mulMask >>= 1;
568 }
569 return retVal;
570}
This file is generated by the NNP Tool – Object Dictionary Editor, as originally developed by CAN Fes...
void updateDiagnostics(void)
If disgnostics is enabled, update their entries in the OD.
Definition acceltemp.c:501
void sleepTemperature(void)
puts thermometer to sleep
Definition acceltemp.c:430
void initAccelerometer(void)
Initializes Accelerometer.
Definition acceltemp.c:119
void updateAccelerometer(void)
update Accelerometer
Definition acceltemp.c:127
void changeModeIMU(UNS8 mode)
Changes functional mode of ISM330IS accelerometer.
Definition acceltemp.c:71
void sleepAccelerometer(void)
puts Accelerometer to sleep
Definition acceltemp.c:59
void updateTemperature(void)
Gets temperature reading via I2C.
Definition acceltemp.c:450
void initTemperature(void)
initializes thermometer to default configuration
Definition acceltemp.c:441
Header file for app.c.
#define UNS8
Unsigned int8 representation in CANFest.
Definition applicfg.h:25
#define UNS16
Unsigned int16 representation in CANFest.
Definition applicfg.h:26
#define INTEGER8
Signed int8 representation in CANFest.
Definition applicfg.h:15
#define UNS32
Unsigned int32 representation in CANFest.
Definition applicfg.h:27
#define INTEGER32
Signed int32 representation in CANFest.
Definition applicfg.h:18
#define INTEGER16
Signed int16 representation in CANFest.
Definition applicfg.h:16
: Header for main.c file. This file contains the common defines of the application.
UNS8 isTimedOut(UNS32 *tRef, UNS32 tAlarm)
Checks if a timer has timed out.
Definition timer_stm.c:41
void resetTimeOut(UNS32 *tRef)
Resets a timed out timer.
Definition timer_stm.c:56