Subversion Repositories NaviCtrl

Rev

Rev 419 | Rev 465 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
242 killagreg 1
/*#######################################################################################*/
2
/* !!! THIS IS NOT FREE SOFTWARE !!!                                                     */
3
/*#######################################################################################*/
4
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5
// + www.MikroKopter.com
6
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 7
// + Software Nutzungsbedingungen (english version: see below)
8
// + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt -
9
// + Der Lizenzgeber räumt dem Kunden ein nicht-ausschließliches, zeitlich und räumlich* unbeschränktes Recht ein, die im den
10
// + Mikrocontroller verwendete Firmware für die Hardware Flight-Ctrl, Navi-Ctrl, BL-Ctrl, MK3Mag & PC-Programm MikroKopter-Tool 
11
// + - nachfolgend Software genannt - nur für private Zwecke zu nutzen.
12
// + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig.
242 killagreg 13
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 14
// + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im
15
// + Rahmen der Vertragsanbahnung und Vertragsdurchführung überlassenen Unterlagen stehen im Verhältnis der Vertragspartner ausschließlich dem Lizenzgeber zu.
16
// + Die in der Software enthaltenen Copyright-Vermerke, Markenzeichen, andere Rechtsvorbehalte, Seriennummern sowie
17
// + sonstige der Programmidentifikation dienenden Merkmale dürfen vom Kunden nicht verändert oder unkenntlich gemacht werden.
18
// + Der Kunde trifft angemessene Vorkehrungen für den sicheren Einsatz der Software. Er wird die Software gründlich auf deren
19
// + Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
20
// + Die Haftung des Lizenzgebers wird - soweit gesetzlich zulässig - begrenzt in Höhe des typischen und vorhersehbaren
21
// + Schadens. Die gesetzliche Haftung bei Personenschäden und nach dem Produkthaftungsgesetz bleibt unberührt. Dem Lizenzgeber steht jedoch der Einwand 
22
// + des Mitverschuldens offen.
23
// + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet.
24
// + Er wird die Software gründlich auf deren Verwendbarkeit zu dem von ihm beabsichtigten Zweck testen, bevor er diese operativ einsetzt.
25
// + Der Kunde wird er seine Daten vor Einsatz der Software nach dem Stand der Technik sichern.
26
// + Der Kunde ist darüber unterrichtet, dass der Lizenzgeber seine Daten im zur Vertragsdurchführung erforderlichen Umfang
27
// + und auf Grundlage der Datenschutzvorschriften erhebt, speichert, verarbeitet und, sofern notwendig, an Dritte übermittelt.
28
// + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software.
29
// + #### ENDE DER NUTZUNGSBEDINGUNGEN ####'
30
// +  Hinweis: Informationen über erweiterte Nutzungsrechte (wie z.B. Nutzung für nicht-private Zwecke) sind auf Anfrage per Email an info(@)hisystems.de verfügbar.
242 killagreg 31
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 32
// + Software LICENSING TERMS
242 killagreg 33
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360 holgerb 34
// + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor -
35
// + The Licensor grants the customer a non-exclusive license to use the microcontroller firmware of the Flight-Ctrl, Navi-Ctrl, BL-Ctrl, and MK3Mag hardware 
36
// + (the Software) exclusively for private purposes. The License is unrestricted with respect to time and territory*.
37
// + The Software may only be used with the Licensor's products.
38
// + The Software provided by the Licensor is protected by copyright. With respect to the relationship between the parties to this
39
// + agreement, all rights pertaining to the Software and other documents provided during the preparation and execution of this
40
// + agreement shall be the property of the Licensor.
41
// + The information contained in the Software copyright notices, trademarks, other legal reservations, serial numbers and other
42
// + features that can be used to identify the program may not be altered or defaced by the customer.
43
// + The customer shall be responsible for taking reasonable precautions
44
// + for the safe use of the Software. The customer shall test the Software thoroughly regarding its suitability for the
45
// + intended purpose before implementing it for actual operation. The Licensor's liability shall be limited to the extent of typical and
46
// + foreseeable damage to the extent permitted by law, notwithstanding statutory liability for bodily injury and product
47
// + liability. However, the Licensor shall be entitled to the defense of contributory negligence.
48
// + The customer will take adequate precautions in the case, that the software is not working properly. The customer will test
49
// + the software for his purpose before any operational usage. The customer will backup his data before using the software.
50
// + The customer understands that the Licensor collects, stores and processes, and, where required, forwards, customer data
51
// + to third parties to the extent necessary for executing the agreement, subject to applicable data protection and privacy regulations.
52
// + *) The territory aspect only refers to the place where the Software is used, not its programmed range.
53
// + #### END OF LICENSING TERMS ####
54
// + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de.
242 killagreg 55
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
254 killagreg 56
#include <math.h>
292 killagreg 57
#include <stdio.h>
242 killagreg 58
#include <string.h>
59
#include "91x_lib.h"
253 killagreg 60
#include "ncmag.h"
242 killagreg 61
#include "i2c.h"
62
#include "timer1.h"
63
#include "led.h"
64
#include "uart1.h"
254 killagreg 65
#include "eeprom.h"
256 killagreg 66
#include "mymath.h"
292 killagreg 67
#include "main.h"
454 holgerb 68
#include "spi_slave.h"
242 killagreg 69
 
253 killagreg 70
u8 NCMAG_Present = 0;
254 killagreg 71
u8 NCMAG_IsCalibrated = 0;
242 killagreg 72
 
394 killagreg 73
// supported magnetic sensor types
74
#define TYPE_NONE                       0
75
#define TYPE_HMC5843            1
76
#define TYPE_LSM303DLH          2
77
#define TYPE_LSM303DLM          3
242 killagreg 78
 
394 killagreg 79
u8 NCMAG_SensorType = TYPE_NONE;
80
 
81
#define EEPROM_ADR_MAG_CALIBRATION              50
338 holgerb 82
#define CALIBRATION_VERSION                     1
394 killagreg 83
#define MAG_CALIBRATION_COMPATIBLE              0xA2
254 killagreg 84
 
256 killagreg 85
#define NCMAG_MIN_RAWVALUE -2047
86
#define NCMAG_MAX_RAWVALUE  2047
87
#define NCMAG_INVALID_DATA -4096
88
 
254 killagreg 89
typedef struct
90
{
91
        s16 Range;
92
        s16 Offset;
256 killagreg 93
} __attribute__((packed)) Scaling_t;
254 killagreg 94
 
95
typedef struct
96
{
97
        Scaling_t MagX;
98
        Scaling_t MagY;
99
        Scaling_t MagZ;
100
        u8 Version;
101
        u8 crc;
256 killagreg 102
} __attribute__((packed)) Calibration_t;
254 killagreg 103
 
104
Calibration_t Calibration;              // calibration data in RAM 
339 holgerb 105
volatile s16vec_t AccRawVector;
106
volatile s16vec_t MagRawVector;
254 killagreg 107
 
253 killagreg 108
// i2c MAG interface
109
#define MAG_SLAVE_ADDRESS       0x3C    // i2C slave address mag. sensor registers
242 killagreg 110
 
253 killagreg 111
// register mapping
112
#define REG_MAG_CRA                     0x00
113
#define REG_MAG_CRB                     0x01
114
#define REG_MAG_MODE            0x02
115
#define REG_MAG_DATAX_MSB       0x03
116
#define REG_MAG_DATAX_LSB       0x04
117
#define REG_MAG_DATAY_MSB       0x05
118
#define REG_MAG_DATAY_LSB       0x06
119
#define REG_MAG_DATAZ_MSB       0x07
120
#define REG_MAG_DATAZ_LSB       0x08
121
#define REG_MAG_STATUS          0x09
329 holgerb 122
 
253 killagreg 123
#define REG_MAG_IDA                     0x0A
124
#define REG_MAG_IDB                     0x0B
125
#define REG_MAG_IDC                     0x0C
394 killagreg 126
#define REG_MAG_IDF                     0x0F  // WHO_AM_I _M = 0x03c when LSM303DLM is connected
242 killagreg 127
 
253 killagreg 128
// bit mask for configuration mode
129
#define CRA_MODE_MASK           0x03
130
#define CRA_MODE_NORMAL         0x00    //default
131
#define CRA_MODE_POSBIAS        0x01
132
#define CRA_MODE_NEGBIAS        0x02
133
#define CRA_MODE_SELFTEST       0x03
242 killagreg 134
 
253 killagreg 135
// bit mask for measurement mode
136
#define MODE_MASK                       0xFF
137
#define MODE_CONTINUOUS         0x00
138
#define MODE_SINGLE                     0x01    // default
139
#define MODE_IDLE                       0x02
140
#define MODE_SLEEP                      0x03
141
 
242 killagreg 142
// bit mask for rate
253 killagreg 143
#define CRA_RATE_MASK           0x1C
144
 
145
// bit mask for gain
146
#define CRB_GAIN_MASK           0xE0
147
 
148
// ids
149
#define MAG_IDA         0x48
150
#define MAG_IDB         0x34
151
#define MAG_IDC         0x33
394 killagreg 152
#define MAG_IDF_LSM303DLM       0x3C
253 killagreg 153
 
154
// the special HMC5843 interface
155
// bit mask for rate
242 killagreg 156
#define HMC5843_CRA_RATE_0_5HZ          0x00
157
#define HMC5843_CRA_RATE_1HZ            0x04
158
#define HMC5843_CRA_RATE_2HZ            0x08
159
#define HMC5843_CRA_RATE_5HZ            0x0C
160
#define HMC5843_CRA_RATE_10HZ           0x10    //default
161
#define HMC5843_CRA_RATE_20HZ           0x14
162
#define HMC5843_CRA_RATE_50HZ           0x18
163
// bit mask for gain
164
#define HMC5843_CRB_GAIN_07GA           0x00
165
#define HMC5843_CRB_GAIN_10GA           0x20    //default
339 holgerb 166
#define HMC5843_CRB_GAIN_15GA           0x40    // <--- we use this     
242 killagreg 167
#define HMC5843_CRB_GAIN_20GA           0x60
168
#define HMC5843_CRB_GAIN_32GA           0x80
169
#define HMC5843_CRB_GAIN_38GA           0xA0
170
#define HMC5843_CRB_GAIN_45GA           0xC0
171
#define HMC5843_CRB_GAIN_65GA           0xE0
253 killagreg 172
// self test value
339 holgerb 173
#define HMC5843_TEST_XSCALE             555
174
#define HMC5843_TEST_YSCALE             555
175
#define HMC5843_TEST_ZSCALE             555
394 killagreg 176
// calibration range
342 holgerb 177
#define HMC5843_CALIBRATION_RANGE   600
242 killagreg 178
 
253 killagreg 179
// the special LSM302DLH interface
180
// bit mask for rate
181
#define LSM303DLH_CRA_RATE_0_75HZ       0x00
182
#define LSM303DLH_CRA_RATE_1_5HZ        0x04
183
#define LSM303DLH_CRA_RATE_3_0HZ        0x08
184
#define LSM303DLH_CRA_RATE_7_5HZ        0x0C
185
#define LSM303DLH_CRA_RATE_15HZ         0x10    //default
186
#define LSM303DLH_CRA_RATE_30HZ         0x14
187
#define LSM303DLH_CRA_RATE_75HZ         0x18
338 holgerb 188
 
253 killagreg 189
// bit mask for gain
190
#define LSM303DLH_CRB_GAIN_XXGA         0x00
191
#define LSM303DLH_CRB_GAIN_13GA         0x20    //default
339 holgerb 192
#define LSM303DLH_CRB_GAIN_19GA         0x40    // <--- we use this
253 killagreg 193
#define LSM303DLH_CRB_GAIN_25GA         0x60
194
#define LSM303DLH_CRB_GAIN_40GA         0x80
195
#define LSM303DLH_CRB_GAIN_47GA         0xA0
196
#define LSM303DLH_CRB_GAIN_56GA         0xC0
197
#define LSM303DLH_CRB_GAIN_81GA         0xE0
394 killagreg 198
 
199
typedef struct
200
{
201
        u8 A;
202
        u8 B;
203
        u8 C;
204
} __attribute__((packed)) Identification_t;
205
volatile Identification_t NCMAG_Identification;
206
 
207
typedef struct
208
{
209
        u8 Sub;
210
} __attribute__((packed)) Identification2_t;
211
volatile Identification2_t NCMAG_Identification2;
212
 
213
typedef struct
214
{
215
        u8 cra;
216
        u8 crb;
217
        u8 mode;
218
} __attribute__((packed)) MagConfig_t;
219
 
220
volatile MagConfig_t MagConfig;
221
 
222
 
253 killagreg 223
// self test value
338 holgerb 224
#define LSM303DLH_TEST_XSCALE   495
225
#define LSM303DLH_TEST_YSCALE   495
226
#define LSM303DLH_TEST_ZSCALE   470
339 holgerb 227
// clibration range
342 holgerb 228
#define LSM303_CALIBRATION_RANGE   550
253 killagreg 229
 
230
// the i2c ACC interface
231
#define ACC_SLAVE_ADDRESS               0x30    // i2c slave for acc. sensor registers
394 killagreg 232
 
233
// multiple byte read/write mask
234
#define REG_ACC_MASK_AUTOINCREMENT 0x80
235
 
253 killagreg 236
// register mapping
237
#define REG_ACC_CTRL1                   0x20
238
#define REG_ACC_CTRL2                   0x21
239
#define REG_ACC_CTRL3                   0x22
240
#define REG_ACC_CTRL4                   0x23
241
#define REG_ACC_CTRL5                   0x24
242
#define REG_ACC_HP_FILTER_RESET 0x25
243
#define REG_ACC_REFERENCE               0x26
244
#define REG_ACC_STATUS                  0x27
245
#define REG_ACC_X_LSB                   0x28
246
#define REG_ACC_X_MSB                   0x29
247
#define REG_ACC_Y_LSB                   0x2A
248
#define REG_ACC_Y_MSB                   0x2B
249
#define REG_ACC_Z_LSB                   0x2C
250
#define REG_ACC_Z_MSB                   0x2D
251
 
394 killagreg 252
#define ACC_CRTL1_PM_DOWN               0x00
253
#define ACC_CRTL1_PM_NORMAL             0x20
254
#define ACC_CRTL1_PM_LOW_0_5HZ  0x40
255
#define ACC_CRTL1_PM_LOW_1HZ    0x60
256
#define ACC_CRTL1_PM_LOW_2HZ    0x80
257
#define ACC_CRTL1_PM_LOW_5HZ    0xA0
258
#define ACC_CRTL1_PM_LOW_10HZ   0xC0
259
// Output data rate in normal power mode
260
#define ACC_CRTL1_DR_50HZ               0x00
261
#define ACC_CRTL1_DR_100HZ              0x08
262
#define ACC_CRTL1_DR_400HZ              0x10
263
#define ACC_CRTL1_DR_1000HZ             0x18
264
// axis anable flags                    
265
#define ACC_CRTL1_XEN                   0x01
266
#define ACC_CRTL1_YEN                   0x02
267
#define ACC_CRTL1_ZEN                   0x04
253 killagreg 268
 
397 holgerb 269
#define ACC_CRTL2_FILTER8       0x10
270
#define ACC_CRTL2_FILTER16      0x11
271
#define ACC_CRTL2_FILTER32      0x12
272
#define ACC_CRTL2_FILTER64      0x13
395 holgerb 273
 
394 killagreg 274
#define ACC_CTRL4_BDU                   0x80 // Block data update, (0: continuos update; 1: output registers not updated between MSB and LSB reading)
275
#define ACC_CTRL4_BLE                   0x40 // Big/little endian, (0: data LSB @ lower address; 1: data MSB @ lower address)
276
#define ACC_CTRL4_FS_2G                 0x00
277
#define ACC_CTRL4_FS_4G                 0x10
278
#define ACC_CTRL4_FS_8G                 0x30
279
#define ACC_CTRL4_STSIGN_PLUS   0x00
280
#define ACC_CTRL4_STSIGN_MINUS  0x08
281
#define ACC_CTRL4_ST_ENABLE             0x02
253 killagreg 282
 
394 killagreg 283
#define ACC_CTRL5_STW_ON                0x03
284
#define ACC_CTRL5_STW_OFF               0x00
242 killagreg 285
 
253 killagreg 286
typedef struct
287
{
288
        u8 ctrl_1;
289
        u8 ctrl_2;
290
        u8 ctrl_3;
291
        u8 ctrl_4;
292
        u8 ctrl_5;
293
} __attribute__((packed)) AccConfig_t;
294
 
295
volatile AccConfig_t AccConfig;
296
 
254 killagreg 297
u8 NCMag_CalibrationWrite(void)
298
{
394 killagreg 299
        u8 i, crc = MAG_CALIBRATION_COMPATIBLE;
254 killagreg 300
        EEPROM_Result_t eres;
301
        u8 *pBuff = (u8*)&Calibration;
302
 
303
        Calibration.Version = CALIBRATION_VERSION;
256 killagreg 304
        for(i = 0; i<(sizeof(Calibration)-1); i++)
254 killagreg 305
        {
306
                crc += pBuff[i];        
307
        }
308
        Calibration.crc = ~crc;
309
        eres = EEPROM_WriteBlock(EEPROM_ADR_MAG_CALIBRATION, pBuff, sizeof(Calibration));
310
        if(EEPROM_SUCCESS == eres) i = 1;
311
        else i = 0;
312
        return(i);     
313
}
314
 
315
u8 NCMag_CalibrationRead(void)
316
{
394 killagreg 317
        u8 i, crc = MAG_CALIBRATION_COMPATIBLE;
254 killagreg 318
        u8 *pBuff = (u8*)&Calibration;
319
 
320
        if(EEPROM_SUCCESS == EEPROM_ReadBlock(EEPROM_ADR_MAG_CALIBRATION, pBuff, sizeof(Calibration)))
321
        {
256 killagreg 322
                for(i = 0; i<(sizeof(Calibration)-1); i++)
254 killagreg 323
                {
324
                        crc += pBuff[i];        
325
                }
326
                crc = ~crc;
327
                if(Calibration.crc != crc) return(0); // crc mismatch
257 killagreg 328
                if(Calibration.Version == CALIBRATION_VERSION) return(1);
254 killagreg 329
        }
330
        return(0);
331
}
332
 
333
 
334
void NCMAG_Calibrate(void)
335
{
330 holgerb 336
        u8 msg[64];
454 holgerb 337
        static u8 speak = 0;
254 killagreg 338
        static s16 Xmin = 0, Xmax = 0, Ymin = 0, Ymax = 0, Zmin = 0, Zmax = 0;
256 killagreg 339
        static s16 X = 0, Y = 0, Z = 0;
254 killagreg 340
        static u8 OldCalState = 0;     
394 killagreg 341
        s16 MinCalibration = 450;
254 killagreg 342
 
256 killagreg 343
        X = (4*X + MagRawVector.X + 3)/5;
344
        Y = (4*Y + MagRawVector.Y + 3)/5;
345
        Z = (4*Z + MagRawVector.Z + 3)/5;
346
 
254 killagreg 347
        switch(Compass_CalState)
348
        {
349
                case 1:
350
                        // 1st step of calibration
351
                        // initialize ranges
352
                        // used to change the orientation of the NC in the horizontal plane
353
                        Xmin =  10000;
354
                        Xmax = -10000;
355
                        Ymin =  10000;
356
                        Ymax = -10000;
357
                        Zmin =  10000;
358
                        Zmax = -10000;
454 holgerb 359
                        speak = 1;
254 killagreg 360
                        break;
361
 
362
                case 2: // 2nd step of calibration
363
                        // find Min and Max of the X- and Y-Sensors during rotation in the horizontal plane
275 killagreg 364
                        if(X < Xmin)            { Xmin = X; BeepTime = 20;}
365
                        else if(X > Xmax)       { Xmax = X; BeepTime = 20;}
366
                        if(Y < Ymin)            { Ymin = Y; BeepTime = 60;}
367
                        else if(Y > Ymax)       { Ymax = Y; BeepTime = 60;}
454 holgerb 368
                        if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0;
254 killagreg 369
                        break;
370
 
371
                case 3: // 3rd step of calibration
372
                        // used to change the orientation of the MK3MAG vertical to the horizontal plane
454 holgerb 373
                        speak = 1;
254 killagreg 374
                        break;
375
 
376
                case 4:
377
                        // find Min and Max of the Z-Sensor
275 killagreg 378
                        if(Z < Zmin)      { Zmin = Z; BeepTime = 80;}
379
                        else if(Z > Zmax) { Zmax = Z; BeepTime = 80;}
454 holgerb 380
                        if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0;
254 killagreg 381
                        break;
382
 
383
                case 5:
384
                        // Save values
385
                        if(Compass_CalState != OldCalState) // avoid continously writing of eeprom!
386
                        {
394 killagreg 387
                                switch(NCMAG_SensorType)
388
                                {
389
                                        case TYPE_HMC5843:
390
                                                UART1_PutString("\r\nHMC5843 calibration\n\r");
391
                                                MinCalibration = HMC5843_CALIBRATION_RANGE;
392
                                                break;
393
 
394
                                        case TYPE_LSM303DLH:
395
                                        case TYPE_LSM303DLM:
396
                                                UART1_PutString("\r\n\r\nLSM303 calibration\n\r");
397
                                                MinCalibration = LSM303_CALIBRATION_RANGE;
398
                                        break;
399
                                }
342 holgerb 400
                                if(EarthMagneticStrengthTheoretic)
401
                                 {
394 killagreg 402
                                  MinCalibration = (MinCalibration * EarthMagneticStrengthTheoretic) / 50;
342 holgerb 403
                                  sprintf(msg, "Earth field on your location should be: %iuT\r\n",EarthMagneticStrengthTheoretic);
404
                                  UART1_PutString(msg);
405
                                 }
406
                            else UART1_PutString("without GPS\n\r");
339 holgerb 407
 
254 killagreg 408
                                Calibration.MagX.Range = Xmax - Xmin;
409
                                Calibration.MagX.Offset = (Xmin + Xmax) / 2;
410
                                Calibration.MagY.Range = Ymax - Ymin;
411
                                Calibration.MagY.Offset = (Ymin + Ymax) / 2;
412
                                Calibration.MagZ.Range = Zmax - Zmin;
413
                                Calibration.MagZ.Offset = (Zmin + Zmax) / 2;
394 killagreg 414
                                if((Calibration.MagX.Range > MinCalibration) && (Calibration.MagY.Range > MinCalibration) && (Calibration.MagZ.Range > MinCalibration))
254 killagreg 415
                                {
416
                                        NCMAG_IsCalibrated = NCMag_CalibrationWrite();
270 killagreg 417
                                        BeepTime = 2500;
342 holgerb 418
                                        UART1_PutString("\r\n-> Calibration okay <-\n\r");
454 holgerb 419
SpeakHoTT = SPEAK_MIKROKOPTER;
254 killagreg 420
                                }
421
                                else
422
                                {
454 holgerb 423
SpeakHoTT = SPEAK_ERR_CALIBARTION;
339 holgerb 424
                                        UART1_PutString("\r\nCalibration FAILED - Values too low: ");
394 killagreg 425
                                    if(Calibration.MagX.Range < MinCalibration) UART1_PutString("X! ");
426
                                    if(Calibration.MagY.Range < MinCalibration) UART1_PutString("Y! ");
427
                                    if(Calibration.MagZ.Range < MinCalibration) UART1_PutString("Z! ");
330 holgerb 428
                                        UART1_PutString("\r\n");
339 holgerb 429
 
254 killagreg 430
                                        // restore old calibration data from eeprom
431
                                        NCMAG_IsCalibrated = NCMag_CalibrationRead();
432
                                }
330 holgerb 433
                                        sprintf(msg, "X: (%i - %i = %i)\r\n",Xmax,Xmin,Xmax - Xmin);
434
                                        UART1_PutString(msg);
435
                                        sprintf(msg, "Y: (%i - %i = %i)\r\n",Ymax,Ymin,Ymax - Ymin);
436
                                        UART1_PutString(msg);
437
                                        sprintf(msg, "Z: (%i - %i = %i)\r\n",Zmax,Zmin,Zmax - Zmin);
438
                                        UART1_PutString(msg);
394 killagreg 439
                                        sprintf(msg, "(Minimum ampilitude is: %i)\r\n",MinCalibration);
342 holgerb 440
                                        UART1_PutString(msg);
254 killagreg 441
                        }
442
                        break;
443
 
444
                default:
445
                        break; 
446
        }
447
        OldCalState = Compass_CalState;
448
}
449
 
242 killagreg 450
// ---------- call back handlers -----------------------------------------
451
 
452
// rx data handler for id info request
253 killagreg 453
void NCMAG_UpdateIdentification(u8* pRxBuffer, u8 RxBufferSize)
254 killagreg 454
{       // if number of bytes are matching
253 killagreg 455
        if(RxBufferSize == sizeof(NCMAG_Identification) )
242 killagreg 456
        {
253 killagreg 457
                memcpy((u8 *)&NCMAG_Identification, pRxBuffer, sizeof(NCMAG_Identification));
458
        }
242 killagreg 459
}
329 holgerb 460
 
461
void NCMAG_UpdateIdentification_Sub(u8* pRxBuffer, u8 RxBufferSize)
462
{       // if number of bytes are matching
463
        if(RxBufferSize == sizeof(NCMAG_Identification2))
464
        {
465
                memcpy((u8 *)&NCMAG_Identification2, pRxBuffer, sizeof(NCMAG_Identification2));
466
        }
467
}
468
 
254 killagreg 469
// rx data handler for magnetic sensor raw data
253 killagreg 470
void NCMAG_UpdateMagVector(u8* pRxBuffer, u8 RxBufferSize)
254 killagreg 471
{       // if number of bytes are matching
472
        if(RxBufferSize == sizeof(MagRawVector) )
243 killagreg 473
        {       // byte order from big to little endian
256 killagreg 474
                s16 raw;
475
                raw = pRxBuffer[0]<<8;
476
                raw+= pRxBuffer[1];
477
                if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) MagRawVector.X = raw;
478
                raw = pRxBuffer[2]<<8;
479
                raw+= pRxBuffer[3];
330 holgerb 480
            if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE)
481
                {
394 killagreg 482
                        if(NCMAG_SensorType == TYPE_LSM303DLM)  MagRawVector.Z = raw; // here Z and Y are exchanged
483
                        else                                                                    MagRawVector.Y = raw;
330 holgerb 484
                }
256 killagreg 485
                raw = pRxBuffer[4]<<8;
486
                raw+= pRxBuffer[5];
330 holgerb 487
                if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE)
488
                {
394 killagreg 489
                        if(NCMAG_SensorType == TYPE_LSM303DLM)  MagRawVector.Y = raw; // here Z and Y are exchanged
490
                        else                                                                    MagRawVector.Z = raw;
330 holgerb 491
                }
242 killagreg 492
        }
254 killagreg 493
        if(Compass_CalState || !NCMAG_IsCalibrated)
284 killagreg 494
        {       // mark out data invalid
289 killagreg 495
                MagVector.X = MagRawVector.X;
496
                MagVector.Y = MagRawVector.Y;
497
                MagVector.Z = MagRawVector.Z;
254 killagreg 498
                Compass_Heading = -1;
499
        }
500
        else
501
        {
502
                // update MagVector from MagRaw Vector by Scaling
503
                MagVector.X = (s16)((1024L*(s32)(MagRawVector.X - Calibration.MagX.Offset))/Calibration.MagX.Range);
504
                MagVector.Y = (s16)((1024L*(s32)(MagRawVector.Y - Calibration.MagY.Offset))/Calibration.MagY.Range);
505
                MagVector.Z = (s16)((1024L*(s32)(MagRawVector.Z - Calibration.MagZ.Offset))/Calibration.MagZ.Range);
292 killagreg 506
                Compass_CalcHeading();
254 killagreg 507
        }
242 killagreg 508
}
254 killagreg 509
// rx data handler  for acceleration raw data
253 killagreg 510
void NCMAG_UpdateAccVector(u8* pRxBuffer, u8 RxBufferSize)
511
{       // if number of byte are matching
397 holgerb 512
static s32 filter_z;
254 killagreg 513
        if(RxBufferSize == sizeof(AccRawVector) )
253 killagreg 514
        {
254 killagreg 515
                memcpy((u8*)&AccRawVector, pRxBuffer,sizeof(AccRawVector));
253 killagreg 516
        }
416 holgerb 517
//      DebugOut.Analog[16] = AccRawVector.X;
518
//      DebugOut.Analog[17] = AccRawVector.Y;
519
        filter_z = (filter_z * 7 + AccRawVector.Z) / 8;
397 holgerb 520
 
416 holgerb 521
//      DebugOut.Analog[18] = filter_z;
522
//      DebugOut.Analog[19] = AccRawVector.Z;
253 killagreg 523
}
254 killagreg 524
// rx data handler for reading magnetic sensor configuration
253 killagreg 525
void NCMAG_UpdateMagConfig(u8* pRxBuffer, u8 RxBufferSize)
526
{       // if number of byte are matching
527
        if(RxBufferSize == sizeof(MagConfig) )
528
        {
529
                memcpy((u8*)(&MagConfig), pRxBuffer, sizeof(MagConfig));
530
        }
531
}
254 killagreg 532
// rx data handler for reading acceleration sensor configuration
253 killagreg 533
void NCMAG_UpdateAccConfig(u8* pRxBuffer, u8 RxBufferSize)
534
{       // if number of byte are matching
535
        if(RxBufferSize == sizeof(AccConfig) )
536
        {
537
                memcpy((u8*)&AccConfig, pRxBuffer, sizeof(AccConfig));
538
        }
539
}
254 killagreg 540
//----------------------------------------------------------------------
253 killagreg 541
 
254 killagreg 542
 
543
// ---------------------------------------------------------------------
253 killagreg 544
u8 NCMAG_SetMagConfig(void)
545
{
546
        u8 retval = 0;
547
        // try to catch the i2c buffer within 100 ms timeout
548
        if(I2C_LockBuffer(100))
549
        {
550
                u8 TxBytes = 0;
551
                I2C_Buffer[TxBytes++] = REG_MAG_CRA;    
552
                memcpy((u8*)(&I2C_Buffer[TxBytes]), (u8*)&MagConfig, sizeof(MagConfig));
553
                TxBytes += sizeof(MagConfig);
554
                if(I2C_Transmission(MAG_SLAVE_ADDRESS, TxBytes, 0, 0))
555
                {
556
                        if(I2C_WaitForEndOfTransmission(100))
557
                        {
558
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
559
                        }
560
                }
561
        }
562
        return(retval);        
563
}
242 killagreg 564
 
253 killagreg 565
// ----------------------------------------------------------------------------------------
566
u8 NCMAG_GetMagConfig(void)
242 killagreg 567
{
253 killagreg 568
        u8 retval = 0;
252 killagreg 569
        // try to catch the i2c buffer within 100 ms timeout
248 killagreg 570
        if(I2C_LockBuffer(100))
242 killagreg 571
        {
253 killagreg 572
                u8 TxBytes = 0;
573
                I2C_Buffer[TxBytes++] = REG_MAG_CRA;
574
                if(I2C_Transmission(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateMagConfig, sizeof(MagConfig)))
248 killagreg 575
                {
252 killagreg 576
                        if(I2C_WaitForEndOfTransmission(100))
577
                        {
578
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
579
                        }
248 killagreg 580
                }
242 killagreg 581
        }
253 killagreg 582
        return(retval);        
242 killagreg 583
}
584
 
585
// ----------------------------------------------------------------------------------------
253 killagreg 586
u8 NCMAG_SetAccConfig(void)
242 killagreg 587
{
252 killagreg 588
        u8 retval = 0;
253 killagreg 589
        // try to catch the i2c buffer within 100 ms timeout
248 killagreg 590
        if(I2C_LockBuffer(100))
242 killagreg 591
        {
253 killagreg 592
                u8 TxBytes = 0;
394 killagreg 593
                I2C_Buffer[TxBytes++] = REG_ACC_CTRL1|REG_ACC_MASK_AUTOINCREMENT;      
253 killagreg 594
                memcpy((u8*)(&I2C_Buffer[TxBytes]), (u8*)&AccConfig, sizeof(AccConfig));
595
                TxBytes += sizeof(AccConfig);
596
                if(I2C_Transmission(ACC_SLAVE_ADDRESS, TxBytes, 0, 0))
597
                {
598
                        if(I2C_WaitForEndOfTransmission(100))
599
                        {
600
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
601
                        }
602
                }
603
        }
604
        return(retval);        
605
}
606
 
607
// ----------------------------------------------------------------------------------------
608
u8 NCMAG_GetAccConfig(void)
609
{
610
        u8 retval = 0;
611
        // try to catch the i2c buffer within 100 ms timeout
612
        if(I2C_LockBuffer(100))
613
        {
614
                u8 TxBytes = 0;
394 killagreg 615
                I2C_Buffer[TxBytes++] = REG_ACC_CTRL1|REG_ACC_MASK_AUTOINCREMENT;
253 killagreg 616
                if(I2C_Transmission(ACC_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateAccConfig, sizeof(AccConfig)))
617
                {
618
                        if(I2C_WaitForEndOfTransmission(100))
619
                        {
620
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
621
                        }
622
                }
623
        }
624
        return(retval);        
625
}
626
 
627
// ----------------------------------------------------------------------------------------
628
u8 NCMAG_GetIdentification(void)
629
{
630
        u8 retval = 0;
631
        // try to catch the i2c buffer within 100 ms timeout
632
        if(I2C_LockBuffer(100))
633
        {
634
                u16 TxBytes = 0;
635
                NCMAG_Identification.A = 0xFF;
636
                NCMAG_Identification.B = 0xFF;
637
                NCMAG_Identification.C = 0xFF;
638
                I2C_Buffer[TxBytes++] = REG_MAG_IDA;
248 killagreg 639
                // initiate transmission
253 killagreg 640
                if(I2C_Transmission(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateIdentification, sizeof(NCMAG_Identification)))
248 killagreg 641
                {
253 killagreg 642
                        if(I2C_WaitForEndOfTransmission(100))
252 killagreg 643
                        {
644
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
645
                        }
248 killagreg 646
                }
242 killagreg 647
        }
253 killagreg 648
        return(retval);
242 killagreg 649
}
650
 
329 holgerb 651
u8 NCMAG_GetIdentification_Sub(void)
652
{
653
        u8 retval = 0;
654
        // try to catch the i2c buffer within 100 ms timeout
655
        if(I2C_LockBuffer(100))
656
        {
657
                u16 TxBytes = 0;
658
                NCMAG_Identification2.Sub = 0xFF;
659
                I2C_Buffer[TxBytes++] = REG_MAG_IDF;
660
                // initiate transmission
661
                if(I2C_Transmission(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateIdentification_Sub, sizeof(NCMAG_Identification2)))
662
                {
663
                        if(I2C_WaitForEndOfTransmission(100))
664
                        {
665
                                if(I2C_Error == I2C_ERROR_NONE) retval = 1;
666
                        }
667
                }
668
        }
669
        return(retval);
670
}
671
 
672
 
253 killagreg 673
// ----------------------------------------------------------------------------------------
674
void NCMAG_GetMagVector(void)
675
{
676
        // try to catch the I2C buffer within 0 ms
677
        if(I2C_LockBuffer(0))
678
        {
679
                u16 TxBytes = 0;
680
                // set register pointer
681
                I2C_Buffer[TxBytes++] = REG_MAG_DATAX_MSB;
682
                // initiate transmission
683
                I2C_Transmission(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateMagVector, sizeof(MagVector));
684
        }
685
}
686
 
242 killagreg 687
//----------------------------------------------------------------
253 killagreg 688
void NCMAG_GetAccVector(void)
243 killagreg 689
{
252 killagreg 690
        // try to catch the I2C buffer within 0 ms
691
        if(I2C_LockBuffer(0))
243 killagreg 692
        {
248 killagreg 693
                u16 TxBytes = 0;
243 killagreg 694
                // set register pointer
394 killagreg 695
                I2C_Buffer[TxBytes++] = REG_ACC_X_LSB|REG_ACC_MASK_AUTOINCREMENT;
243 killagreg 696
                // initiate transmission
254 killagreg 697
                I2C_Transmission(ACC_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector));
243 killagreg 698
        }
699
}
700
 
330 holgerb 701
//----------------------------------------------------------------
394 killagreg 702
u8 InitNC_MagnetSensor(void)
330 holgerb 703
{
704
        u8 crb_gain, cra_rate;
705
 
394 killagreg 706
        switch(NCMAG_SensorType)
330 holgerb 707
        {
394 killagreg 708
                case TYPE_HMC5843:
339 holgerb 709
                        crb_gain = HMC5843_CRB_GAIN_15GA;
330 holgerb 710
                        cra_rate = HMC5843_CRA_RATE_50HZ;
711
                        break;
712
 
394 killagreg 713
                case TYPE_LSM303DLH:
714
                case TYPE_LSM303DLM:
338 holgerb 715
                        crb_gain = LSM303DLH_CRB_GAIN_19GA;
330 holgerb 716
                        cra_rate = LSM303DLH_CRA_RATE_75HZ;
717
                        break;
718
 
719
                default:
394 killagreg 720
                return(0);
330 holgerb 721
        }
722
 
723
        MagConfig.cra = cra_rate|CRA_MODE_NORMAL;
724
        MagConfig.crb = crb_gain;
725
        MagConfig.mode = MODE_CONTINUOUS;
394 killagreg 726
        return(NCMAG_SetMagConfig());
330 holgerb 727
}
728
 
395 holgerb 729
 
394 killagreg 730
//----------------------------------------------------------------
731
u8 NCMAG_Init_ACCSensor(void)
732
{
395 holgerb 733
        AccConfig.ctrl_1 = ACC_CRTL1_PM_NORMAL|ACC_CRTL1_DR_50HZ|ACC_CRTL1_XEN|ACC_CRTL1_YEN|ACC_CRTL1_ZEN;
397 holgerb 734
        AccConfig.ctrl_2 = 0;//ACC_CRTL2_FILTER32;
394 killagreg 735
        AccConfig.ctrl_3 = 0x00;
397 holgerb 736
        AccConfig.ctrl_4 = ACC_CTRL4_BDU | ACC_CTRL4_FS_8G;
394 killagreg 737
        AccConfig.ctrl_5 = ACC_CTRL5_STW_OFF;
738
        return(NCMAG_SetAccConfig());
739
}
253 killagreg 740
// --------------------------------------------------------
292 killagreg 741
void NCMAG_Update(void)
243 killagreg 742
{
292 killagreg 743
        static u32 TimerUpdate = 0;
419 holgerb 744
        static s8 send_config = 0;
394 killagreg 745
        u32 delay = 20;
243 killagreg 746
 
254 killagreg 747
        if( (I2C_State == I2C_STATE_OFF) || !NCMAG_Present )
748
        {
749
                Compass_Heading = -1;
326 holgerb 750
                DebugOut.Analog[14]++; // count I2C error
254 killagreg 751
                return;
752
        }
292 killagreg 753
        if(CheckDelay(TimerUpdate))
243 killagreg 754
        {
394 killagreg 755
                if(Compass_Heading != -1) send_config = 0; // no re-configuration if value is valid
756
        if(++send_config == 25)   // 500ms
757
                {
419 holgerb 758
                        send_config = -25;    // next try after 1 second
394 killagreg 759
                InitNC_MagnetSensor();
419 holgerb 760
                        TimerUpdate = SetDelay(20);    // back into the old time-slot
394 killagreg 761
                }
321 holgerb 762
                else
763
                {
398 holgerb 764
//                      static u8 s = 0;
394 killagreg 765
                        // check for new calibration state
766
                        Compass_UpdateCalState();
767
                        if(Compass_CalState) NCMAG_Calibrate();
768
 
769
                        // in case of LSM303 type
770
                        switch(NCMAG_SensorType)
771
                        {
772
                                case TYPE_HMC5843:                             
773
                                        NCMAG_GetMagVector();
774
                                        delay = 20;
775
                                        break;
776
                                case TYPE_LSM303DLH:
777
                                case TYPE_LSM303DLM:
397 holgerb 778
                                        NCMAG_GetMagVector();
779
                                        delay = 20;
780
/*                                      if(s){ NCMAG_GetMagVector(); s = 0;}
394 killagreg 781
                                        else { NCMAG_GetAccVector(); s = 1;}
782
                                        delay = 10;
397 holgerb 783
*/
394 killagreg 784
                                        break;                           
785
                        }
419 holgerb 786
                        if(send_config == 24) TimerUpdate = SetDelay(15);    // next event is the re-configuration
394 killagreg 787
                        else TimerUpdate = SetDelay(delay);    // every 20 ms are 50 Hz
321 holgerb 788
                }
243 killagreg 789
        }
790
}
791
 
330 holgerb 792
 
254 killagreg 793
// --------------------------------------------------------
253 killagreg 794
u8 NCMAG_SelfTest(void)
243 killagreg 795
{
266 holgerb 796
        u8 msg[64];
275 killagreg 797
        static u8 done = 0;
266 holgerb 798
 
287 holgerb 799
        if(done) return(1);        // just make it once
275 killagreg 800
 
271 holgerb 801
        #define LIMITS(value, min, max) {min = (80 * value)/100; max = (120 * value)/100;}
243 killagreg 802
        u32 time;
253 killagreg 803
        s32 XMin = 0, XMax = 0, YMin = 0, YMax = 0, ZMin = 0, ZMax = 0;
804
        s16 xscale, yscale, zscale, scale_min, scale_max;
805
        u8 crb_gain, cra_rate;
806
        u8 i = 0, retval = 1;
243 killagreg 807
 
394 killagreg 808
        switch(NCMAG_SensorType)
253 killagreg 809
        {
394 killagreg 810
                case TYPE_HMC5843:
339 holgerb 811
                        crb_gain = HMC5843_CRB_GAIN_15GA;
253 killagreg 812
                        cra_rate = HMC5843_CRA_RATE_50HZ;
813
                        xscale = HMC5843_TEST_XSCALE;
814
                        yscale = HMC5843_TEST_YSCALE;
815
                        zscale = HMC5843_TEST_ZSCALE;
816
                        break;
817
 
394 killagreg 818
                case TYPE_LSM303DLH:
338 holgerb 819
                        crb_gain = LSM303DLH_CRB_GAIN_19GA;
253 killagreg 820
                        cra_rate = LSM303DLH_CRA_RATE_75HZ;
821
                        xscale = LSM303DLH_TEST_XSCALE;
822
                        yscale = LSM303DLH_TEST_YSCALE;
823
                        zscale = LSM303DLH_TEST_ZSCALE;
824
                        break;
825
 
394 killagreg 826
                case TYPE_LSM303DLM:
827
                        // does not support self test feature 
828
                        done = retval;
829
                        return(retval);
830
                        break;
831
 
253 killagreg 832
                default:
394 killagreg 833
                        return(0);
253 killagreg 834
        }
835
 
836
        MagConfig.cra = cra_rate|CRA_MODE_POSBIAS;
837
        MagConfig.crb = crb_gain;
838
        MagConfig.mode = MODE_CONTINUOUS;
839
        // activate positive bias field
840
        NCMAG_SetMagConfig();
251 killagreg 841
        // wait for stable readings
842
        time = SetDelay(50);
843
        while(!CheckDelay(time));
243 killagreg 844
        // averaging
253 killagreg 845
        #define AVERAGE 20
846
        for(i = 0; i<AVERAGE; i++)
243 killagreg 847
        {
253 killagreg 848
                NCMAG_GetMagVector();
243 killagreg 849
                time = SetDelay(20);
850
        while(!CheckDelay(time));
254 killagreg 851
                XMax += MagRawVector.X;
852
                YMax += MagRawVector.Y;
853
                ZMax += MagRawVector.Z;
243 killagreg 854
        }
253 killagreg 855
        MagConfig.cra = cra_rate|CRA_MODE_NEGBIAS;
856
        // activate positive bias field
857
        NCMAG_SetMagConfig();
251 killagreg 858
    // wait for stable readings
859
        time = SetDelay(50);
860
        while(!CheckDelay(time));
243 killagreg 861
        // averaging
253 killagreg 862
        for(i = 0; i < AVERAGE; i++)
243 killagreg 863
        {
253 killagreg 864
                NCMAG_GetMagVector();
243 killagreg 865
                time = SetDelay(20);
866
        while(!CheckDelay(time));
254 killagreg 867
                XMin += MagRawVector.X;
868
                YMin += MagRawVector.Y;
869
                ZMin += MagRawVector.Z;
243 killagreg 870
        }
871
        // setup final configuration
253 killagreg 872
        MagConfig.cra = cra_rate|CRA_MODE_NORMAL;
873
        // activate positive bias field
874
        NCMAG_SetMagConfig();
266 holgerb 875
        // check scale for all axes
243 killagreg 876
        // prepare scale limits
253 killagreg 877
        LIMITS(xscale, scale_min, scale_max);
267 holgerb 878
        xscale = (XMax - XMin)/(2*AVERAGE);
266 holgerb 879
        if((xscale > scale_max) || (xscale < scale_min))
394 killagreg 880
    {
881
                retval = 0;
882
        sprintf(msg, "\r\n Value X: %d not %d-%d !", xscale, scale_min,scale_max);
883
                UART1_PutString(msg);
884
    }
267 holgerb 885
        LIMITS(yscale, scale_min, scale_max);
266 holgerb 886
        yscale = (YMax - YMin)/(2*AVERAGE);
887
        if((yscale > scale_max) || (yscale < scale_min))
394 killagreg 888
    {
889
                retval = 0;
890
        sprintf(msg, "\r\n Value Y: %d not %d-%d !", yscale, scale_min,scale_max);
891
                UART1_PutString(msg);
892
    }
267 holgerb 893
        LIMITS(zscale, scale_min, scale_max);
266 holgerb 894
        zscale = (ZMax - ZMin)/(2*AVERAGE);
895
        if((zscale > scale_max) || (zscale < scale_min))      
394 killagreg 896
        {
897
                retval = 0;
898
        sprintf(msg, "\r\n Value Z: %d not %d-%d !", zscale, scale_min,scale_max);
899
                UART1_PutString(msg);
900
    }
275 killagreg 901
        done = retval;
253 killagreg 902
        return(retval);
243 killagreg 903
}
904
 
905
 
906
//----------------------------------------------------------------
253 killagreg 907
u8 NCMAG_Init(void)
242 killagreg 908
{
909
        u8 msg[64];
252 killagreg 910
        u8 retval = 0;
242 killagreg 911
        u8 repeat;
912
 
253 killagreg 913
        NCMAG_Present = 0;
394 killagreg 914
        NCMAG_SensorType = TYPE_HMC5843;        // assuming having an HMC5843
915
        // polling for LSM302DLH/DLM option by ACC address ack
253 killagreg 916
        repeat = 0;
917
        do
918
        {
919
                retval = NCMAG_GetAccConfig();
920
                if(retval) break; // break loop on success
921
                UART1_PutString(".");
922
                repeat++;
923
        }while(repeat < 3);
394 killagreg 924
        if(retval)
242 killagreg 925
        {
394 killagreg 926
                // initialize ACC sensor
927
                NCMAG_Init_ACCSensor();
928
 
929
                NCMAG_SensorType = TYPE_LSM303DLH;     
930
                // polling of sub identification
931
                repeat = 0;
932
                do
933
                {
934
                        retval = NCMAG_GetIdentification_Sub();
935
                        if(retval) break; // break loop on success
936
                        UART1_PutString(".");
937
                        repeat++;
938
                }while(repeat < 12);
939
                if(retval)
940
                {
941
                        if(NCMAG_Identification2.Sub == MAG_IDF_LSM303DLM)      NCMAG_SensorType = TYPE_LSM303DLM;
942
                }      
943
        }
944
        // get id bytes
329 holgerb 945
        retval = 0;
946
        do
947
        {
253 killagreg 948
                retval = NCMAG_GetIdentification();
252 killagreg 949
                if(retval) break; // break loop on success
242 killagreg 950
                UART1_PutString(".");
951
                repeat++;
252 killagreg 952
        }while(repeat < 12);
329 holgerb 953
 
253 killagreg 954
        // if we got an answer to id request
252 killagreg 955
        if(retval)
242 killagreg 956
        {
329 holgerb 957
                u8 n1[] = "\n\r HMC5843";
958
                u8 n2[] = "\n\r LSM303DLH";
959
                u8 n3[] = "\n\r LSM303DLM";
394 killagreg 960
                u8* pn = n1;
329 holgerb 961
 
394 killagreg 962
                switch(NCMAG_SensorType)
329 holgerb 963
                {
394 killagreg 964
                        case TYPE_HMC5843:
965
                                pn = n1;
966
                                break;
967
                        case TYPE_LSM303DLH:
968
                                pn = n2;
969
                                break;
970
                        case TYPE_LSM303DLM:
971
                                pn = n3;
972
                                break;
329 holgerb 973
                }
974
 
975
                sprintf(msg, " %s ID 0x%02x/%02x/%02x-%02x", pn, NCMAG_Identification.A, NCMAG_Identification.B, NCMAG_Identification.C,NCMAG_Identification2.Sub);
242 killagreg 976
                UART1_PutString(msg);
253 killagreg 977
                if (    (NCMAG_Identification.A == MAG_IDA)
978
                     && (NCMAG_Identification.B == MAG_IDB)
979
                         && (NCMAG_Identification.C == MAG_IDC))
242 killagreg 980
                {
268 killagreg 981
                        NCMAG_Present = 1;
329 holgerb 982
 
983
                        if(EEPROM_Init())
394 killagreg 984
                        {
985
                                NCMAG_IsCalibrated = NCMag_CalibrationRead();
986
                                if(!NCMAG_IsCalibrated) UART1_PutString("\r\n Not calibrated!");
987
                        }
329 holgerb 988
                        else UART1_PutString("\r\n EEPROM data not available!!!!!!!!!!!!!!!");
394 killagreg 989
                        // perform self test
990
                        if(!NCMAG_SelfTest())
991
                        {
329 holgerb 992
                                UART1_PutString("\r\n Selftest failed!!!!!!!!!!!!!!!!!!!!\r\n");
993
                                LED_RED_ON;
994
                                NCMAG_IsCalibrated = 0;
394 killagreg 995
                        }
996
                        else UART1_PutString("\r\n Selftest ok");
997
 
998
                        // initialize magnetic sensor configuration
999
                        InitNC_MagnetSensor();
242 killagreg 1000
                }
1001
                else
1002
                {
254 killagreg 1003
                        UART1_PutString("\n\r Not compatible!");
256 killagreg 1004
                        UART_VersionInfo.HardwareError[0] |= NC_ERROR0_COMPASS_INCOMPATIBLE;
242 killagreg 1005
                        LED_RED_ON;
1006
                }
1007
        }
253 killagreg 1008
        else // nothing found
1009
        {
394 killagreg 1010
                NCMAG_SensorType = TYPE_NONE;
253 killagreg 1011
                UART1_PutString("not found!");  
1012
        }
1013
        return(NCMAG_Present);
242 killagreg 1014
}
1015