Subversion Repositories NaviCtrl

Rev

Rev 454 | Rev 469 | 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"
465 ingob 62
#include "i2c0.h"
63
 
242 killagreg 64
#include "timer1.h"
65
#include "led.h"
66
#include "uart1.h"
254 killagreg 67
#include "eeprom.h"
256 killagreg 68
#include "mymath.h"
292 killagreg 69
#include "main.h"
454 holgerb 70
#include "spi_slave.h"
242 killagreg 71
 
253 killagreg 72
u8 NCMAG_Present = 0;
254 killagreg 73
u8 NCMAG_IsCalibrated = 0;
242 killagreg 74
 
465 ingob 75
u8 *I2C_BufferPnt;
76
u8 *I2C_ErrorPnt;
77
I2C_TransmissionFunc_t                          I2C_TransmissionFunc;
78
I2C_LockBufferFunc_t                            I2C_LockBufferFunc;
79
I2C_WaitForEndOfTransmissionFunc_t      I2C_WaitForEndOfTransmissionFunc;
80
 
81
 
394 killagreg 82
// supported magnetic sensor types
83
#define TYPE_NONE                       0
84
#define TYPE_HMC5843            1
85
#define TYPE_LSM303DLH          2
86
#define TYPE_LSM303DLM          3
242 killagreg 87
 
394 killagreg 88
u8 NCMAG_SensorType = TYPE_NONE;
89
 
90
#define EEPROM_ADR_MAG_CALIBRATION              50
338 holgerb 91
#define CALIBRATION_VERSION                     1
394 killagreg 92
#define MAG_CALIBRATION_COMPATIBLE              0xA2
254 killagreg 93
 
256 killagreg 94
#define NCMAG_MIN_RAWVALUE -2047
95
#define NCMAG_MAX_RAWVALUE  2047
96
#define NCMAG_INVALID_DATA -4096
97
 
254 killagreg 98
typedef struct
99
{
100
        s16 Range;
101
        s16 Offset;
256 killagreg 102
} __attribute__((packed)) Scaling_t;
254 killagreg 103
 
104
typedef struct
105
{
106
        Scaling_t MagX;
107
        Scaling_t MagY;
108
        Scaling_t MagZ;
109
        u8 Version;
110
        u8 crc;
256 killagreg 111
} __attribute__((packed)) Calibration_t;
254 killagreg 112
 
113
Calibration_t Calibration;              // calibration data in RAM 
339 holgerb 114
volatile s16vec_t AccRawVector;
115
volatile s16vec_t MagRawVector;
254 killagreg 116
 
253 killagreg 117
// i2c MAG interface
118
#define MAG_SLAVE_ADDRESS       0x3C    // i2C slave address mag. sensor registers
242 killagreg 119
 
253 killagreg 120
// register mapping
121
#define REG_MAG_CRA                     0x00
122
#define REG_MAG_CRB                     0x01
123
#define REG_MAG_MODE            0x02
124
#define REG_MAG_DATAX_MSB       0x03
125
#define REG_MAG_DATAX_LSB       0x04
126
#define REG_MAG_DATAY_MSB       0x05
127
#define REG_MAG_DATAY_LSB       0x06
128
#define REG_MAG_DATAZ_MSB       0x07
129
#define REG_MAG_DATAZ_LSB       0x08
130
#define REG_MAG_STATUS          0x09
329 holgerb 131
 
253 killagreg 132
#define REG_MAG_IDA                     0x0A
133
#define REG_MAG_IDB                     0x0B
134
#define REG_MAG_IDC                     0x0C
394 killagreg 135
#define REG_MAG_IDF                     0x0F  // WHO_AM_I _M = 0x03c when LSM303DLM is connected
242 killagreg 136
 
253 killagreg 137
// bit mask for configuration mode
138
#define CRA_MODE_MASK           0x03
139
#define CRA_MODE_NORMAL         0x00    //default
140
#define CRA_MODE_POSBIAS        0x01
141
#define CRA_MODE_NEGBIAS        0x02
142
#define CRA_MODE_SELFTEST       0x03
242 killagreg 143
 
253 killagreg 144
// bit mask for measurement mode
145
#define MODE_MASK                       0xFF
146
#define MODE_CONTINUOUS         0x00
147
#define MODE_SINGLE                     0x01    // default
148
#define MODE_IDLE                       0x02
149
#define MODE_SLEEP                      0x03
150
 
242 killagreg 151
// bit mask for rate
253 killagreg 152
#define CRA_RATE_MASK           0x1C
153
 
154
// bit mask for gain
155
#define CRB_GAIN_MASK           0xE0
156
 
157
// ids
158
#define MAG_IDA         0x48
159
#define MAG_IDB         0x34
160
#define MAG_IDC         0x33
394 killagreg 161
#define MAG_IDF_LSM303DLM       0x3C
253 killagreg 162
 
163
// the special HMC5843 interface
164
// bit mask for rate
242 killagreg 165
#define HMC5843_CRA_RATE_0_5HZ          0x00
166
#define HMC5843_CRA_RATE_1HZ            0x04
167
#define HMC5843_CRA_RATE_2HZ            0x08
168
#define HMC5843_CRA_RATE_5HZ            0x0C
169
#define HMC5843_CRA_RATE_10HZ           0x10    //default
170
#define HMC5843_CRA_RATE_20HZ           0x14
171
#define HMC5843_CRA_RATE_50HZ           0x18
172
// bit mask for gain
173
#define HMC5843_CRB_GAIN_07GA           0x00
174
#define HMC5843_CRB_GAIN_10GA           0x20    //default
339 holgerb 175
#define HMC5843_CRB_GAIN_15GA           0x40    // <--- we use this     
242 killagreg 176
#define HMC5843_CRB_GAIN_20GA           0x60
177
#define HMC5843_CRB_GAIN_32GA           0x80
178
#define HMC5843_CRB_GAIN_38GA           0xA0
179
#define HMC5843_CRB_GAIN_45GA           0xC0
180
#define HMC5843_CRB_GAIN_65GA           0xE0
253 killagreg 181
// self test value
339 holgerb 182
#define HMC5843_TEST_XSCALE             555
183
#define HMC5843_TEST_YSCALE             555
184
#define HMC5843_TEST_ZSCALE             555
394 killagreg 185
// calibration range
342 holgerb 186
#define HMC5843_CALIBRATION_RANGE   600
242 killagreg 187
 
253 killagreg 188
// the special LSM302DLH interface
189
// bit mask for rate
190
#define LSM303DLH_CRA_RATE_0_75HZ       0x00
191
#define LSM303DLH_CRA_RATE_1_5HZ        0x04
192
#define LSM303DLH_CRA_RATE_3_0HZ        0x08
193
#define LSM303DLH_CRA_RATE_7_5HZ        0x0C
194
#define LSM303DLH_CRA_RATE_15HZ         0x10    //default
195
#define LSM303DLH_CRA_RATE_30HZ         0x14
196
#define LSM303DLH_CRA_RATE_75HZ         0x18
338 holgerb 197
 
253 killagreg 198
// bit mask for gain
199
#define LSM303DLH_CRB_GAIN_XXGA         0x00
200
#define LSM303DLH_CRB_GAIN_13GA         0x20    //default
339 holgerb 201
#define LSM303DLH_CRB_GAIN_19GA         0x40    // <--- we use this
253 killagreg 202
#define LSM303DLH_CRB_GAIN_25GA         0x60
203
#define LSM303DLH_CRB_GAIN_40GA         0x80
204
#define LSM303DLH_CRB_GAIN_47GA         0xA0
205
#define LSM303DLH_CRB_GAIN_56GA         0xC0
206
#define LSM303DLH_CRB_GAIN_81GA         0xE0
394 killagreg 207
 
208
typedef struct
209
{
210
        u8 A;
211
        u8 B;
212
        u8 C;
213
} __attribute__((packed)) Identification_t;
214
volatile Identification_t NCMAG_Identification;
215
 
216
typedef struct
217
{
218
        u8 Sub;
219
} __attribute__((packed)) Identification2_t;
220
volatile Identification2_t NCMAG_Identification2;
221
 
222
typedef struct
223
{
224
        u8 cra;
225
        u8 crb;
226
        u8 mode;
227
} __attribute__((packed)) MagConfig_t;
228
 
229
volatile MagConfig_t MagConfig;
230
 
231
 
465 ingob 232
 
233
 
234
 
253 killagreg 235
// self test value
338 holgerb 236
#define LSM303DLH_TEST_XSCALE   495
237
#define LSM303DLH_TEST_YSCALE   495
238
#define LSM303DLH_TEST_ZSCALE   470
339 holgerb 239
// clibration range
342 holgerb 240
#define LSM303_CALIBRATION_RANGE   550
253 killagreg 241
 
242
// the i2c ACC interface
243
#define ACC_SLAVE_ADDRESS               0x30    // i2c slave for acc. sensor registers
394 killagreg 244
 
245
// multiple byte read/write mask
246
#define REG_ACC_MASK_AUTOINCREMENT 0x80
247
 
253 killagreg 248
// register mapping
249
#define REG_ACC_CTRL1                   0x20
250
#define REG_ACC_CTRL2                   0x21
251
#define REG_ACC_CTRL3                   0x22
252
#define REG_ACC_CTRL4                   0x23
253
#define REG_ACC_CTRL5                   0x24
254
#define REG_ACC_HP_FILTER_RESET 0x25
255
#define REG_ACC_REFERENCE               0x26
256
#define REG_ACC_STATUS                  0x27
257
#define REG_ACC_X_LSB                   0x28
258
#define REG_ACC_X_MSB                   0x29
259
#define REG_ACC_Y_LSB                   0x2A
260
#define REG_ACC_Y_MSB                   0x2B
261
#define REG_ACC_Z_LSB                   0x2C
262
#define REG_ACC_Z_MSB                   0x2D
263
 
394 killagreg 264
#define ACC_CRTL1_PM_DOWN               0x00
265
#define ACC_CRTL1_PM_NORMAL             0x20
266
#define ACC_CRTL1_PM_LOW_0_5HZ  0x40
267
#define ACC_CRTL1_PM_LOW_1HZ    0x60
268
#define ACC_CRTL1_PM_LOW_2HZ    0x80
269
#define ACC_CRTL1_PM_LOW_5HZ    0xA0
270
#define ACC_CRTL1_PM_LOW_10HZ   0xC0
271
// Output data rate in normal power mode
272
#define ACC_CRTL1_DR_50HZ               0x00
273
#define ACC_CRTL1_DR_100HZ              0x08
274
#define ACC_CRTL1_DR_400HZ              0x10
275
#define ACC_CRTL1_DR_1000HZ             0x18
276
// axis anable flags                    
277
#define ACC_CRTL1_XEN                   0x01
278
#define ACC_CRTL1_YEN                   0x02
279
#define ACC_CRTL1_ZEN                   0x04
253 killagreg 280
 
397 holgerb 281
#define ACC_CRTL2_FILTER8       0x10
282
#define ACC_CRTL2_FILTER16      0x11
283
#define ACC_CRTL2_FILTER32      0x12
284
#define ACC_CRTL2_FILTER64      0x13
395 holgerb 285
 
394 killagreg 286
#define ACC_CTRL4_BDU                   0x80 // Block data update, (0: continuos update; 1: output registers not updated between MSB and LSB reading)
287
#define ACC_CTRL4_BLE                   0x40 // Big/little endian, (0: data LSB @ lower address; 1: data MSB @ lower address)
288
#define ACC_CTRL4_FS_2G                 0x00
289
#define ACC_CTRL4_FS_4G                 0x10
290
#define ACC_CTRL4_FS_8G                 0x30
291
#define ACC_CTRL4_STSIGN_PLUS   0x00
292
#define ACC_CTRL4_STSIGN_MINUS  0x08
293
#define ACC_CTRL4_ST_ENABLE             0x02
253 killagreg 294
 
394 killagreg 295
#define ACC_CTRL5_STW_ON                0x03
296
#define ACC_CTRL5_STW_OFF               0x00
242 killagreg 297
 
253 killagreg 298
typedef struct
299
{
300
        u8 ctrl_1;
301
        u8 ctrl_2;
302
        u8 ctrl_3;
303
        u8 ctrl_4;
304
        u8 ctrl_5;
305
} __attribute__((packed)) AccConfig_t;
306
 
307
volatile AccConfig_t AccConfig;
308
 
254 killagreg 309
u8 NCMag_CalibrationWrite(void)
310
{
394 killagreg 311
        u8 i, crc = MAG_CALIBRATION_COMPATIBLE;
254 killagreg 312
        EEPROM_Result_t eres;
313
        u8 *pBuff = (u8*)&Calibration;
314
 
315
        Calibration.Version = CALIBRATION_VERSION;
256 killagreg 316
        for(i = 0; i<(sizeof(Calibration)-1); i++)
254 killagreg 317
        {
318
                crc += pBuff[i];        
319
        }
320
        Calibration.crc = ~crc;
321
        eres = EEPROM_WriteBlock(EEPROM_ADR_MAG_CALIBRATION, pBuff, sizeof(Calibration));
322
        if(EEPROM_SUCCESS == eres) i = 1;
323
        else i = 0;
324
        return(i);     
325
}
326
 
327
u8 NCMag_CalibrationRead(void)
328
{
394 killagreg 329
        u8 i, crc = MAG_CALIBRATION_COMPATIBLE;
254 killagreg 330
        u8 *pBuff = (u8*)&Calibration;
331
 
332
        if(EEPROM_SUCCESS == EEPROM_ReadBlock(EEPROM_ADR_MAG_CALIBRATION, pBuff, sizeof(Calibration)))
333
        {
256 killagreg 334
                for(i = 0; i<(sizeof(Calibration)-1); i++)
254 killagreg 335
                {
336
                        crc += pBuff[i];        
337
                }
338
                crc = ~crc;
339
                if(Calibration.crc != crc) return(0); // crc mismatch
257 killagreg 340
                if(Calibration.Version == CALIBRATION_VERSION) return(1);
254 killagreg 341
        }
342
        return(0);
343
}
344
 
345
 
346
void NCMAG_Calibrate(void)
347
{
330 holgerb 348
        u8 msg[64];
454 holgerb 349
        static u8 speak = 0;
254 killagreg 350
        static s16 Xmin = 0, Xmax = 0, Ymin = 0, Ymax = 0, Zmin = 0, Zmax = 0;
256 killagreg 351
        static s16 X = 0, Y = 0, Z = 0;
254 killagreg 352
        static u8 OldCalState = 0;     
394 killagreg 353
        s16 MinCalibration = 450;
254 killagreg 354
 
256 killagreg 355
        X = (4*X + MagRawVector.X + 3)/5;
356
        Y = (4*Y + MagRawVector.Y + 3)/5;
357
        Z = (4*Z + MagRawVector.Z + 3)/5;
358
 
254 killagreg 359
        switch(Compass_CalState)
360
        {
361
                case 1:
362
                        // 1st step of calibration
363
                        // initialize ranges
364
                        // used to change the orientation of the NC in the horizontal plane
365
                        Xmin =  10000;
366
                        Xmax = -10000;
367
                        Ymin =  10000;
368
                        Ymax = -10000;
369
                        Zmin =  10000;
370
                        Zmax = -10000;
454 holgerb 371
                        speak = 1;
254 killagreg 372
                        break;
373
 
374
                case 2: // 2nd step of calibration
375
                        // find Min and Max of the X- and Y-Sensors during rotation in the horizontal plane
275 killagreg 376
                        if(X < Xmin)            { Xmin = X; BeepTime = 20;}
377
                        else if(X > Xmax)       { Xmax = X; BeepTime = 20;}
378
                        if(Y < Ymin)            { Ymin = Y; BeepTime = 60;}
379
                        else if(Y > Ymax)       { Ymax = Y; BeepTime = 60;}
454 holgerb 380
                        if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0;
254 killagreg 381
                        break;
382
 
383
                case 3: // 3rd step of calibration
384
                        // used to change the orientation of the MK3MAG vertical to the horizontal plane
454 holgerb 385
                        speak = 1;
254 killagreg 386
                        break;
387
 
388
                case 4:
389
                        // find Min and Max of the Z-Sensor
275 killagreg 390
                        if(Z < Zmin)      { Zmin = Z; BeepTime = 80;}
391
                        else if(Z > Zmax) { Zmax = Z; BeepTime = 80;}
454 holgerb 392
                        if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0;
254 killagreg 393
                        break;
394
 
395
                case 5:
396
                        // Save values
397
                        if(Compass_CalState != OldCalState) // avoid continously writing of eeprom!
398
                        {
394 killagreg 399
                                switch(NCMAG_SensorType)
400
                                {
401
                                        case TYPE_HMC5843:
402
                                                UART1_PutString("\r\nHMC5843 calibration\n\r");
403
                                                MinCalibration = HMC5843_CALIBRATION_RANGE;
404
                                                break;
405
 
406
                                        case TYPE_LSM303DLH:
407
                                        case TYPE_LSM303DLM:
408
                                                UART1_PutString("\r\n\r\nLSM303 calibration\n\r");
409
                                                MinCalibration = LSM303_CALIBRATION_RANGE;
410
                                        break;
411
                                }
342 holgerb 412
                                if(EarthMagneticStrengthTheoretic)
413
                                 {
394 killagreg 414
                                  MinCalibration = (MinCalibration * EarthMagneticStrengthTheoretic) / 50;
342 holgerb 415
                                  sprintf(msg, "Earth field on your location should be: %iuT\r\n",EarthMagneticStrengthTheoretic);
416
                                  UART1_PutString(msg);
417
                                 }
418
                            else UART1_PutString("without GPS\n\r");
339 holgerb 419
 
254 killagreg 420
                                Calibration.MagX.Range = Xmax - Xmin;
421
                                Calibration.MagX.Offset = (Xmin + Xmax) / 2;
422
                                Calibration.MagY.Range = Ymax - Ymin;
423
                                Calibration.MagY.Offset = (Ymin + Ymax) / 2;
424
                                Calibration.MagZ.Range = Zmax - Zmin;
425
                                Calibration.MagZ.Offset = (Zmin + Zmax) / 2;
394 killagreg 426
                                if((Calibration.MagX.Range > MinCalibration) && (Calibration.MagY.Range > MinCalibration) && (Calibration.MagZ.Range > MinCalibration))
254 killagreg 427
                                {
428
                                        NCMAG_IsCalibrated = NCMag_CalibrationWrite();
270 killagreg 429
                                        BeepTime = 2500;
342 holgerb 430
                                        UART1_PutString("\r\n-> Calibration okay <-\n\r");
454 holgerb 431
SpeakHoTT = SPEAK_MIKROKOPTER;
254 killagreg 432
                                }
433
                                else
434
                                {
454 holgerb 435
SpeakHoTT = SPEAK_ERR_CALIBARTION;
339 holgerb 436
                                        UART1_PutString("\r\nCalibration FAILED - Values too low: ");
394 killagreg 437
                                    if(Calibration.MagX.Range < MinCalibration) UART1_PutString("X! ");
438
                                    if(Calibration.MagY.Range < MinCalibration) UART1_PutString("Y! ");
439
                                    if(Calibration.MagZ.Range < MinCalibration) UART1_PutString("Z! ");
330 holgerb 440
                                        UART1_PutString("\r\n");
339 holgerb 441
 
254 killagreg 442
                                        // restore old calibration data from eeprom
443
                                        NCMAG_IsCalibrated = NCMag_CalibrationRead();
444
                                }
330 holgerb 445
                                        sprintf(msg, "X: (%i - %i = %i)\r\n",Xmax,Xmin,Xmax - Xmin);
446
                                        UART1_PutString(msg);
447
                                        sprintf(msg, "Y: (%i - %i = %i)\r\n",Ymax,Ymin,Ymax - Ymin);
448
                                        UART1_PutString(msg);
449
                                        sprintf(msg, "Z: (%i - %i = %i)\r\n",Zmax,Zmin,Zmax - Zmin);
450
                                        UART1_PutString(msg);
394 killagreg 451
                                        sprintf(msg, "(Minimum ampilitude is: %i)\r\n",MinCalibration);
342 holgerb 452
                                        UART1_PutString(msg);
254 killagreg 453
                        }
454
                        break;
455
 
456
                default:
457
                        break; 
458
        }
459
        OldCalState = Compass_CalState;
460
}
461
 
242 killagreg 462
// ---------- call back handlers -----------------------------------------
463
 
464
// rx data handler for id info request
253 killagreg 465
void NCMAG_UpdateIdentification(u8* pRxBuffer, u8 RxBufferSize)
254 killagreg 466
{       // if number of bytes are matching
253 killagreg 467
        if(RxBufferSize == sizeof(NCMAG_Identification) )
242 killagreg 468
        {
253 killagreg 469
                memcpy((u8 *)&NCMAG_Identification, pRxBuffer, sizeof(NCMAG_Identification));
470
        }
242 killagreg 471
}
329 holgerb 472
 
473
void NCMAG_UpdateIdentification_Sub(u8* pRxBuffer, u8 RxBufferSize)
474
{       // if number of bytes are matching
475
        if(RxBufferSize == sizeof(NCMAG_Identification2))
476
        {
477
                memcpy((u8 *)&NCMAG_Identification2, pRxBuffer, sizeof(NCMAG_Identification2));
478
        }
479
}
480
 
254 killagreg 481
// rx data handler for magnetic sensor raw data
253 killagreg 482
void NCMAG_UpdateMagVector(u8* pRxBuffer, u8 RxBufferSize)
254 killagreg 483
{       // if number of bytes are matching
484
        if(RxBufferSize == sizeof(MagRawVector) )
243 killagreg 485
        {       // byte order from big to little endian
256 killagreg 486
                s16 raw;
487
                raw = pRxBuffer[0]<<8;
488
                raw+= pRxBuffer[1];
489
                if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) MagRawVector.X = raw;
490
                raw = pRxBuffer[2]<<8;
491
                raw+= pRxBuffer[3];
330 holgerb 492
            if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE)
493
                {
394 killagreg 494
                        if(NCMAG_SensorType == TYPE_LSM303DLM)  MagRawVector.Z = raw; // here Z and Y are exchanged
495
                        else                                                                    MagRawVector.Y = raw;
330 holgerb 496
                }
256 killagreg 497
                raw = pRxBuffer[4]<<8;
498
                raw+= pRxBuffer[5];
330 holgerb 499
                if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE)
500
                {
394 killagreg 501
                        if(NCMAG_SensorType == TYPE_LSM303DLM)  MagRawVector.Y = raw; // here Z and Y are exchanged
502
                        else                                                                    MagRawVector.Z = raw;
330 holgerb 503
                }
242 killagreg 504
        }
254 killagreg 505
        if(Compass_CalState || !NCMAG_IsCalibrated)
284 killagreg 506
        {       // mark out data invalid
289 killagreg 507
                MagVector.X = MagRawVector.X;
508
                MagVector.Y = MagRawVector.Y;
509
                MagVector.Z = MagRawVector.Z;
254 killagreg 510
                Compass_Heading = -1;
511
        }
512
        else
513
        {
514
                // update MagVector from MagRaw Vector by Scaling
515
                MagVector.X = (s16)((1024L*(s32)(MagRawVector.X - Calibration.MagX.Offset))/Calibration.MagX.Range);
516
                MagVector.Y = (s16)((1024L*(s32)(MagRawVector.Y - Calibration.MagY.Offset))/Calibration.MagY.Range);
517
                MagVector.Z = (s16)((1024L*(s32)(MagRawVector.Z - Calibration.MagZ.Offset))/Calibration.MagZ.Range);
292 killagreg 518
                Compass_CalcHeading();
254 killagreg 519
        }
242 killagreg 520
}
254 killagreg 521
// rx data handler  for acceleration raw data
253 killagreg 522
void NCMAG_UpdateAccVector(u8* pRxBuffer, u8 RxBufferSize)
523
{       // if number of byte are matching
397 holgerb 524
static s32 filter_z;
254 killagreg 525
        if(RxBufferSize == sizeof(AccRawVector) )
253 killagreg 526
        {
254 killagreg 527
                memcpy((u8*)&AccRawVector, pRxBuffer,sizeof(AccRawVector));
253 killagreg 528
        }
416 holgerb 529
//      DebugOut.Analog[16] = AccRawVector.X;
530
//      DebugOut.Analog[17] = AccRawVector.Y;
531
        filter_z = (filter_z * 7 + AccRawVector.Z) / 8;
397 holgerb 532
 
416 holgerb 533
//      DebugOut.Analog[18] = filter_z;
534
//      DebugOut.Analog[19] = AccRawVector.Z;
253 killagreg 535
}
254 killagreg 536
// rx data handler for reading magnetic sensor configuration
253 killagreg 537
void NCMAG_UpdateMagConfig(u8* pRxBuffer, u8 RxBufferSize)
538
{       // if number of byte are matching
539
        if(RxBufferSize == sizeof(MagConfig) )
540
        {
541
                memcpy((u8*)(&MagConfig), pRxBuffer, sizeof(MagConfig));
542
        }
543
}
254 killagreg 544
// rx data handler for reading acceleration sensor configuration
253 killagreg 545
void NCMAG_UpdateAccConfig(u8* pRxBuffer, u8 RxBufferSize)
546
{       // if number of byte are matching
547
        if(RxBufferSize == sizeof(AccConfig) )
548
        {
549
                memcpy((u8*)&AccConfig, pRxBuffer, sizeof(AccConfig));
550
        }
551
}
254 killagreg 552
//----------------------------------------------------------------------
253 killagreg 553
 
254 killagreg 554
 
555
// ---------------------------------------------------------------------
253 killagreg 556
u8 NCMAG_SetMagConfig(void)
557
{
558
        u8 retval = 0;
559
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 560
        if(I2C_LockBufferFunc(100))
253 killagreg 561
        {
562
                u8 TxBytes = 0;
465 ingob 563
                I2C_BufferPnt[TxBytes++] = REG_MAG_CRA;        
564
                memcpy((u8*)(&I2C_BufferPnt[TxBytes]), (u8*)&MagConfig, sizeof(MagConfig));
253 killagreg 565
                TxBytes += sizeof(MagConfig);
465 ingob 566
                if(I2C_TransmissionFunc(MAG_SLAVE_ADDRESS, TxBytes, 0, 0))
253 killagreg 567
                {
465 ingob 568
                        if(I2C_WaitForEndOfTransmissionFunc(100))
253 killagreg 569
                        {
465 ingob 570
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
253 killagreg 571
                        }
572
                }
573
        }
574
        return(retval);        
575
}
242 killagreg 576
 
253 killagreg 577
// ----------------------------------------------------------------------------------------
578
u8 NCMAG_GetMagConfig(void)
242 killagreg 579
{
253 killagreg 580
        u8 retval = 0;
252 killagreg 581
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 582
        if(I2C_LockBufferFunc(100))
242 killagreg 583
        {
253 killagreg 584
                u8 TxBytes = 0;
465 ingob 585
                I2C_BufferPnt[TxBytes++] = REG_MAG_CRA;
586
                if(I2C_TransmissionFunc(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateMagConfig, sizeof(MagConfig)))
248 killagreg 587
                {
465 ingob 588
                        if(I2C_WaitForEndOfTransmissionFunc(100))
252 killagreg 589
                        {
465 ingob 590
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
252 killagreg 591
                        }
248 killagreg 592
                }
242 killagreg 593
        }
253 killagreg 594
        return(retval);        
242 killagreg 595
}
596
 
597
// ----------------------------------------------------------------------------------------
253 killagreg 598
u8 NCMAG_SetAccConfig(void)
242 killagreg 599
{
252 killagreg 600
        u8 retval = 0;
253 killagreg 601
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 602
        if(I2C_LockBufferFunc(100))
242 killagreg 603
        {
253 killagreg 604
                u8 TxBytes = 0;
465 ingob 605
                I2C_BufferPnt[TxBytes++] = REG_ACC_CTRL1|REG_ACC_MASK_AUTOINCREMENT;    
606
                memcpy((u8*)(&I2C_BufferPnt[TxBytes]), (u8*)&AccConfig, sizeof(AccConfig));
253 killagreg 607
                TxBytes += sizeof(AccConfig);
465 ingob 608
                if(I2C_TransmissionFunc(ACC_SLAVE_ADDRESS, TxBytes, 0, 0))
253 killagreg 609
                {
465 ingob 610
                        if(I2C_WaitForEndOfTransmissionFunc(100))
253 killagreg 611
                        {
465 ingob 612
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
253 killagreg 613
                        }
614
                }
615
        }
616
        return(retval);        
617
}
618
 
619
// ----------------------------------------------------------------------------------------
620
u8 NCMAG_GetAccConfig(void)
621
{
622
        u8 retval = 0;
623
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 624
        if(I2C_LockBufferFunc(100))
253 killagreg 625
        {
626
                u8 TxBytes = 0;
465 ingob 627
                I2C_BufferPnt[TxBytes++] = REG_ACC_CTRL1|REG_ACC_MASK_AUTOINCREMENT;
628
                if(I2C_TransmissionFunc(ACC_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateAccConfig, sizeof(AccConfig)))
253 killagreg 629
                {
465 ingob 630
                        if(I2C_WaitForEndOfTransmissionFunc(100))
253 killagreg 631
                        {
465 ingob 632
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
253 killagreg 633
                        }
634
                }
635
        }
636
        return(retval);        
637
}
638
 
639
// ----------------------------------------------------------------------------------------
640
u8 NCMAG_GetIdentification(void)
641
{
642
        u8 retval = 0;
643
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 644
        if(I2C_LockBufferFunc(100))
253 killagreg 645
        {
646
                u16 TxBytes = 0;
647
                NCMAG_Identification.A = 0xFF;
648
                NCMAG_Identification.B = 0xFF;
649
                NCMAG_Identification.C = 0xFF;
465 ingob 650
                I2C_BufferPnt[TxBytes++] = REG_MAG_IDA;
248 killagreg 651
                // initiate transmission
465 ingob 652
                if(I2C_TransmissionFunc(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateIdentification, sizeof(NCMAG_Identification)))
248 killagreg 653
                {
465 ingob 654
                        if(I2C_WaitForEndOfTransmissionFunc(100))
252 killagreg 655
                        {
465 ingob 656
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
252 killagreg 657
                        }
248 killagreg 658
                }
242 killagreg 659
        }
253 killagreg 660
        return(retval);
242 killagreg 661
}
662
 
329 holgerb 663
u8 NCMAG_GetIdentification_Sub(void)
664
{
665
        u8 retval = 0;
666
        // try to catch the i2c buffer within 100 ms timeout
465 ingob 667
        if(I2C_LockBufferFunc(100))
329 holgerb 668
        {
669
                u16 TxBytes = 0;
670
                NCMAG_Identification2.Sub = 0xFF;
465 ingob 671
                I2C_BufferPnt[TxBytes++] = REG_MAG_IDF;
329 holgerb 672
                // initiate transmission
465 ingob 673
                if(I2C_TransmissionFunc(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateIdentification_Sub, sizeof(NCMAG_Identification2)))
329 holgerb 674
                {
465 ingob 675
                        if(I2C_WaitForEndOfTransmissionFunc(100))
329 holgerb 676
                        {
465 ingob 677
                                if(*I2C_ErrorPnt == I2C_ERROR_NONE) retval = 1;
329 holgerb 678
                        }
679
                }
680
        }
681
        return(retval);
682
}
683
 
684
 
253 killagreg 685
// ----------------------------------------------------------------------------------------
686
void NCMAG_GetMagVector(void)
687
{
688
        // try to catch the I2C buffer within 0 ms
465 ingob 689
        if(I2C_LockBufferFunc(0))
253 killagreg 690
        {
691
                u16 TxBytes = 0;
692
                // set register pointer
465 ingob 693
                I2C_BufferPnt[TxBytes++] = REG_MAG_DATAX_MSB;
253 killagreg 694
                // initiate transmission
465 ingob 695
                I2C_TransmissionFunc(MAG_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateMagVector, sizeof(MagVector));
253 killagreg 696
        }
697
}
698
 
242 killagreg 699
//----------------------------------------------------------------
253 killagreg 700
void NCMAG_GetAccVector(void)
243 killagreg 701
{
252 killagreg 702
        // try to catch the I2C buffer within 0 ms
465 ingob 703
        if(I2C_LockBufferFunc(0))
243 killagreg 704
        {
248 killagreg 705
                u16 TxBytes = 0;
243 killagreg 706
                // set register pointer
465 ingob 707
                I2C_BufferPnt[TxBytes++] = REG_ACC_X_LSB|REG_ACC_MASK_AUTOINCREMENT;
243 killagreg 708
                // initiate transmission
465 ingob 709
                I2C_TransmissionFunc(ACC_SLAVE_ADDRESS, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector));
243 killagreg 710
        }
711
}
712
 
330 holgerb 713
//----------------------------------------------------------------
394 killagreg 714
u8 InitNC_MagnetSensor(void)
330 holgerb 715
{
716
        u8 crb_gain, cra_rate;
717
 
394 killagreg 718
        switch(NCMAG_SensorType)
330 holgerb 719
        {
394 killagreg 720
                case TYPE_HMC5843:
339 holgerb 721
                        crb_gain = HMC5843_CRB_GAIN_15GA;
330 holgerb 722
                        cra_rate = HMC5843_CRA_RATE_50HZ;
723
                        break;
724
 
394 killagreg 725
                case TYPE_LSM303DLH:
726
                case TYPE_LSM303DLM:
338 holgerb 727
                        crb_gain = LSM303DLH_CRB_GAIN_19GA;
330 holgerb 728
                        cra_rate = LSM303DLH_CRA_RATE_75HZ;
729
                        break;
730
 
731
                default:
394 killagreg 732
                return(0);
330 holgerb 733
        }
734
 
735
        MagConfig.cra = cra_rate|CRA_MODE_NORMAL;
736
        MagConfig.crb = crb_gain;
737
        MagConfig.mode = MODE_CONTINUOUS;
394 killagreg 738
        return(NCMAG_SetMagConfig());
330 holgerb 739
}
740
 
395 holgerb 741
 
394 killagreg 742
//----------------------------------------------------------------
743
u8 NCMAG_Init_ACCSensor(void)
744
{
395 holgerb 745
        AccConfig.ctrl_1 = ACC_CRTL1_PM_NORMAL|ACC_CRTL1_DR_50HZ|ACC_CRTL1_XEN|ACC_CRTL1_YEN|ACC_CRTL1_ZEN;
397 holgerb 746
        AccConfig.ctrl_2 = 0;//ACC_CRTL2_FILTER32;
394 killagreg 747
        AccConfig.ctrl_3 = 0x00;
397 holgerb 748
        AccConfig.ctrl_4 = ACC_CTRL4_BDU | ACC_CTRL4_FS_8G;
394 killagreg 749
        AccConfig.ctrl_5 = ACC_CTRL5_STW_OFF;
750
        return(NCMAG_SetAccConfig());
751
}
253 killagreg 752
// --------------------------------------------------------
292 killagreg 753
void NCMAG_Update(void)
243 killagreg 754
{
292 killagreg 755
        static u32 TimerUpdate = 0;
419 holgerb 756
        static s8 send_config = 0;
394 killagreg 757
        u32 delay = 20;
243 killagreg 758
 
254 killagreg 759
        if( (I2C_State == I2C_STATE_OFF) || !NCMAG_Present )
760
        {
761
                Compass_Heading = -1;
326 holgerb 762
                DebugOut.Analog[14]++; // count I2C error
254 killagreg 763
                return;
764
        }
292 killagreg 765
        if(CheckDelay(TimerUpdate))
243 killagreg 766
        {
394 killagreg 767
                if(Compass_Heading != -1) send_config = 0; // no re-configuration if value is valid
768
        if(++send_config == 25)   // 500ms
769
                {
419 holgerb 770
                        send_config = -25;    // next try after 1 second
394 killagreg 771
                InitNC_MagnetSensor();
419 holgerb 772
                        TimerUpdate = SetDelay(20);    // back into the old time-slot
394 killagreg 773
                }
321 holgerb 774
                else
775
                {
398 holgerb 776
//                      static u8 s = 0;
394 killagreg 777
                        // check for new calibration state
778
                        Compass_UpdateCalState();
779
                        if(Compass_CalState) NCMAG_Calibrate();
780
 
781
                        // in case of LSM303 type
782
                        switch(NCMAG_SensorType)
783
                        {
784
                                case TYPE_HMC5843:                             
785
                                        NCMAG_GetMagVector();
786
                                        delay = 20;
787
                                        break;
788
                                case TYPE_LSM303DLH:
789
                                case TYPE_LSM303DLM:
397 holgerb 790
                                        NCMAG_GetMagVector();
791
                                        delay = 20;
792
/*                                      if(s){ NCMAG_GetMagVector(); s = 0;}
394 killagreg 793
                                        else { NCMAG_GetAccVector(); s = 1;}
794
                                        delay = 10;
397 holgerb 795
*/
394 killagreg 796
                                        break;                           
797
                        }
419 holgerb 798
                        if(send_config == 24) TimerUpdate = SetDelay(15);    // next event is the re-configuration
394 killagreg 799
                        else TimerUpdate = SetDelay(delay);    // every 20 ms are 50 Hz
321 holgerb 800
                }
243 killagreg 801
        }
802
}
803
 
330 holgerb 804
 
254 killagreg 805
// --------------------------------------------------------
253 killagreg 806
u8 NCMAG_SelfTest(void)
243 killagreg 807
{
266 holgerb 808
        u8 msg[64];
275 killagreg 809
        static u8 done = 0;
266 holgerb 810
 
287 holgerb 811
        if(done) return(1);        // just make it once
275 killagreg 812
 
271 holgerb 813
        #define LIMITS(value, min, max) {min = (80 * value)/100; max = (120 * value)/100;}
243 killagreg 814
        u32 time;
253 killagreg 815
        s32 XMin = 0, XMax = 0, YMin = 0, YMax = 0, ZMin = 0, ZMax = 0;
816
        s16 xscale, yscale, zscale, scale_min, scale_max;
817
        u8 crb_gain, cra_rate;
818
        u8 i = 0, retval = 1;
243 killagreg 819
 
394 killagreg 820
        switch(NCMAG_SensorType)
253 killagreg 821
        {
394 killagreg 822
                case TYPE_HMC5843:
339 holgerb 823
                        crb_gain = HMC5843_CRB_GAIN_15GA;
253 killagreg 824
                        cra_rate = HMC5843_CRA_RATE_50HZ;
825
                        xscale = HMC5843_TEST_XSCALE;
826
                        yscale = HMC5843_TEST_YSCALE;
827
                        zscale = HMC5843_TEST_ZSCALE;
828
                        break;
829
 
394 killagreg 830
                case TYPE_LSM303DLH:
338 holgerb 831
                        crb_gain = LSM303DLH_CRB_GAIN_19GA;
253 killagreg 832
                        cra_rate = LSM303DLH_CRA_RATE_75HZ;
833
                        xscale = LSM303DLH_TEST_XSCALE;
834
                        yscale = LSM303DLH_TEST_YSCALE;
835
                        zscale = LSM303DLH_TEST_ZSCALE;
836
                        break;
837
 
394 killagreg 838
                case TYPE_LSM303DLM:
839
                        // does not support self test feature 
840
                        done = retval;
841
                        return(retval);
842
                        break;
843
 
253 killagreg 844
                default:
394 killagreg 845
                        return(0);
253 killagreg 846
        }
847
 
848
        MagConfig.cra = cra_rate|CRA_MODE_POSBIAS;
849
        MagConfig.crb = crb_gain;
850
        MagConfig.mode = MODE_CONTINUOUS;
851
        // activate positive bias field
852
        NCMAG_SetMagConfig();
251 killagreg 853
        // wait for stable readings
854
        time = SetDelay(50);
855
        while(!CheckDelay(time));
243 killagreg 856
        // averaging
253 killagreg 857
        #define AVERAGE 20
858
        for(i = 0; i<AVERAGE; i++)
243 killagreg 859
        {
253 killagreg 860
                NCMAG_GetMagVector();
243 killagreg 861
                time = SetDelay(20);
862
        while(!CheckDelay(time));
254 killagreg 863
                XMax += MagRawVector.X;
864
                YMax += MagRawVector.Y;
865
                ZMax += MagRawVector.Z;
243 killagreg 866
        }
253 killagreg 867
        MagConfig.cra = cra_rate|CRA_MODE_NEGBIAS;
868
        // activate positive bias field
869
        NCMAG_SetMagConfig();
251 killagreg 870
    // wait for stable readings
871
        time = SetDelay(50);
872
        while(!CheckDelay(time));
243 killagreg 873
        // averaging
253 killagreg 874
        for(i = 0; i < AVERAGE; i++)
243 killagreg 875
        {
253 killagreg 876
                NCMAG_GetMagVector();
243 killagreg 877
                time = SetDelay(20);
878
        while(!CheckDelay(time));
254 killagreg 879
                XMin += MagRawVector.X;
880
                YMin += MagRawVector.Y;
881
                ZMin += MagRawVector.Z;
243 killagreg 882
        }
883
        // setup final configuration
253 killagreg 884
        MagConfig.cra = cra_rate|CRA_MODE_NORMAL;
885
        // activate positive bias field
886
        NCMAG_SetMagConfig();
266 holgerb 887
        // check scale for all axes
243 killagreg 888
        // prepare scale limits
253 killagreg 889
        LIMITS(xscale, scale_min, scale_max);
267 holgerb 890
        xscale = (XMax - XMin)/(2*AVERAGE);
266 holgerb 891
        if((xscale > scale_max) || (xscale < scale_min))
394 killagreg 892
    {
893
                retval = 0;
894
        sprintf(msg, "\r\n Value X: %d not %d-%d !", xscale, scale_min,scale_max);
895
                UART1_PutString(msg);
896
    }
267 holgerb 897
        LIMITS(yscale, scale_min, scale_max);
266 holgerb 898
        yscale = (YMax - YMin)/(2*AVERAGE);
899
        if((yscale > scale_max) || (yscale < scale_min))
394 killagreg 900
    {
901
                retval = 0;
902
        sprintf(msg, "\r\n Value Y: %d not %d-%d !", yscale, scale_min,scale_max);
903
                UART1_PutString(msg);
904
    }
267 holgerb 905
        LIMITS(zscale, scale_min, scale_max);
266 holgerb 906
        zscale = (ZMax - ZMin)/(2*AVERAGE);
907
        if((zscale > scale_max) || (zscale < scale_min))      
394 killagreg 908
        {
909
                retval = 0;
910
        sprintf(msg, "\r\n Value Z: %d not %d-%d !", zscale, scale_min,scale_max);
911
                UART1_PutString(msg);
912
    }
275 killagreg 913
        done = retval;
253 killagreg 914
        return(retval);
243 killagreg 915
}
916
 
917
 
918
//----------------------------------------------------------------
465 ingob 919
void NCMAG_SelectI2CBus(u8 busno)
920
{
921
  if (busno == 0)
922
  {
923
    I2C_WaitForEndOfTransmissionFunc = &I2C0_WaitForEndOfTransmission;
924
        I2C_LockBufferFunc = &I2C0_LockBuffer;
925
        I2C_TransmissionFunc = &I2C0_Transmission;
926
        I2C_BufferPnt = I2C0_Buffer;
927
        I2C_ErrorPnt = &I2C0_Error;
928
  }
929
   else
930
  {
931
    I2C_WaitForEndOfTransmissionFunc = &I2C_WaitForEndOfTransmission;
932
        I2C_LockBufferFunc = &I2C_LockBuffer;
933
        I2C_TransmissionFunc = &I2C_Transmission;
934
        I2C_BufferPnt = I2C_Buffer;
935
        I2C_ErrorPnt = &I2C_Error;
936
  }
937
}
938
 
939
//----------------------------------------------------------------
253 killagreg 940
u8 NCMAG_Init(void)
242 killagreg 941
{
942
        u8 msg[64];
252 killagreg 943
        u8 retval = 0;
242 killagreg 944
        u8 repeat;
945
 
465 ingob 946
        NCMAG_SelectI2CBus(0);
947
 
253 killagreg 948
        NCMAG_Present = 0;
394 killagreg 949
        NCMAG_SensorType = TYPE_HMC5843;        // assuming having an HMC5843
950
        // polling for LSM302DLH/DLM option by ACC address ack
253 killagreg 951
        repeat = 0;
952
        do
953
        {
954
                retval = NCMAG_GetAccConfig();
955
                if(retval) break; // break loop on success
465 ingob 956
                UART1_PutString("*");
253 killagreg 957
                repeat++;
958
        }while(repeat < 3);
394 killagreg 959
        if(retval)
242 killagreg 960
        {
394 killagreg 961
                // initialize ACC sensor
962
                NCMAG_Init_ACCSensor();
963
 
964
                NCMAG_SensorType = TYPE_LSM303DLH;     
965
                // polling of sub identification
966
                repeat = 0;
967
                do
968
                {
969
                        retval = NCMAG_GetIdentification_Sub();
970
                        if(retval) break; // break loop on success
971
                        UART1_PutString(".");
972
                        repeat++;
973
                }while(repeat < 12);
974
                if(retval)
975
                {
976
                        if(NCMAG_Identification2.Sub == MAG_IDF_LSM303DLM)      NCMAG_SensorType = TYPE_LSM303DLM;
977
                }      
978
        }
979
        // get id bytes
329 holgerb 980
        retval = 0;
981
        do
982
        {
253 killagreg 983
                retval = NCMAG_GetIdentification();
252 killagreg 984
                if(retval) break; // break loop on success
465 ingob 985
                UART1_PutString("#");
242 killagreg 986
                repeat++;
252 killagreg 987
        }while(repeat < 12);
329 holgerb 988
 
253 killagreg 989
        // if we got an answer to id request
252 killagreg 990
        if(retval)
242 killagreg 991
        {
329 holgerb 992
                u8 n1[] = "\n\r HMC5843";
993
                u8 n2[] = "\n\r LSM303DLH";
994
                u8 n3[] = "\n\r LSM303DLM";
394 killagreg 995
                u8* pn = n1;
329 holgerb 996
 
394 killagreg 997
                switch(NCMAG_SensorType)
329 holgerb 998
                {
394 killagreg 999
                        case TYPE_HMC5843:
1000
                                pn = n1;
1001
                                break;
1002
                        case TYPE_LSM303DLH:
1003
                                pn = n2;
1004
                                break;
1005
                        case TYPE_LSM303DLM:
1006
                                pn = n3;
1007
                                break;
329 holgerb 1008
                }
1009
 
1010
                sprintf(msg, " %s ID 0x%02x/%02x/%02x-%02x", pn, NCMAG_Identification.A, NCMAG_Identification.B, NCMAG_Identification.C,NCMAG_Identification2.Sub);
242 killagreg 1011
                UART1_PutString(msg);
253 killagreg 1012
                if (    (NCMAG_Identification.A == MAG_IDA)
1013
                     && (NCMAG_Identification.B == MAG_IDB)
1014
                         && (NCMAG_Identification.C == MAG_IDC))
242 killagreg 1015
                {
268 killagreg 1016
                        NCMAG_Present = 1;
329 holgerb 1017
 
1018
                        if(EEPROM_Init())
394 killagreg 1019
                        {
1020
                                NCMAG_IsCalibrated = NCMag_CalibrationRead();
1021
                                if(!NCMAG_IsCalibrated) UART1_PutString("\r\n Not calibrated!");
1022
                        }
329 holgerb 1023
                        else UART1_PutString("\r\n EEPROM data not available!!!!!!!!!!!!!!!");
394 killagreg 1024
                        // perform self test
1025
                        if(!NCMAG_SelfTest())
1026
                        {
329 holgerb 1027
                                UART1_PutString("\r\n Selftest failed!!!!!!!!!!!!!!!!!!!!\r\n");
1028
                                LED_RED_ON;
1029
                                NCMAG_IsCalibrated = 0;
394 killagreg 1030
                        }
1031
                        else UART1_PutString("\r\n Selftest ok");
1032
 
1033
                        // initialize magnetic sensor configuration
1034
                        InitNC_MagnetSensor();
242 killagreg 1035
                }
1036
                else
1037
                {
254 killagreg 1038
                        UART1_PutString("\n\r Not compatible!");
256 killagreg 1039
                        UART_VersionInfo.HardwareError[0] |= NC_ERROR0_COMPASS_INCOMPATIBLE;
242 killagreg 1040
                        LED_RED_ON;
1041
                }
1042
        }
253 killagreg 1043
        else // nothing found
1044
        {
394 killagreg 1045
                NCMAG_SensorType = TYPE_NONE;
253 killagreg 1046
                UART1_PutString("not found!");  
1047
        }
1048
        return(NCMAG_Present);
242 killagreg 1049
}
1050