Rev 743 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 743 | Rev 767 | ||
---|---|---|---|
1 | /*#######################################################################################*/ |
1 | /*#######################################################################################*/ |
2 | /* !!! THIS IS NOT FREE SOFTWARE !!! */ |
2 | /* !!! THIS IS NOT FREE SOFTWARE !!! */ |
3 | /*#######################################################################################*/ |
3 | /*#######################################################################################*/ |
4 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
4 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 | // + www.MikroKopter.com |
5 | // + www.MikroKopter.com |
6 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
7 | // + Software Nutzungsbedingungen (english version: see below) |
7 | // + Software Nutzungsbedingungen (english version: see below) |
8 | // + der Fa. HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland - nachfolgend Lizenzgeber genannt - |
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 |
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 |
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. |
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. |
12 | // + Der Einsatz dieser Software ist nur auf oder mit Produkten des Lizenzgebers zulässig. |
13 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
13 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
14 | // + Die vom Lizenzgeber gelieferte Software ist urheberrechtlich geschützt. Alle Rechte an der Software sowie an sonstigen im |
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. |
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 |
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. |
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 |
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. |
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 |
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 |
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. |
22 | // + des Mitverschuldens offen. |
23 | // + Der Kunde trifft angemessene Vorkehrungen für den Fall, dass die Software ganz oder teilweise nicht ordnungsgemäß arbeitet. |
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. |
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. |
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 |
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. |
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. |
28 | // + *) Die räumliche Nutzung bezieht sich nur auf den Einsatzort, nicht auf die Reichweite der programmierten Software. |
29 | // + #### ENDE DER NUTZUNGSBEDINGUNGEN ####' |
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. |
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. |
31 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
31 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
32 | // + Software LICENSING TERMS |
32 | // + Software LICENSING TERMS |
33 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
33 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
34 | // + of HiSystems GmbH, Flachsmeerstrasse 2, 26802 Moormerland, Germany - the Licensor - |
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 |
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*. |
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. |
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 |
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 |
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. |
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 |
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. |
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 |
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 |
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 |
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 |
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. |
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 |
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. |
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 |
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. |
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. |
52 | // + *) The territory aspect only refers to the place where the Software is used, not its programmed range. |
53 | // + #### END OF LICENSING TERMS #### |
53 | // + #### END OF LICENSING TERMS #### |
54 | // + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
54 | // + Note: For information on license extensions (e.g. commercial use), please contact us at info(@)hisystems.de. |
55 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
55 | // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
56 | #include <math.h> |
56 | #include <math.h> |
57 | #include <stdio.h> |
57 | #include <stdio.h> |
58 | #include <stdlib.h> |
58 | #include <stdlib.h> |
59 | #include <string.h> |
59 | #include <string.h> |
60 | #include "91x_lib.h" |
60 | #include "91x_lib.h" |
61 | #include "ncmag.h" |
61 | #include "ncmag.h" |
62 | #include "i2c.h" |
62 | #include "i2c.h" |
63 | #include "timer1.h" |
63 | #include "timer1.h" |
64 | #include "led.h" |
64 | #include "led.h" |
65 | #include "uart1.h" |
65 | #include "uart1.h" |
66 | #include "eeprom.h" |
66 | #include "eeprom.h" |
67 | #include "mymath.h" |
67 | #include "mymath.h" |
68 | #include "main.h" |
68 | #include "main.h" |
69 | #include "spi_slave.h" |
69 | #include "spi_slave.h" |
70 | 70 | ||
71 | u8 NCMAG_Present = 0; |
71 | u8 NCMAG_Present = 0; |
72 | u8 NCMAG_IsCalibrated = 0; |
72 | u8 NCMAG_IsCalibrated = 0; |
73 | u8 NCMAG_SensorType = TYPE_NONE; |
73 | u8 NCMAG_SensorType = TYPE_NONE; |
74 | u8 NCMAG_Orientation = 0; // 0 means unknown! |
74 | u8 NCMAG_Orientation = 0; // 0 means unknown! |
75 | u8 NCMAG_Compass_use_Orientation = 0; |
75 | u8 NCMAG_Compass_use_Orientation = 0; |
76 | 76 | ||
77 | #define CALIBRATION_VERSION 1 |
77 | #define CALIBRATION_VERSION 1 |
78 | #define MAG_CALIBRATION_COMPATIBLE 0xA3 |
78 | #define MAG_CALIBRATION_COMPATIBLE 0xA3 |
79 | 79 | ||
80 | #define NCMAG_MIN_RAWVALUE -2047 |
80 | #define NCMAG_MIN_RAWVALUE -2047 |
81 | #define NCMAG_MAX_RAWVALUE 2047 |
81 | #define NCMAG_MAX_RAWVALUE 2047 |
82 | #define NCMAG_INVALID_DATA -4096 |
82 | #define NCMAG_INVALID_DATA -4096 |
83 | 83 | ||
84 | typedef struct |
84 | typedef struct |
85 | { |
85 | { |
86 | s16 Range; |
86 | s16 Range; |
87 | s16 Offset; |
87 | s16 Offset; |
88 | } __attribute__((packed)) Scaling_t; |
88 | } __attribute__((packed)) Scaling_t; |
89 | 89 | ||
90 | typedef struct |
90 | typedef struct |
91 | { |
91 | { |
92 | Scaling_t MagX; |
92 | Scaling_t MagX; |
93 | Scaling_t MagY; |
93 | Scaling_t MagY; |
94 | Scaling_t MagZ; |
94 | Scaling_t MagZ; |
95 | u8 Version; |
95 | u8 Version; |
96 | u8 crc; |
96 | u8 crc; |
97 | } __attribute__((packed)) Calibration_t; |
97 | } __attribute__((packed)) Calibration_t; |
98 | 98 | ||
99 | Calibration_t Calibration; // calibration data in RAM |
99 | Calibration_t Calibration; // calibration data in RAM |
100 | volatile s16vec_t AccRawVector; |
100 | volatile s16vec_t AccRawVector; |
101 | volatile s16vec_t MagRawVector; |
101 | volatile s16vec_t MagRawVector; |
102 | 102 | ||
103 | // i2c MAG interface |
103 | // i2c MAG interface |
104 | #define MAG_SLAVE_ADDRESS 0x3C // i2C slave address mag. sensor registers |
104 | #define MAG_SLAVE_ADDRESS 0x3C // i2C slave address mag. sensor registers |
105 | 105 | ||
106 | // register mapping |
106 | // register mapping |
107 | #define REG_MAG_CRA 0x00 |
107 | #define REG_MAG_CRA 0x00 |
108 | #define REG_MAG_CRB 0x01 |
108 | #define REG_MAG_CRB 0x01 |
109 | #define REG_MAG_MODE 0x02 |
109 | #define REG_MAG_MODE 0x02 |
110 | #define REG_MAG_DATAX_MSB 0x03 |
110 | #define REG_MAG_DATAX_MSB 0x03 |
111 | #define REG_MAG_DATAX_LSB 0x04 |
111 | #define REG_MAG_DATAX_LSB 0x04 |
112 | #define REG_MAG_DATAY_MSB 0x05 |
112 | #define REG_MAG_DATAY_MSB 0x05 |
113 | #define REG_MAG_DATAY_LSB 0x06 |
113 | #define REG_MAG_DATAY_LSB 0x06 |
114 | #define REG_MAG_DATAZ_MSB 0x07 |
114 | #define REG_MAG_DATAZ_MSB 0x07 |
115 | #define REG_MAG_DATAZ_LSB 0x08 |
115 | #define REG_MAG_DATAZ_LSB 0x08 |
116 | #define REG_MAG_STATUS 0x09 |
116 | #define REG_MAG_STATUS 0x09 |
117 | 117 | ||
118 | #define REG_MAG_IDA 0x0A |
118 | #define REG_MAG_IDA 0x0A |
119 | #define REG_MAG_IDB 0x0B |
119 | #define REG_MAG_IDB 0x0B |
120 | #define REG_MAG_IDC 0x0C |
120 | #define REG_MAG_IDC 0x0C |
121 | #define REG_MAG_IDF 0x0F // WHO_AM_I _M = 0x03c when LSM303DLM is connected |
121 | #define REG_MAG_IDF 0x0F // WHO_AM_I _M = 0x03c when LSM303DLM is connected |
122 | 122 | ||
123 | #define ADR_LSM303D_MAG 0x08 |
123 | #define ADR_LSM303D_MAG 0x08 |
124 | #define REG_303D_CTRL0 0x1F // Fifo + Interrupts |
124 | #define REG_303D_CTRL0 0x1F // Fifo + Interrupts |
125 | #define REG_303D_CTRL1 0x20 // ACC Update Speed |
125 | #define REG_303D_CTRL1 0x20 // ACC Update Speed |
126 | #define REG_303D_CTRL2 0x21 // ACC Gain + Filter |
126 | #define REG_303D_CTRL2 0x21 // ACC Gain + Filter |
127 | #define REG_303D_CTRL3 0x22 // Fifo + Interrupts |
127 | #define REG_303D_CTRL3 0x22 // Fifo + Interrupts |
128 | #define REG_303D_CTRL4 0x23 // Fifo + Interrupts |
128 | #define REG_303D_CTRL4 0x23 // Fifo + Interrupts |
129 | #define REG_303D_CTRL5 0x24 // Temperature Enable + Magn.Resolution + Magn.Rate |
129 | #define REG_303D_CTRL5 0x24 // Temperature Enable + Magn.Resolution + Magn.Rate |
130 | #define REG_303D_CTRL6 0x25 // Magn. Gain |
130 | #define REG_303D_CTRL6 0x25 // Magn. Gain |
131 | #define REG_303D_CTRL7 0x26 // Magn. PowerDown + Filter |
131 | #define REG_303D_CTRL7 0x26 // Magn. PowerDown + Filter |
132 | // bit mask for configuration mode |
132 | // bit mask for configuration mode |
133 | #define CRA_MODE_MASK 0x03 |
133 | #define CRA_MODE_MASK 0x03 |
134 | #define CRA_MODE_NORMAL 0x00 //default |
134 | #define CRA_MODE_NORMAL 0x00 //default |
135 | #define CRA_MODE_POSBIAS 0x01 |
135 | #define CRA_MODE_POSBIAS 0x01 |
136 | #define CRA_MODE_NEGBIAS 0x02 |
136 | #define CRA_MODE_NEGBIAS 0x02 |
137 | #define CRA_MODE_SELFTEST 0x03 |
137 | #define CRA_MODE_SELFTEST 0x03 |
138 | 138 | ||
139 | // bit mask for measurement mode |
139 | // bit mask for measurement mode |
140 | #define MODE_MASK 0xFF |
140 | #define MODE_MASK 0xFF |
141 | #define MODE_CONTINUOUS 0x00 |
141 | #define MODE_CONTINUOUS 0x00 |
142 | #define MODE_SINGLE 0x01 // default |
142 | #define MODE_SINGLE 0x01 // default |
143 | #define MODE_IDLE 0x02 |
143 | #define MODE_IDLE 0x02 |
144 | #define MODE_SLEEP 0x03 |
144 | #define MODE_SLEEP 0x03 |
145 | 145 | ||
146 | // bit mask for rate |
146 | // bit mask for rate |
147 | #define CRA_RATE_MASK 0x1C |
147 | #define CRA_RATE_MASK 0x1C |
148 | 148 | ||
149 | // bit mask for gain |
149 | // bit mask for gain |
150 | #define CRB_GAIN_MASK 0xE0 |
150 | #define CRB_GAIN_MASK 0xE0 |
151 | 151 | ||
152 | // ids |
152 | // ids |
153 | #define MAG_IDA 0x48 |
153 | #define MAG_IDA 0x48 |
154 | #define MAG_IDB 0x34 |
154 | #define MAG_IDB 0x34 |
155 | #define MAG_IDC 0x33 |
155 | #define MAG_IDC 0x33 |
156 | #define MAG_IDF_LSM303DLM 0x3C |
156 | #define MAG_IDF_LSM303DLM 0x3C |
157 | #define MAG_IDF_LSM303D 0x49 |
157 | #define MAG_IDF_LSM303D 0x49 |
158 | #define MAG_IDF_LSM303DLH 0x00 |
158 | #define MAG_IDF_LSM303DLH 0x00 |
159 | 159 | ||
160 | // the special HMC5843 interface |
160 | // the special HMC5843 interface |
161 | // bit mask for rate |
161 | // bit mask for rate |
162 | #define HMC5843_CRA_RATE_0_5HZ 0x00 |
162 | #define HMC5843_CRA_RATE_0_5HZ 0x00 |
163 | #define HMC5843_CRA_RATE_1HZ 0x04 |
163 | #define HMC5843_CRA_RATE_1HZ 0x04 |
164 | #define HMC5843_CRA_RATE_2HZ 0x08 |
164 | #define HMC5843_CRA_RATE_2HZ 0x08 |
165 | #define HMC5843_CRA_RATE_5HZ 0x0C |
165 | #define HMC5843_CRA_RATE_5HZ 0x0C |
166 | #define HMC5843_CRA_RATE_10HZ 0x10 //default |
166 | #define HMC5843_CRA_RATE_10HZ 0x10 //default |
167 | #define HMC5843_CRA_RATE_20HZ 0x14 |
167 | #define HMC5843_CRA_RATE_20HZ 0x14 |
168 | #define HMC5843_CRA_RATE_50HZ 0x18 // <-- we use this |
168 | #define HMC5843_CRA_RATE_50HZ 0x18 // <-- we use this |
169 | // bit mask for gain |
169 | // bit mask for gain |
170 | #define HMC5843_CRB_GAIN_07GA 0x00 |
170 | #define HMC5843_CRB_GAIN_07GA 0x00 |
171 | #define HMC5843_CRB_GAIN_10GA 0x20 //default |
171 | #define HMC5843_CRB_GAIN_10GA 0x20 //default |
172 | #define HMC5843_CRB_GAIN_15GA 0x40 // <--- we use this |
172 | #define HMC5843_CRB_GAIN_15GA 0x40 // <--- we use this |
173 | #define HMC5843_CRB_GAIN_20GA 0x60 |
173 | #define HMC5843_CRB_GAIN_20GA 0x60 |
174 | #define HMC5843_CRB_GAIN_32GA 0x80 |
174 | #define HMC5843_CRB_GAIN_32GA 0x80 |
175 | #define HMC5843_CRB_GAIN_38GA 0xA0 |
175 | #define HMC5843_CRB_GAIN_38GA 0xA0 |
176 | #define HMC5843_CRB_GAIN_45GA 0xC0 |
176 | #define HMC5843_CRB_GAIN_45GA 0xC0 |
177 | #define HMC5843_CRB_GAIN_65GA 0xE0 |
177 | #define HMC5843_CRB_GAIN_65GA 0xE0 |
178 | // self test value |
178 | // self test value |
179 | #define HMC5843_TEST_XSCALE 555 |
179 | #define HMC5843_TEST_XSCALE 555 |
180 | #define HMC5843_TEST_YSCALE 555 |
180 | #define HMC5843_TEST_YSCALE 555 |
181 | #define HMC5843_TEST_ZSCALE 555 |
181 | #define HMC5843_TEST_ZSCALE 555 |
182 | // calibration range |
182 | // calibration range |
183 | #define HMC5843_CALIBRATION_RANGE 600 |
183 | #define HMC5843_CALIBRATION_RANGE 600 |
184 | 184 | ||
185 | // the special LSM302DLH interface |
185 | // the special LSM302DLH interface |
186 | // bit mask for rate |
186 | // bit mask for rate |
187 | #define LSM303DLH_CRA_RATE_0_75HZ 0x00 |
187 | #define LSM303DLH_CRA_RATE_0_75HZ 0x00 |
188 | #define LSM303DLH_CRA_RATE_1_5HZ 0x04 |
188 | #define LSM303DLH_CRA_RATE_1_5HZ 0x04 |
189 | #define LSM303DLH_CRA_RATE_3_0HZ 0x08 |
189 | #define LSM303DLH_CRA_RATE_3_0HZ 0x08 |
190 | #define LSM303DLH_CRA_RATE_7_5HZ 0x0C |
190 | #define LSM303DLH_CRA_RATE_7_5HZ 0x0C |
191 | #define LSM303DLH_CRA_RATE_15HZ 0x10 //default |
191 | #define LSM303DLH_CRA_RATE_15HZ 0x10 //default |
192 | #define LSM303DLH_CRA_RATE_30HZ 0x14 |
192 | #define LSM303DLH_CRA_RATE_30HZ 0x14 |
193 | #define LSM303DLH_CRA_RATE_75HZ 0x18 // <-- we use this |
193 | #define LSM303DLH_CRA_RATE_75HZ 0x18 // <-- we use this |
194 | 194 | ||
195 | // LSM303D CTRL1 |
195 | // LSM303D CTRL1 |
196 | #define LSM303D_ACC_RATE_0HZ 0x0F |
196 | #define LSM303D_ACC_RATE_0HZ 0x0F |
197 | #define LSM303D_ACC_RATE_3HZ 0x1F |
197 | #define LSM303D_ACC_RATE_3HZ 0x1F |
198 | #define LSM303D_ACC_RATE_6HZ 0x2F |
198 | #define LSM303D_ACC_RATE_6HZ 0x2F |
199 | #define LSM303D_ACC_RATE_12HZ 0x3F |
199 | #define LSM303D_ACC_RATE_12HZ 0x3F |
200 | #define LSM303D_ACC_RATE_25HZ 0x4F |
200 | #define LSM303D_ACC_RATE_25HZ 0x4F |
201 | #define LSM303D_ACC_RATE_50HZ 0x5F |
201 | #define LSM303D_ACC_RATE_50HZ 0x5F |
202 | #define LSM303D_ACC_RATE_100HZ 0x6F |
202 | #define LSM303D_ACC_RATE_100HZ 0x6F |
203 | #define LSM303D_ACC_RATE_200HZ 0x7F |
203 | #define LSM303D_ACC_RATE_200HZ 0x7F |
204 | #define LSM303D_ACC_RATE_400HZ 0x8F |
204 | #define LSM303D_ACC_RATE_400HZ 0x8F |
205 | #define LSM303D_ACC_RATE_800HZ 0x9F |
205 | #define LSM303D_ACC_RATE_800HZ 0x9F |
206 | #define LSM303D_ACC_RATE_1600HZ 0xAF |
206 | #define LSM303D_ACC_RATE_1600HZ 0xAF |
207 | 207 | ||
208 | // LSM303D CTRL1 |
208 | // LSM303D CTRL1 |
209 | #define LSM303D_ACC_SCALE_2g 0x00 |
209 | #define LSM303D_ACC_SCALE_2g 0x00 |
210 | #define LSM303D_ACC_SCALE_4g 0x08 |
210 | #define LSM303D_ACC_SCALE_4g 0x08 |
211 | #define LSM303D_ACC_SCALE_6g 0x10 |
211 | #define LSM303D_ACC_SCALE_6g 0x10 |
212 | #define LSM303D_ACC_SCALE_8g 0x18 |
212 | #define LSM303D_ACC_SCALE_8g 0x18 |
213 | #define LSM303D_ACC_SCALE_16g 0x20 |
213 | #define LSM303D_ACC_SCALE_16g 0x20 |
214 | 214 | ||
215 | // LSM303D CTRL5 |
215 | // LSM303D CTRL5 |
216 | #define LSM303D_ODR_RATE_3HZ 0x00 |
216 | #define LSM303D_ODR_RATE_3HZ 0x00 |
217 | #define LSM303D_ODR_RATE_6HZ 0x04 |
217 | #define LSM303D_ODR_RATE_6HZ 0x04 |
218 | #define LSM303D_ODR_RATE_12HZ 0x08 |
218 | #define LSM303D_ODR_RATE_12HZ 0x08 |
219 | #define LSM303D_ODR_RATE_25HZ 0x0C |
219 | #define LSM303D_ODR_RATE_25HZ 0x0C |
220 | #define LSM303D_ODR_RATE_50HZ 0x10 |
220 | #define LSM303D_ODR_RATE_50HZ 0x10 |
221 | #define LSM303D_ODR_RATE_100HZ 0x14 // attention: ACC Rate must be >50Hz to use this |
221 | #define LSM303D_ODR_RATE_100HZ 0x14 // attention: ACC Rate must be >50Hz to use this |
222 | #define LSM303D_HIGH_RESULUTION 0x60 |
222 | #define LSM303D_HIGH_RESULUTION 0x60 |
223 | #define LSM303D_LOW_RESULUTION 0x00 |
223 | #define LSM303D_LOW_RESULUTION 0x00 |
224 | #define LSM303D_TEMP_ENABLE 0x80 |
224 | #define LSM303D_TEMP_ENABLE 0x80 |
225 | 225 | ||
226 | // LSM303D CTRL6 |
226 | // LSM303D CTRL6 |
227 | #define LSM303D_MAG_SCALE_2GA 0x00 |
227 | #define LSM303D_MAG_SCALE_2GA 0x00 |
228 | #define LSM303D_MAG_SCALE_4GA 0x20 |
228 | #define LSM303D_MAG_SCALE_4GA 0x20 |
229 | #define LSM303D_MAG_SCALE_8GA 0x40 // <-- we use this (Achtung: der LSM303D hat eine höhere Auflösung) |
229 | #define LSM303D_MAG_SCALE_8GA 0x40 // <-- we use this (Achtung: der LSM303D hat eine höhere Auflösung) |
230 | #define LSM303D_MAG_SCALE_12GA 0x60 |
230 | #define LSM303D_MAG_SCALE_12GA 0x60 |
231 | 231 | ||
232 | // bit mask for gain |
232 | // bit mask for gain |
233 | #define LSM303DLH_CRB_GAIN_XXGA 0x00 |
233 | #define LSM303DLH_CRB_GAIN_XXGA 0x00 |
234 | #define LSM303DLH_CRB_GAIN_13GA 0x20 //default |
234 | #define LSM303DLH_CRB_GAIN_13GA 0x20 //default |
235 | #define LSM303DLH_CRB_GAIN_19GA 0x40 |
235 | #define LSM303DLH_CRB_GAIN_19GA 0x40 |
236 | #define LSM303DLH_CRB_GAIN_25GA 0x60 |
236 | #define LSM303DLH_CRB_GAIN_25GA 0x60 |
237 | #define LSM303DLH_CRB_GAIN_40GA 0x80 // <--- we use this (Since V2.03) |
237 | #define LSM303DLH_CRB_GAIN_40GA 0x80 // <--- we use this (Since V2.03) |
238 | #define LSM303DLH_CRB_GAIN_47GA 0xA0 |
238 | #define LSM303DLH_CRB_GAIN_47GA 0xA0 |
239 | #define LSM303DLH_CRB_GAIN_56GA 0xC0 |
239 | #define LSM303DLH_CRB_GAIN_56GA 0xC0 |
240 | #define LSM303DLH_CRB_GAIN_81GA 0xE0 |
240 | #define LSM303DLH_CRB_GAIN_81GA 0xE0 |
241 | 241 | ||
242 | typedef struct |
242 | typedef struct |
243 | { |
243 | { |
244 | u8 A; |
244 | u8 A; |
245 | u8 B; |
245 | u8 B; |
246 | u8 C; |
246 | u8 C; |
247 | } __attribute__((packed)) Identification_t; |
247 | } __attribute__((packed)) Identification_t; |
248 | volatile Identification_t NCMAG_Identification; |
248 | volatile Identification_t NCMAG_Identification; |
249 | 249 | ||
250 | typedef struct |
250 | typedef struct |
251 | { |
251 | { |
252 | u8 Sub; |
252 | u8 Sub; |
253 | } __attribute__((packed)) Identification2_t; |
253 | } __attribute__((packed)) Identification2_t; |
254 | volatile Identification2_t NCMAG_Identification2; |
254 | volatile Identification2_t NCMAG_Identification2; |
255 | 255 | ||
256 | typedef struct |
256 | typedef struct |
257 | { |
257 | { |
258 | u8 cra; |
258 | u8 cra; |
259 | u8 crb; |
259 | u8 crb; |
260 | u8 mode; |
260 | u8 mode; |
261 | } __attribute__((packed)) MagConfig_t; |
261 | } __attribute__((packed)) MagConfig_t; |
262 | 262 | ||
263 | volatile MagConfig_t MagConfig; |
263 | volatile MagConfig_t MagConfig; |
264 | 264 | ||
265 | // self test value |
265 | // self test value |
266 | #define LSM303DLH_TEST_XSCALE 245 |
266 | #define LSM303DLH_TEST_XSCALE 245 |
267 | #define LSM303DLH_TEST_YSCALE 245 |
267 | #define LSM303DLH_TEST_YSCALE 245 |
268 | #define LSM303DLH_TEST_ZSCALE 235 |
268 | #define LSM303DLH_TEST_ZSCALE 235 |
269 | // clibration range |
269 | // clibration range |
270 | #define LSM303_CALIBRATION_RANGE 300 // War bis V2.02: 550 -> Auflösung von 19Ga auf 40GA reduziert |
270 | #define LSM303_CALIBRATION_RANGE 300 // War bis V2.02: 550 -> Auflösung von 19Ga auf 40GA reduziert |
271 | 271 | ||
272 | // the i2c ACC interface |
272 | // the i2c ACC interface |
273 | #define ACC_SLAVE_ADDRESS 0x30 // i2c slave for acc. sensor registers |
273 | #define ACC_SLAVE_ADDRESS 0x30 // i2c slave for acc. sensor registers |
274 | 274 | ||
275 | // multiple byte read/write mask |
275 | // multiple byte read/write mask |
276 | #define REG_MASK_AUTOINCREMENT 0x80 |
276 | #define REG_MASK_AUTOINCREMENT 0x80 |
277 | 277 | ||
278 | // register mapping |
278 | // register mapping |
279 | #define REG_ACC_CTRL1 0x20 |
279 | #define REG_ACC_CTRL1 0x20 |
280 | #define REG_ACC_CTRL2 0x21 |
280 | #define REG_ACC_CTRL2 0x21 |
281 | #define REG_ACC_CTRL3 0x22 |
281 | #define REG_ACC_CTRL3 0x22 |
282 | #define REG_ACC_CTRL4 0x23 |
282 | #define REG_ACC_CTRL4 0x23 |
283 | #define REG_ACC_CTRL5 0x24 |
283 | #define REG_ACC_CTRL5 0x24 |
284 | #define REG_ACC_HP_FILTER_RESET 0x25 |
284 | #define REG_ACC_HP_FILTER_RESET 0x25 |
285 | #define REG_ACC_REFERENCE 0x26 |
285 | #define REG_ACC_REFERENCE 0x26 |
286 | #define REG_ACC_STATUS 0x27 |
286 | #define REG_ACC_STATUS 0x27 |
287 | #define REG_ACC_X_LSB 0x28 |
287 | #define REG_ACC_X_LSB 0x28 |
288 | #define REG_ACC_X_MSB 0x29 |
288 | #define REG_ACC_X_MSB 0x29 |
289 | #define REG_ACC_Y_LSB 0x2A |
289 | #define REG_ACC_Y_LSB 0x2A |
290 | #define REG_ACC_Y_MSB 0x2B |
290 | #define REG_ACC_Y_MSB 0x2B |
291 | #define REG_ACC_Z_LSB 0x2C |
291 | #define REG_ACC_Z_LSB 0x2C |
292 | #define REG_ACC_Z_MSB 0x2D |
292 | #define REG_ACC_Z_MSB 0x2D |
293 | 293 | ||
294 | #define ACC_CRTL1_PM_DOWN 0x00 |
294 | #define ACC_CRTL1_PM_DOWN 0x00 |
295 | #define ACC_CRTL1_PM_NORMAL 0x20 |
295 | #define ACC_CRTL1_PM_NORMAL 0x20 |
296 | #define ACC_CRTL1_PM_LOW_0_5HZ 0x40 |
296 | #define ACC_CRTL1_PM_LOW_0_5HZ 0x40 |
297 | #define ACC_CRTL1_PM_LOW_1HZ 0x60 |
297 | #define ACC_CRTL1_PM_LOW_1HZ 0x60 |
298 | #define ACC_CRTL1_PM_LOW_2HZ 0x80 |
298 | #define ACC_CRTL1_PM_LOW_2HZ 0x80 |
299 | #define ACC_CRTL1_PM_LOW_5HZ 0xA0 |
299 | #define ACC_CRTL1_PM_LOW_5HZ 0xA0 |
300 | #define ACC_CRTL1_PM_LOW_10HZ 0xC0 |
300 | #define ACC_CRTL1_PM_LOW_10HZ 0xC0 |
301 | // Output data rate in normal power mode |
301 | // Output data rate in normal power mode |
302 | #define ACC_CRTL1_DR_50HZ 0x00 |
302 | #define ACC_CRTL1_DR_50HZ 0x00 |
303 | #define ACC_CRTL1_DR_100HZ 0x08 |
303 | #define ACC_CRTL1_DR_100HZ 0x08 |
304 | #define ACC_CRTL1_DR_400HZ 0x10 |
304 | #define ACC_CRTL1_DR_400HZ 0x10 |
305 | #define ACC_CRTL1_DR_1000HZ 0x18 |
305 | #define ACC_CRTL1_DR_1000HZ 0x18 |
306 | // axis anable flags |
306 | // axis anable flags |
307 | #define ACC_CRTL1_XEN 0x01 |
307 | #define ACC_CRTL1_XEN 0x01 |
308 | #define ACC_CRTL1_YEN 0x02 |
308 | #define ACC_CRTL1_YEN 0x02 |
309 | #define ACC_CRTL1_ZEN 0x04 |
309 | #define ACC_CRTL1_ZEN 0x04 |
310 | 310 | ||
311 | #define ACC_CRTL2_FILTER8 0x10 |
311 | #define ACC_CRTL2_FILTER8 0x10 |
312 | #define ACC_CRTL2_FILTER16 0x11 |
312 | #define ACC_CRTL2_FILTER16 0x11 |
313 | #define ACC_CRTL2_FILTER32 0x12 |
313 | #define ACC_CRTL2_FILTER32 0x12 |
314 | #define ACC_CRTL2_FILTER64 0x13 |
314 | #define ACC_CRTL2_FILTER64 0x13 |
315 | 315 | ||
316 | #define ACC_CTRL4_BDU 0x80 // Block data update, (0: continuos update; 1: output registers not updated between MSB and LSB reading) |
316 | #define ACC_CTRL4_BDU 0x80 // Block data update, (0: continuos update; 1: output registers not updated between MSB and LSB reading) |
317 | #define ACC_CTRL4_BLE 0x40 // Big/little endian, (0: data LSB @ lower address; 1: data MSB @ lower address) |
317 | #define ACC_CTRL4_BLE 0x40 // Big/little endian, (0: data LSB @ lower address; 1: data MSB @ lower address) |
318 | #define ACC_CTRL4_FS_2G 0x00 |
318 | #define ACC_CTRL4_FS_2G 0x00 |
319 | #define ACC_CTRL4_FS_4G 0x10 |
319 | #define ACC_CTRL4_FS_4G 0x10 |
320 | #define ACC_CTRL4_FS_8G 0x30 |
320 | #define ACC_CTRL4_FS_8G 0x30 |
321 | #define ACC_CTRL4_STSIGN_PLUS 0x00 |
321 | #define ACC_CTRL4_STSIGN_PLUS 0x00 |
322 | #define ACC_CTRL4_STSIGN_MINUS 0x08 |
322 | #define ACC_CTRL4_STSIGN_MINUS 0x08 |
323 | #define ACC_CTRL4_ST_ENABLE 0x02 |
323 | #define ACC_CTRL4_ST_ENABLE 0x02 |
324 | 324 | ||
325 | #define ACC_CTRL5_STW_ON 0x03 |
325 | #define ACC_CTRL5_STW_ON 0x03 |
326 | #define ACC_CTRL5_STW_OFF 0x00 |
326 | #define ACC_CTRL5_STW_OFF 0x00 |
327 | 327 | ||
328 | typedef struct |
328 | typedef struct |
329 | { |
329 | { |
330 | u8 ctrl_1; |
330 | u8 ctrl_1; |
331 | u8 ctrl_2; |
331 | u8 ctrl_2; |
332 | u8 ctrl_3; |
332 | u8 ctrl_3; |
333 | u8 ctrl_4; |
333 | u8 ctrl_4; |
334 | u8 ctrl_5; |
334 | u8 ctrl_5; |
335 | } __attribute__((packed)) AccConfig_t; |
335 | } __attribute__((packed)) AccConfig_t; |
336 | 336 | ||
337 | volatile AccConfig_t AccConfig; |
337 | volatile AccConfig_t AccConfig; |
338 | 338 | ||
339 | // write calibration data for external and internal sensor seperately |
339 | // write calibration data for external and internal sensor seperately |
340 | u8 NCMag_CalibrationWrite(I2C_TypeDef* I2Cx) |
340 | u8 NCMag_CalibrationWrite(I2C_TypeDef* I2Cx) |
341 | { |
341 | { |
342 | u16 address; |
342 | u16 address; |
343 | u8 i = 0, crc = MAG_CALIBRATION_COMPATIBLE; |
343 | u8 i = 0, crc = MAG_CALIBRATION_COMPATIBLE; |
344 | EEPROM_Result_t eres; |
344 | EEPROM_Result_t eres; |
345 | u8 *pBuff = (u8*)&Calibration; |
345 | u8 *pBuff = (u8*)&Calibration; |
346 | Calibration.Version = CALIBRATION_VERSION + (NCMAG_Orientation<<4);; |
346 | Calibration.Version = CALIBRATION_VERSION + (NCMAG_Orientation<<4);; |
347 | 347 | ||
348 | if (I2Cx == NCMAG_PORT_EXTERN) |
348 | if (I2Cx == NCMAG_PORT_EXTERN) |
349 | { |
349 | { |
350 | address = EEPROM_ADR_MAG_CALIBRATION_EXTERN; |
350 | address = EEPROM_ADR_MAG_CALIBRATION_EXTERN; |
351 | } |
351 | } |
352 | else if (I2Cx == NCMAG_PORT_INTERN) |
352 | else if (I2Cx == NCMAG_PORT_INTERN) |
353 | { |
353 | { |
354 | address = EEPROM_ADR_MAG_CALIBRATION_INTERN; |
354 | address = EEPROM_ADR_MAG_CALIBRATION_INTERN; |
355 | } |
355 | } |
356 | else return(i); |
356 | else return(i); |
357 | 357 | ||
358 | for(i = 0; i<(sizeof(Calibration)-1); i++) |
358 | for(i = 0; i<(sizeof(Calibration)-1); i++) |
359 | { |
359 | { |
360 | crc += pBuff[i]; |
360 | crc += pBuff[i]; |
361 | } |
361 | } |
362 | Calibration.crc = ~crc; |
362 | Calibration.crc = ~crc; |
363 | eres = EEPROM_WriteBlock(address, pBuff, sizeof(Calibration)); |
363 | eres = EEPROM_WriteBlock(address, pBuff, sizeof(Calibration)); |
364 | if(EEPROM_SUCCESS == eres) i = 1; |
364 | if(EEPROM_SUCCESS == eres) i = 1; |
365 | else i = 0; |
365 | else i = 0; |
366 | return(i); |
366 | return(i); |
367 | } |
367 | } |
368 | 368 | ||
369 | // read calibration data for external and internal sensor seperately |
369 | // read calibration data for external and internal sensor seperately |
370 | u8 NCMag_CalibrationRead(I2C_TypeDef* I2Cx) |
370 | u8 NCMag_CalibrationRead(I2C_TypeDef* I2Cx) |
371 | { |
371 | { |
372 | u8 address; |
372 | u8 address; |
373 | u8 i = 0, crc = MAG_CALIBRATION_COMPATIBLE; |
373 | u8 i = 0, crc = MAG_CALIBRATION_COMPATIBLE; |
374 | u8 *pBuff = (u8*)&Calibration; |
374 | u8 *pBuff = (u8*)&Calibration; |
375 | 375 | ||
376 | if (I2Cx == NCMAG_PORT_EXTERN) address = EEPROM_ADR_MAG_CALIBRATION_EXTERN; |
376 | if (I2Cx == NCMAG_PORT_EXTERN) address = EEPROM_ADR_MAG_CALIBRATION_EXTERN; |
377 | else if (I2Cx == NCMAG_PORT_INTERN) address = EEPROM_ADR_MAG_CALIBRATION_INTERN; |
377 | else if (I2Cx == NCMAG_PORT_INTERN) address = EEPROM_ADR_MAG_CALIBRATION_INTERN; |
378 | else return(0); |
378 | else return(0); |
379 | 379 | ||
380 | if(EEPROM_SUCCESS == EEPROM_ReadBlock(address, pBuff, sizeof(Calibration))) |
380 | if(EEPROM_SUCCESS == EEPROM_ReadBlock(address, pBuff, sizeof(Calibration))) |
381 | { |
381 | { |
382 | for(i = 0; i<(sizeof(Calibration)-1); i++) |
382 | for(i = 0; i<(sizeof(Calibration)-1); i++) |
383 | { |
383 | { |
384 | crc += pBuff[i]; |
384 | crc += pBuff[i]; |
385 | } |
385 | } |
386 | crc = ~crc; |
386 | crc = ~crc; |
387 | if(Calibration.crc != crc) return(0); // crc mismatch |
387 | if(Calibration.crc != crc) return(0); // crc mismatch |
388 | if((Calibration.Version & 0x0F) == CALIBRATION_VERSION) return(1); |
388 | if((Calibration.Version & 0x0F) == CALIBRATION_VERSION) return(1); |
389 | } |
389 | } |
390 | return(0); |
390 | return(0); |
391 | } |
391 | } |
392 | 392 | ||
393 | 393 | ||
394 | void NCMAG_Calibrate(void) |
394 | void NCMAG_Calibrate(void) |
395 | { |
395 | { |
396 | u8 msg[64]; |
396 | u8 msg[64]; |
397 | static u8 speak = 0; |
397 | static u8 speak = 0; |
398 | static s16 Xmin = 0, Xmax = 0, Ymin = 0, Ymax = 0, Zmin = 0, Zmax = 0, Zmin2 = 0, Zmax2 = 0;; |
398 | static s16 Xmin = 0, Xmax = 0, Ymin = 0, Ymax = 0, Zmin = 0, Zmax = 0, Zmin2 = 0, Zmax2 = 0;; |
399 | static s16 X = 0, Y = 0, Z = 0; |
399 | static s16 X = 0, Y = 0, Z = 0; |
400 | static u8 OldCalState = 0; |
400 | static u8 OldCalState = 0; |
401 | s16 MinCalibration = 450; |
401 | s16 MinCalibration = 450; |
402 | 402 | ||
403 | X = (X + MagRawVector.X)/2; |
403 | X = (X + MagRawVector.X)/2; |
404 | Y = (Y + MagRawVector.Y)/2; |
404 | Y = (Y + MagRawVector.Y)/2; |
405 | Z = (Z + MagRawVector.Z)/2; |
405 | Z = (Z + MagRawVector.Z)/2; |
406 | 406 | ||
407 | switch(Compass_CalState) |
407 | switch(Compass_CalState) |
408 | { |
408 | { |
409 | case 1: |
409 | case 1: |
410 | // 1st step of calibration |
410 | // 1st step of calibration |
411 | // initialize ranges |
411 | // initialize ranges |
412 | // used to change the orientation of the NC in the horizontal plane |
412 | // used to change the orientation of the NC in the horizontal plane |
413 | Xmin = 10000; |
413 | Xmin = 10000; |
414 | Xmax = -10000; |
414 | Xmax = -10000; |
415 | Ymin = 10000; |
415 | Ymin = 10000; |
416 | Ymax = -10000; |
416 | Ymax = -10000; |
417 | Zmin = 10000; |
417 | Zmin = 10000; |
418 | Zmax = -10000; |
418 | Zmax = -10000; |
419 | Zmin2 = 10000; |
419 | Zmin2 = 10000; |
420 | Zmax2 = -10000; |
420 | Zmax2 = -10000; |
421 | X = 0; Y = 0; Z = 0; |
421 | X = 0; Y = 0; Z = 0; |
422 | speak = 1; |
422 | speak = 1; |
423 | CompassValueErrorCount = 0; |
423 | CompassValueErrorCount = 0; |
424 | if(Compass_CalState != OldCalState) // only once per state |
424 | if(Compass_CalState != OldCalState) // only once per state |
425 | { |
425 | { |
426 | UART1_PutString("\r\nStarting compass calibration"); |
426 | UART1_PutString("\r\nStarting compass calibration"); |
427 | if(NCMAG_Compass_use_Orientation) |
427 | if(NCMAG_Compass_use_Orientation) |
428 | { |
428 | { |
429 | if(!NCMAG_Orientation) NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
429 | if(!NCMAG_Orientation) NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
430 | UART1_PutString(" - External sensor "); |
430 | UART1_PutString(" - External sensor "); |
431 | sprintf(msg, "with orientation: %d ", NCMAG_Orientation); |
431 | sprintf(msg, "with orientation: %d ", NCMAG_Orientation); |
432 | UART1_PutString(msg); |
432 | UART1_PutString(msg); |
433 | } |
433 | } |
434 | else UART1_PutString(" - Internal sensor "); |
434 | else UART1_PutString(" - Internal sensor "); |
435 | } |
435 | } |
436 | break; |
436 | break; |
437 | 437 | ||
438 | case 2: // 2nd step of calibration |
438 | case 2: // 2nd step of calibration |
439 | // find Min and Max of the X- and Y-Sensors during rotation in the horizontal plane |
439 | // find Min and Max of the X- and Y-Sensors during rotation in the horizontal plane |
440 | if(X < Xmin) { Xmin = X; BeepTime = 20;} |
440 | if(X < Xmin) { Xmin = X; BeepTime = 20;} |
441 | else if(X > Xmax) { Xmax = X; BeepTime = 20;} |
441 | else if(X > Xmax) { Xmax = X; BeepTime = 20;} |
442 | if(Y < Ymin) { Ymin = Y; BeepTime = 60;} |
442 | if(Y < Ymin) { Ymin = Y; BeepTime = 60;} |
443 | else if(Y > Ymax) { Ymax = Y; BeepTime = 60;} |
443 | else if(Y > Ymax) { Ymax = Y; BeepTime = 60;} |
444 | if(Z < Zmin) { Zmin = Z; } // silent |
444 | if(Z < Zmin) { Zmin = Z; } // silent |
445 | else if(Z > Zmax) { Zmax = Z; } |
445 | else if(Z > Zmax) { Zmax = Z; } |
446 | if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0; |
446 | if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0; |
447 | break; |
447 | break; |
448 | 448 | ||
449 | case 3: // 3rd step of calibration |
449 | case 3: // 3rd step of calibration |
450 | // used to change the orientation of the MK3MAG vertical to the horizontal plane |
450 | // used to change the orientation of the MK3MAG vertical to the horizontal plane |
451 | speak = 1; |
451 | speak = 1; |
452 | break; |
452 | break; |
453 | 453 | ||
454 | case 4: |
454 | case 4: |
455 | // find Min and Max of the Z-Sensor |
455 | // find Min and Max of the Z-Sensor |
456 | if(Z < Zmin2) { Zmin2 = Z; BeepTime = 80;} |
456 | if(Z < Zmin2) { Zmin2 = Z; BeepTime = 80;} |
457 | else if(Z > Zmax2) { Zmax2 = Z; BeepTime = 80;} |
457 | else if(Z > Zmax2) { Zmax2 = Z; BeepTime = 80;} |
458 | if(X < Xmin) { Xmin = X; BeepTime = 20;} |
458 | if(X < Xmin) { Xmin = X; BeepTime = 20;} |
459 | else if(X > Xmax) { Xmax = X; BeepTime = 20;} |
459 | else if(X > Xmax) { Xmax = X; BeepTime = 20;} |
460 | if(Y < Ymin) { Ymin = Y; BeepTime = 60;} |
460 | if(Y < Ymin) { Ymin = Y; BeepTime = 60;} |
461 | else if(Y > Ymax) { Ymax = Y; BeepTime = 60;} |
461 | else if(Y > Ymax) { Ymax = Y; BeepTime = 60;} |
462 | if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0; |
462 | if(speak) SpeakHoTT = SPEAK_CALIBRATE; speak = 0; |
463 | break; |
463 | break; |
464 | 464 | ||
465 | case 5: |
465 | case 5: |
466 | // Save values |
466 | // Save values |
467 | if(Compass_CalState != OldCalState) // avoid continously writing of eeprom! |
467 | if(Compass_CalState != OldCalState) // avoid continously writing of eeprom! |
468 | { |
468 | { |
469 | switch(NCMAG_SensorType) |
469 | switch(NCMAG_SensorType) |
470 | { |
470 | { |
471 | case TYPE_HMC5843: |
471 | case TYPE_HMC5843: |
472 | UART1_PutString("\r\nFinished: HMC5843 calibration\n\r"); |
472 | UART1_PutString("\r\nFinished: HMC5843 calibration\r\n"); |
473 | MinCalibration = HMC5843_CALIBRATION_RANGE; |
473 | MinCalibration = HMC5843_CALIBRATION_RANGE; |
474 | break; |
474 | break; |
475 | 475 | ||
476 | case TYPE_LSM303DLH: |
476 | case TYPE_LSM303DLH: |
477 | case TYPE_LSM303DLM: |
477 | case TYPE_LSM303DLM: |
478 | case TYPE_LSM303D: |
478 | case TYPE_LSM303D: |
479 | default: |
479 | default: |
480 | UART1_PutString("\r\nFinished: LSM303 calibration\n\r"); |
480 | UART1_PutString("\r\nFinished: LSM303 calibration\r\n"); |
481 | MinCalibration = LSM303_CALIBRATION_RANGE; |
481 | MinCalibration = LSM303_CALIBRATION_RANGE; |
482 | break; |
482 | break; |
483 | } |
483 | } |
484 | if(EarthMagneticStrengthTheoretic) |
484 | if(EarthMagneticStrengthTheoretic) |
485 | { |
485 | { |
486 | MinCalibration = (MinCalibration * EarthMagneticStrengthTheoretic) / 50; |
486 | MinCalibration = (MinCalibration * EarthMagneticStrengthTheoretic) / 50; |
487 | sprintf(msg, "Earth field on your location should be: %iuT\r\n",EarthMagneticStrengthTheoretic); |
487 | sprintf(msg, "Earth field on your location should be: %iuT\r\n",EarthMagneticStrengthTheoretic); |
488 | UART1_PutString(msg); |
488 | UART1_PutString(msg); |
489 | } |
489 | } |
490 | else UART1_PutString("without GPS\n\r"); |
490 | else UART1_PutString("without GPS\r\n"); |
491 | 491 | ||
492 | if(Zmin2 < Zmin) Zmin = Zmin2; |
492 | if(Zmin2 < Zmin) Zmin = Zmin2; |
493 | if(Zmax2 > Zmax) Zmax = Zmax2; |
493 | if(Zmax2 > Zmax) Zmax = Zmax2; |
494 | Calibration.MagX.Range = Xmax - Xmin; |
494 | Calibration.MagX.Range = Xmax - Xmin; |
495 | Calibration.MagX.Offset = (Xmin + Xmax) / 2; |
495 | Calibration.MagX.Offset = (Xmin + Xmax) / 2; |
496 | Calibration.MagY.Range = Ymax - Ymin; |
496 | Calibration.MagY.Range = Ymax - Ymin; |
497 | Calibration.MagY.Offset = (Ymin + Ymax) / 2; |
497 | Calibration.MagY.Offset = (Ymin + Ymax) / 2; |
498 | Calibration.MagZ.Range = Zmax - Zmin; |
498 | Calibration.MagZ.Range = Zmax - Zmin; |
499 | Calibration.MagZ.Offset = (Zmin + Zmax) / 2; |
499 | Calibration.MagZ.Offset = (Zmin + Zmax) / 2; |
500 | if(CompassValueErrorCount) |
500 | if(CompassValueErrorCount) |
501 | { |
501 | { |
502 | SpeakHoTT = SPEAK_ERR_CALIBARTION; |
502 | SpeakHoTT = SPEAK_ERR_CALIBARTION; |
503 | UART1_PutString("\r\nCalibration FAILED - Compass sensor error !!!!\r\n "); |
503 | UART1_PutString("\r\nCalibration FAILED - Compass sensor error !!!!\r\n "); |
504 | 504 | ||
505 | } |
505 | } |
506 | else |
506 | else |
507 | if((Calibration.MagX.Range > MinCalibration) && (Calibration.MagY.Range > MinCalibration) && (Calibration.MagZ.Range > MinCalibration)) |
507 | if((Calibration.MagX.Range > MinCalibration) && (Calibration.MagY.Range > MinCalibration) && (Calibration.MagZ.Range > MinCalibration)) |
508 | { |
508 | { |
509 | NCMAG_IsCalibrated = NCMag_CalibrationWrite(Compass_I2CPort); |
509 | NCMAG_IsCalibrated = NCMag_CalibrationWrite(Compass_I2CPort); |
510 | BeepTime = 2500; |
510 | BeepTime = 2500; |
511 | UART1_PutString("\r\n-> Calibration okay <-\n\r"); |
511 | UART1_PutString("\r\n-> Calibration okay <-\r\n"); |
512 | SpeakHoTT = SPEAK_MIKROKOPTER; |
512 | SpeakHoTT = SPEAK_MIKROKOPTER; |
513 | } |
513 | } |
514 | else |
514 | else |
515 | { |
515 | { |
516 | SpeakHoTT = SPEAK_ERR_CALIBARTION; |
516 | SpeakHoTT = SPEAK_ERR_CALIBARTION; |
517 | UART1_PutString("\r\nCalibration FAILED - Values too low: "); |
517 | UART1_PutString("\r\nCalibration FAILED - Values too low: "); |
518 | if(Calibration.MagX.Range < MinCalibration) UART1_PutString("X! "); |
518 | if(Calibration.MagX.Range < MinCalibration) UART1_PutString("X! "); |
519 | if(Calibration.MagY.Range < MinCalibration) UART1_PutString("Y! "); |
519 | if(Calibration.MagY.Range < MinCalibration) UART1_PutString("Y! "); |
520 | if(Calibration.MagZ.Range < MinCalibration) UART1_PutString("Z! "); |
520 | if(Calibration.MagZ.Range < MinCalibration) UART1_PutString("Z! "); |
521 | UART1_PutString("\r\n"); |
521 | UART1_PutString("\r\n"); |
522 | 522 | ||
523 | // restore old calibration data from eeprom |
523 | // restore old calibration data from eeprom |
524 | NCMAG_IsCalibrated = NCMag_CalibrationRead(Compass_I2CPort); |
524 | NCMAG_IsCalibrated = NCMag_CalibrationRead(Compass_I2CPort); |
525 | } |
525 | } |
526 | sprintf(msg, "X: (%i - %i = %i)\r\n",Xmax,Xmin,Xmax - Xmin); |
526 | sprintf(msg, "X: (%i - %i = %i)\r\n",Xmax,Xmin,Xmax - Xmin); |
527 | UART1_PutString(msg); |
527 | UART1_PutString(msg); |
528 | sprintf(msg, "Y: (%i - %i = %i)\r\n",Ymax,Ymin,Ymax - Ymin); |
528 | sprintf(msg, "Y: (%i - %i = %i)\r\n",Ymax,Ymin,Ymax - Ymin); |
529 | UART1_PutString(msg); |
529 | UART1_PutString(msg); |
530 | sprintf(msg, "Z: (%i - %i = %i)\r\n",Zmax,Zmin,Zmax - Zmin); |
530 | sprintf(msg, "Z: (%i - %i = %i)\r\n",Zmax,Zmin,Zmax - Zmin); |
531 | UART1_PutString(msg); |
531 | UART1_PutString(msg); |
532 | sprintf(msg, "(Minimum ampilitude is: %i)\r\n",MinCalibration); |
532 | sprintf(msg, "(Minimum ampilitude is: %i)\r\n",MinCalibration); |
533 | UART1_PutString(msg); |
533 | UART1_PutString(msg); |
534 | } |
534 | } |
535 | break; |
535 | break; |
536 | 536 | ||
537 | default: |
537 | default: |
538 | break; |
538 | break; |
539 | } |
539 | } |
540 | OldCalState = Compass_CalState; |
540 | OldCalState = Compass_CalState; |
541 | } |
541 | } |
542 | 542 | ||
543 | // ---------- call back handlers ----------------------------------------- |
543 | // ---------- call back handlers ----------------------------------------- |
544 | 544 | ||
545 | // rx data handler for id info request |
545 | // rx data handler for id info request |
546 | void NCMAG_UpdateIdentification(u8* pRxBuffer, u8 RxBufferSize) |
546 | void NCMAG_UpdateIdentification(u8* pRxBuffer, u8 RxBufferSize) |
547 | { // if number of bytes are matching |
547 | { // if number of bytes are matching |
548 | if(RxBufferSize == sizeof(NCMAG_Identification) ) |
548 | if(RxBufferSize == sizeof(NCMAG_Identification) ) |
549 | { |
549 | { |
550 | memcpy((u8 *)&NCMAG_Identification, pRxBuffer, sizeof(NCMAG_Identification)); |
550 | memcpy((u8 *)&NCMAG_Identification, pRxBuffer, sizeof(NCMAG_Identification)); |
551 | } |
551 | } |
552 | } |
552 | } |
553 | 553 | ||
554 | void NCMAG_UpdateIdentification_Sub(u8* pRxBuffer, u8 RxBufferSize) |
554 | void NCMAG_UpdateIdentification_Sub(u8* pRxBuffer, u8 RxBufferSize) |
555 | { // if number of bytes are matching |
555 | { // if number of bytes are matching |
556 | if(RxBufferSize == sizeof(NCMAG_Identification2)) |
556 | if(RxBufferSize == sizeof(NCMAG_Identification2)) |
557 | { |
557 | { |
558 | memcpy((u8 *)&NCMAG_Identification2, pRxBuffer, sizeof(NCMAG_Identification2)); |
558 | memcpy((u8 *)&NCMAG_Identification2, pRxBuffer, sizeof(NCMAG_Identification2)); |
559 | } |
559 | } |
560 | } |
560 | } |
561 | 561 | ||
562 | // rx data handler for magnetic sensor raw data |
562 | // rx data handler for magnetic sensor raw data |
563 | void NCMAG_UpdateMagVector(u8* pRxBuffer, u8 RxBufferSize) |
563 | void NCMAG_UpdateMagVector(u8* pRxBuffer, u8 RxBufferSize) |
564 | { |
564 | { |
565 | u8 endian = 1; |
565 | u8 endian = 1; |
566 | if(NCMAG_SensorType == TYPE_LSM303D) endian = 0; // here the low and high-bytes are mixed |
566 | if(NCMAG_SensorType == TYPE_LSM303D) endian = 0; // here the low and high-bytes are mixed |
567 | if(RxBufferSize == sizeof(MagRawVector) ) // if number of bytes are matching |
567 | if(RxBufferSize == sizeof(MagRawVector) ) // if number of bytes are matching |
568 | { // byte order from big to little endian |
568 | { // byte order from big to little endian |
569 | s16 raw, X = 0, Y = 0, Z = 0; |
569 | s16 raw, X = 0, Y = 0, Z = 0; |
570 | if(endian) {raw = pRxBuffer[0]<<8; raw+= pRxBuffer[1];} else {raw = (pRxBuffer[1] << 8) + pRxBuffer[0]; raw >>= 3;} |
570 | if(endian) {raw = pRxBuffer[0]<<8; raw+= pRxBuffer[1];} else {raw = (pRxBuffer[1] << 8) + pRxBuffer[0]; raw >>= 3;} |
571 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) X = raw; |
571 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) X = raw; |
572 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
572 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
573 | if(endian) {raw = pRxBuffer[2]<<8; raw+= pRxBuffer[3];} else {raw = (pRxBuffer[3] << 8) + pRxBuffer[2]; raw >>= 3;} |
573 | if(endian) {raw = pRxBuffer[2]<<8; raw+= pRxBuffer[3];} else {raw = (pRxBuffer[3] << 8) + pRxBuffer[2]; raw >>= 3;} |
574 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) |
574 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) |
575 | { |
575 | { |
576 | if(NCMAG_SensorType == TYPE_LSM303DLM) Z = raw; // here Z and Y are exchanged |
576 | if(NCMAG_SensorType == TYPE_LSM303DLM) Z = raw; // here Z and Y are exchanged |
577 | else Y = raw; |
577 | else Y = raw; |
578 | } |
578 | } |
579 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
579 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
580 | if(endian) {raw = pRxBuffer[4]<<8; raw+= pRxBuffer[5];} else {raw = (pRxBuffer[5] << 8) + pRxBuffer[4]; raw >>= 3;} |
580 | if(endian) {raw = pRxBuffer[4]<<8; raw+= pRxBuffer[5];} else {raw = (pRxBuffer[5] << 8) + pRxBuffer[4]; raw >>= 3;} |
581 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) |
581 | if(raw >= NCMAG_MIN_RAWVALUE && raw <= NCMAG_MAX_RAWVALUE) |
582 | { |
582 | { |
583 | if(NCMAG_SensorType == TYPE_LSM303DLM) Y = raw; // here Z and Y are exchanged |
583 | if(NCMAG_SensorType == TYPE_LSM303DLM) Y = raw; // here Z and Y are exchanged |
584 | else Z = raw; |
584 | else Z = raw; |
585 | } |
585 | } |
586 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
586 | else if(CompassValueErrorCount < 35) CompassValueErrorCount++; // invalid data |
587 | // correct compass orientation |
587 | // correct compass orientation |
588 | switch(NCMAG_Orientation) |
588 | switch(NCMAG_Orientation) |
589 | { |
589 | { |
590 | case 0: |
590 | case 0: |
591 | case 1: |
591 | case 1: |
592 | default: |
592 | default: |
593 | // 1:1 Mapping |
593 | // 1:1 Mapping |
594 | MagRawVector.X = X; |
594 | MagRawVector.X = X; |
595 | MagRawVector.Y = Y; |
595 | MagRawVector.Y = Y; |
596 | MagRawVector.Z = Z; |
596 | MagRawVector.Z = Z; |
597 | break; |
597 | break; |
598 | case 2: |
598 | case 2: |
599 | MagRawVector.X = -X; |
599 | MagRawVector.X = -X; |
600 | MagRawVector.Y = Y; |
600 | MagRawVector.Y = Y; |
601 | MagRawVector.Z = -Z; |
601 | MagRawVector.Z = -Z; |
602 | break; |
602 | break; |
603 | case 3: |
603 | case 3: |
604 | MagRawVector.X = -Z; |
604 | MagRawVector.X = -Z; |
605 | MagRawVector.Y = Y; |
605 | MagRawVector.Y = Y; |
606 | MagRawVector.Z = X; |
606 | MagRawVector.Z = X; |
607 | break; |
607 | break; |
608 | case 4: |
608 | case 4: |
609 | MagRawVector.X = Z; |
609 | MagRawVector.X = Z; |
610 | MagRawVector.Y = Y; |
610 | MagRawVector.Y = Y; |
611 | MagRawVector.Z = -X; |
611 | MagRawVector.Z = -X; |
612 | break; |
612 | break; |
613 | case 5: |
613 | case 5: |
614 | MagRawVector.X = X; |
614 | MagRawVector.X = X; |
615 | MagRawVector.Y = -Z; |
615 | MagRawVector.Y = -Z; |
616 | MagRawVector.Z = Y; |
616 | MagRawVector.Z = Y; |
617 | break; |
617 | break; |
618 | case 6: |
618 | case 6: |
619 | MagRawVector.X = -X; |
619 | MagRawVector.X = -X; |
620 | MagRawVector.Y = -Z; |
620 | MagRawVector.Y = -Z; |
621 | MagRawVector.Z = -Y; |
621 | MagRawVector.Z = -Y; |
622 | break; |
622 | break; |
623 | } |
623 | } |
624 | } |
624 | } |
625 | if(Compass_CalState || !NCMAG_IsCalibrated) |
625 | if(Compass_CalState || !NCMAG_IsCalibrated) |
626 | { // mark out data invalid |
626 | { // mark out data invalid |
627 | MagVector.X = MagRawVector.X; |
627 | MagVector.X = MagRawVector.X; |
628 | MagVector.Y = MagRawVector.Y; |
628 | MagVector.Y = MagRawVector.Y; |
629 | MagVector.Z = MagRawVector.Z; |
629 | MagVector.Z = MagRawVector.Z; |
630 | Compass_Heading = -1; |
630 | Compass_Heading = -1; |
631 | } |
631 | } |
632 | else |
632 | else |
633 | { |
633 | { |
634 | // update MagVector from MagRaw Vector by Scaling |
634 | // update MagVector from MagRaw Vector by Scaling |
635 | MagVector.X = (s16)((1024L*(s32)(MagRawVector.X - Calibration.MagX.Offset))/Calibration.MagX.Range); |
635 | MagVector.X = (s16)((1024L*(s32)(MagRawVector.X - Calibration.MagX.Offset))/Calibration.MagX.Range); |
636 | MagVector.Y = (s16)((1024L*(s32)(MagRawVector.Y - Calibration.MagY.Offset))/Calibration.MagY.Range); |
636 | MagVector.Y = (s16)((1024L*(s32)(MagRawVector.Y - Calibration.MagY.Offset))/Calibration.MagY.Range); |
637 | MagVector.Z = (s16)((1024L*(s32)(MagRawVector.Z - Calibration.MagZ.Offset))/Calibration.MagZ.Range); |
637 | MagVector.Z = (s16)((1024L*(s32)(MagRawVector.Z - Calibration.MagZ.Offset))/Calibration.MagZ.Range); |
638 | Compass_CalcHeading(); |
638 | Compass_CalcHeading(); |
639 | } |
639 | } |
640 | } |
640 | } |
641 | // rx data handler for acceleration raw data |
641 | // rx data handler for acceleration raw data |
642 | void NCMAG_UpdateAccVector(u8* pRxBuffer, u8 RxBufferSize) |
642 | void NCMAG_UpdateAccVector(u8* pRxBuffer, u8 RxBufferSize) |
643 | { // if number of bytes are matching |
643 | { // if number of bytes are matching |
644 | if(RxBufferSize == sizeof(AccRawVector) ) |
644 | if(RxBufferSize == sizeof(AccRawVector) ) |
645 | { |
645 | { |
646 | // copy from I2C buffer |
646 | // copy from I2C buffer |
647 | memcpy((u8*)&AccRawVector, pRxBuffer,sizeof(AccRawVector)); |
647 | memcpy((u8*)&AccRawVector, pRxBuffer,sizeof(AccRawVector)); |
648 | // scale and update Acc Vector, at the moment simply 1:1 |
648 | // scale and update Acc Vector, at the moment simply 1:1 |
649 | memcpy((u8*)&AccVector, (u8*)&AccRawVector,sizeof(AccRawVector)); |
649 | memcpy((u8*)&AccVector, (u8*)&AccRawVector,sizeof(AccRawVector)); |
650 | } |
650 | } |
651 | } |
651 | } |
652 | // rx data handler for reading magnetic sensor configuration |
652 | // rx data handler for reading magnetic sensor configuration |
653 | void NCMAG_UpdateMagConfig(u8* pRxBuffer, u8 RxBufferSize) |
653 | void NCMAG_UpdateMagConfig(u8* pRxBuffer, u8 RxBufferSize) |
654 | { // if number of byte are matching |
654 | { // if number of byte are matching |
655 | if(RxBufferSize == sizeof(MagConfig) ) |
655 | if(RxBufferSize == sizeof(MagConfig) ) |
656 | { |
656 | { |
657 | memcpy((u8*)(&MagConfig), pRxBuffer, sizeof(MagConfig)); |
657 | memcpy((u8*)(&MagConfig), pRxBuffer, sizeof(MagConfig)); |
658 | } |
658 | } |
659 | } |
659 | } |
660 | // rx data handler for reading acceleration sensor configuration |
660 | // rx data handler for reading acceleration sensor configuration |
661 | void NCMAG_UpdateAccConfig(u8* pRxBuffer, u8 RxBufferSize) |
661 | void NCMAG_UpdateAccConfig(u8* pRxBuffer, u8 RxBufferSize) |
662 | { // if number of byte are matching |
662 | { // if number of byte are matching |
663 | if(RxBufferSize == sizeof(AccConfig) ) |
663 | if(RxBufferSize == sizeof(AccConfig) ) |
664 | { |
664 | { |
665 | memcpy((u8*)&AccConfig, pRxBuffer, sizeof(AccConfig)); |
665 | memcpy((u8*)&AccConfig, pRxBuffer, sizeof(AccConfig)); |
666 | } |
666 | } |
667 | } |
667 | } |
668 | //---------------------------------------------------------------------- |
668 | //---------------------------------------------------------------------- |
669 | 669 | ||
670 | u8 NCMAG_GetOrientationFromAcc(void) |
670 | u8 NCMAG_GetOrientationFromAcc(void) |
671 | { |
671 | { |
672 | // only if external compass connected |
672 | // only if external compass connected |
673 | if(!NCMAG_Compass_use_Orientation) return(0); |
673 | if(!NCMAG_Compass_use_Orientation) return(0); |
674 | // MK must not be tilted |
674 | // MK must not be tilted |
675 | if((abs(FromFlightCtrl.AngleNick) > 300) || (abs(FromFlightCtrl.AngleRoll) > 300)) |
675 | if((abs(FromFlightCtrl.AngleNick) > 300) || (abs(FromFlightCtrl.AngleRoll) > 300)) |
676 | { |
676 | { |
677 | // UART1_PutString("\r\nTilted"); |
677 | // UART1_PutString("\r\nTilted"); |
678 | return(0); |
678 | return(0); |
679 | } |
679 | } |
680 | if(NCMAG_SensorType == TYPE_LSM303D) return(2); // der Sensor muss immer so verbaut sein, weil der interne ACC manchmal spinnt |
680 | if(NCMAG_SensorType == TYPE_LSM303D) return(2); // der Sensor muss immer so verbaut sein, weil der interne ACC manchmal spinnt |
681 | 681 | ||
682 | if(abs(AccRawVector.Z) + abs(AccRawVector.X) + abs(AccRawVector.Y) > 9000) return(0); // sensor defekt? |
682 | if(abs(AccRawVector.Z) + abs(AccRawVector.X) + abs(AccRawVector.Y) > 9000) return(0); // sensor defekt? |
683 | // select orientation |
683 | // select orientation |
684 | if(AccRawVector.Z > 3300) return(1); // Flach - Bestückung oben - Pfeil nach vorn |
684 | if(AccRawVector.Z > 3300) return(1); // Flach - Bestückung oben - Pfeil nach vorn |
685 | else |
685 | else |
686 | if(AccRawVector.Z < -3300) return(2); // Flach - Bestückung unten - Pfeil nach vorn |
686 | if(AccRawVector.Z < -3300) return(2); // Flach - Bestückung unten - Pfeil nach vorn |
687 | else |
687 | else |
688 | if(AccRawVector.X > 3300) return(3); // Flach - Bestückung Links - Pfeil nach vorn |
688 | if(AccRawVector.X > 3300) return(3); // Flach - Bestückung Links - Pfeil nach vorn |
689 | else |
689 | else |
690 | if(AccRawVector.X < -3300) return(4); // Flach - Bestückung rechts - Pfeil nach vorn |
690 | if(AccRawVector.X < -3300) return(4); // Flach - Bestückung rechts - Pfeil nach vorn |
691 | else |
691 | else |
692 | if(AccRawVector.Y > 3300) return(5); // Stehend - Pfeil nach oben - 'front' nach vorn |
692 | if(AccRawVector.Y > 3300) return(5); // Stehend - Pfeil nach oben - 'front' nach vorn |
693 | else |
693 | else |
694 | if(AccRawVector.Y < -3300) return(6); // Stehend - Pfeil nach unten - 'front' nach vorn |
694 | if(AccRawVector.Y < -3300) return(6); // Stehend - Pfeil nach unten - 'front' nach vorn |
695 | 695 | ||
696 | return(0); |
696 | return(0); |
697 | } |
697 | } |
698 | 698 | ||
699 | // --------------------------------------------------------------------- |
699 | // --------------------------------------------------------------------- |
700 | u8 NCMAG_SetMagConfig(void) |
700 | u8 NCMAG_SetMagConfig(void) |
701 | { |
701 | { |
702 | u8 retval = 0; |
702 | u8 retval = 0; |
703 | 703 | ||
704 | // try to catch the i2c buffer within 100 ms timeout |
704 | // try to catch the i2c buffer within 100 ms timeout |
705 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
705 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
706 | { |
706 | { |
707 | if(NCMAG_SensorType == TYPE_LSM303D) |
707 | if(NCMAG_SensorType == TYPE_LSM303D) |
708 | { |
708 | { |
709 | u8 TxBytes = 0; |
709 | u8 TxBytes = 0; |
710 | u8 CfgData[] = { REG_303D_CTRL0 | REG_MASK_AUTOINCREMENT, |
710 | u8 CfgData[] = { REG_303D_CTRL0 | REG_MASK_AUTOINCREMENT, |
711 | 0, // Ctrl 0 -> Fifo |
711 | 0, // Ctrl 0 -> Fifo |
712 | LSM303D_ACC_RATE_50HZ, // Ctrl 1 -> ACC Update Speed |
712 | LSM303D_ACC_RATE_50HZ, // Ctrl 1 -> ACC Update Speed |
713 | LSM303D_ACC_SCALE_8g, // Ctrl 2 -> ACC Gain + Filter (0 = 773Hz) |
713 | LSM303D_ACC_SCALE_8g, // Ctrl 2 -> ACC Gain + Filter (0 = 773Hz) |
714 | 0, // Ctrl 3 -> Interrupts |
714 | 0, // Ctrl 3 -> Interrupts |
715 | 0, // Ctrl 4 -> Interrupts |
715 | 0, // Ctrl 4 -> Interrupts |
716 | LSM303D_ODR_RATE_50HZ | LSM303D_TEMP_ENABLE | LSM303D_LOW_RESULUTION,// Ctrl 5 -> Temperature Enable + Magn.Resolution + Magn.Rate |
716 | LSM303D_ODR_RATE_50HZ | LSM303D_TEMP_ENABLE | LSM303D_LOW_RESULUTION,// Ctrl 5 -> Temperature Enable + Magn.Resolution + Magn.Rate |
717 | LSM303D_MAG_SCALE_8GA, // Ctrl 6 -> Magn. Scale |
717 | LSM303D_MAG_SCALE_8GA, // Ctrl 6 -> Magn. Scale |
718 | 0x80 // Ctrl 7 -> Magn. PowerDown + Filter |
718 | 0x80 // Ctrl 7 -> Magn. PowerDown + Filter |
719 | }; |
719 | }; |
720 | 720 | ||
721 | TxBytes = sizeof(CfgData); |
721 | TxBytes = sizeof(CfgData); |
722 | 722 | ||
723 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, CfgData, TxBytes, 0, 0)) |
723 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, CfgData, TxBytes, 0, 0)) |
724 | { |
724 | { |
725 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
725 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
726 | { |
726 | { |
727 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
727 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
728 | } |
728 | } |
729 | } |
729 | } |
730 | } |
730 | } |
731 | else |
731 | else |
732 | { |
732 | { |
733 | u8 TxBytes = 0; |
733 | u8 TxBytes = 0; |
734 | u8 TxData[sizeof(MagConfig) + 3]; |
734 | u8 TxData[sizeof(MagConfig) + 3]; |
735 | 735 | ||
736 | TxData[TxBytes++] = REG_MAG_CRA; |
736 | TxData[TxBytes++] = REG_MAG_CRA; |
737 | memcpy(&TxData[TxBytes], (u8*)&MagConfig, sizeof(MagConfig)); |
737 | memcpy(&TxData[TxBytes], (u8*)&MagConfig, sizeof(MagConfig)); |
738 | TxBytes += sizeof(MagConfig); |
738 | TxBytes += sizeof(MagConfig); |
739 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, 0, 0)) |
739 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, 0, 0)) |
740 | { |
740 | { |
741 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
741 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
742 | { |
742 | { |
743 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
743 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
744 | } |
744 | } |
745 | } |
745 | } |
746 | } |
746 | } |
747 | } |
747 | } |
748 | return(retval); |
748 | return(retval); |
749 | } |
749 | } |
750 | 750 | ||
751 | // ---------------------------------------------------------------------------------------- |
751 | // ---------------------------------------------------------------------------------------- |
752 | /* |
752 | /* |
753 | u8 NCMAG_GetMagConfig(void) |
753 | u8 NCMAG_GetMagConfig(void) |
754 | { |
754 | { |
755 | u8 retval = 0; |
755 | u8 retval = 0; |
756 | // try to catch the i2c buffer within 100 ms timeout |
756 | // try to catch the i2c buffer within 100 ms timeout |
757 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
757 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
758 | { |
758 | { |
759 | u8 TxBytes = 0; |
759 | u8 TxBytes = 0; |
760 | u8 TxData[3]; |
760 | u8 TxData[3]; |
761 | TxData[TxBytes++] = REG_MAG_CRA; |
761 | TxData[TxBytes++] = REG_MAG_CRA; |
762 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateMagConfig, sizeof(MagConfig))) |
762 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateMagConfig, sizeof(MagConfig))) |
763 | { |
763 | { |
764 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
764 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
765 | { |
765 | { |
766 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
766 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
767 | } |
767 | } |
768 | } |
768 | } |
769 | } |
769 | } |
770 | return(retval); |
770 | return(retval); |
771 | } |
771 | } |
772 | */ |
772 | */ |
773 | // ---------------------------------------------------------------------------------------- |
773 | // ---------------------------------------------------------------------------------------- |
774 | u8 NCMAG_SetAccConfig(void) |
774 | u8 NCMAG_SetAccConfig(void) |
775 | { |
775 | { |
776 | u8 retval = 0; |
776 | u8 retval = 0; |
777 | // try to catch the i2c buffer within 50 ms timeout |
777 | // try to catch the i2c buffer within 50 ms timeout |
778 | if(I2CBus_LockBuffer(Compass_I2CPort, 50)) |
778 | if(I2CBus_LockBuffer(Compass_I2CPort, 50)) |
779 | { |
779 | { |
780 | u8 TxBytes = 0; |
780 | u8 TxBytes = 0; |
781 | u8 TxData[sizeof(AccConfig) + 3]; |
781 | u8 TxData[sizeof(AccConfig) + 3]; |
782 | TxData[TxBytes++] = REG_ACC_CTRL1|REG_MASK_AUTOINCREMENT; |
782 | TxData[TxBytes++] = REG_ACC_CTRL1|REG_MASK_AUTOINCREMENT; |
783 | memcpy(&TxData[TxBytes], (u8*)&AccConfig, sizeof(AccConfig)); |
783 | memcpy(&TxData[TxBytes], (u8*)&AccConfig, sizeof(AccConfig)); |
784 | TxBytes += sizeof(AccConfig); |
784 | TxBytes += sizeof(AccConfig); |
785 | if(I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, 0, 0)) |
785 | if(I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, 0, 0)) |
786 | { |
786 | { |
787 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 50)) |
787 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 50)) |
788 | { |
788 | { |
789 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
789 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
790 | } |
790 | } |
791 | } |
791 | } |
792 | } |
792 | } |
793 | return(retval); |
793 | return(retval); |
794 | } |
794 | } |
795 | 795 | ||
796 | // ---------------------------------------------------------------------------------------- |
796 | // ---------------------------------------------------------------------------------------- |
797 | u8 NCMAG_GetAccConfig(void) |
797 | u8 NCMAG_GetAccConfig(void) |
798 | { |
798 | { |
799 | u8 retval = 0; |
799 | u8 retval = 0; |
800 | // try to catch the i2c buffer within 100 ms timeout |
800 | // try to catch the i2c buffer within 100 ms timeout |
801 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
801 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
802 | { |
802 | { |
803 | u8 TxBytes = 0; |
803 | u8 TxBytes = 0; |
804 | u8 TxData[3]; |
804 | u8 TxData[3]; |
805 | TxData[TxBytes++] = REG_ACC_CTRL1|REG_MASK_AUTOINCREMENT; |
805 | TxData[TxBytes++] = REG_ACC_CTRL1|REG_MASK_AUTOINCREMENT; |
806 | if(I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccConfig, sizeof(AccConfig))) |
806 | if(I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccConfig, sizeof(AccConfig))) |
807 | { |
807 | { |
808 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
808 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
809 | { |
809 | { |
810 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
810 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
811 | } |
811 | } |
812 | } |
812 | } |
813 | } |
813 | } |
814 | return(retval); |
814 | return(retval); |
815 | } |
815 | } |
816 | 816 | ||
817 | // ---------------------------------------------------------------------------------------- |
817 | // ---------------------------------------------------------------------------------------- |
818 | u8 NCMAG_GetIdentification(void) |
818 | u8 NCMAG_GetIdentification(void) |
819 | { |
819 | { |
820 | u8 retval = 0; |
820 | u8 retval = 0; |
821 | if(NCMAG_SensorType == TYPE_LSM303D) return(1); |
821 | if(NCMAG_SensorType == TYPE_LSM303D) return(1); |
822 | // try to catch the i2c buffer within 100 ms timeout |
822 | // try to catch the i2c buffer within 100 ms timeout |
823 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
823 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
824 | { |
824 | { |
825 | u8 TxBytes = 0; |
825 | u8 TxBytes = 0; |
826 | u8 TxData[3]; |
826 | u8 TxData[3]; |
827 | NCMAG_Identification.A = 0xFF; |
827 | NCMAG_Identification.A = 0xFF; |
828 | NCMAG_Identification.B = 0xFF; |
828 | NCMAG_Identification.B = 0xFF; |
829 | NCMAG_Identification.C = 0xFF; |
829 | NCMAG_Identification.C = 0xFF; |
830 | TxData[TxBytes++] = REG_MAG_IDA; |
830 | TxData[TxBytes++] = REG_MAG_IDA; |
831 | // initiate transmission |
831 | // initiate transmission |
832 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateIdentification, sizeof(NCMAG_Identification))) |
832 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateIdentification, sizeof(NCMAG_Identification))) |
833 | { |
833 | { |
834 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
834 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
835 | { |
835 | { |
836 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
836 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
837 | } |
837 | } |
838 | } |
838 | } |
839 | } |
839 | } |
840 | return(retval); |
840 | return(retval); |
841 | } |
841 | } |
842 | 842 | ||
843 | u8 NCMAG_GetIdentification_Sub(void) |
843 | u8 NCMAG_GetIdentification_Sub(void) |
844 | { |
844 | { |
845 | u8 retval = 0; |
845 | u8 retval = 0; |
846 | // try to catch the i2c buffer within 100 ms timeout |
846 | // try to catch the i2c buffer within 100 ms timeout |
847 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
847 | if(I2CBus_LockBuffer(Compass_I2CPort, 100)) |
848 | { |
848 | { |
849 | u8 TxBytes = 0; |
849 | u8 TxBytes = 0; |
850 | u8 TxData[3]; |
850 | u8 TxData[3]; |
851 | NCMAG_Identification2.Sub = 0xFF; |
851 | NCMAG_Identification2.Sub = 0xFF; |
852 | TxData[TxBytes++] = REG_MAG_IDF; |
852 | TxData[TxBytes++] = REG_MAG_IDF; |
853 | // initiate transmission |
853 | // initiate transmission |
854 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateIdentification_Sub, sizeof(NCMAG_Identification2))) |
854 | if(I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateIdentification_Sub, sizeof(NCMAG_Identification2))) |
855 | { |
855 | { |
856 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
856 | if(I2CBus_WaitForEndOfTransmission(Compass_I2CPort, 100)) |
857 | { |
857 | { |
858 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
858 | if(I2CBus(Compass_I2CPort)->Error == I2C_ERROR_NONE) retval = 1; |
859 | } |
859 | } |
860 | } |
860 | } |
861 | } |
861 | } |
862 | return(retval); |
862 | return(retval); |
863 | } |
863 | } |
864 | 864 | ||
865 | 865 | ||
866 | // ---------------------------------------------------------------------------------------- |
866 | // ---------------------------------------------------------------------------------------- |
867 | void NCMAG_GetMagVector(u8 timeout) |
867 | void NCMAG_GetMagVector(u8 timeout) |
868 | { |
868 | { |
869 | // try to catch the I2C buffer within timeout ms |
869 | // try to catch the I2C buffer within timeout ms |
870 | if(I2CBus_LockBuffer(Compass_I2CPort, timeout)) |
870 | if(I2CBus_LockBuffer(Compass_I2CPort, timeout)) |
871 | { |
871 | { |
872 | u8 TxBytes = 0; |
872 | u8 TxBytes = 0; |
873 | u8 TxData[3]; |
873 | u8 TxData[3]; |
874 | // set register pointer |
874 | // set register pointer |
875 | if(NCMAG_SensorType == TYPE_LSM303D) TxData[TxBytes++] = ADR_LSM303D_MAG | REG_MASK_AUTOINCREMENT; |
875 | if(NCMAG_SensorType == TYPE_LSM303D) TxData[TxBytes++] = ADR_LSM303D_MAG | REG_MASK_AUTOINCREMENT; |
876 | else TxData[TxBytes++] = REG_MAG_DATAX_MSB; |
876 | else TxData[TxBytes++] = REG_MAG_DATAX_MSB; |
877 | // initiate transmission |
877 | // initiate transmission |
878 | I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateMagVector, sizeof(MagVector)); |
878 | I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateMagVector, sizeof(MagVector)); |
879 | } |
879 | } |
880 | } |
880 | } |
881 | 881 | ||
882 | //---------------------------------------------------------------- |
882 | //---------------------------------------------------------------- |
883 | void NCMAG_GetAccVector(u8 timeout) |
883 | void NCMAG_GetAccVector(u8 timeout) |
884 | { |
884 | { |
885 | // try to catch the I2C buffer within timeout ms |
885 | // try to catch the I2C buffer within timeout ms |
886 | if(I2CBus_LockBuffer(Compass_I2CPort, timeout)) |
886 | if(I2CBus_LockBuffer(Compass_I2CPort, timeout)) |
887 | { |
887 | { |
888 | u8 TxBytes = 0; |
888 | u8 TxBytes = 0; |
889 | u8 TxData[3]; |
889 | u8 TxData[3]; |
890 | // set register pointer |
890 | // set register pointer |
891 | if(NCMAG_SensorType == TYPE_LSM303D) |
891 | if(NCMAG_SensorType == TYPE_LSM303D) |
892 | { |
892 | { |
893 | TxData[TxBytes++] = REG_ACC_X_LSB | REG_MASK_AUTOINCREMENT; |
893 | TxData[TxBytes++] = REG_ACC_X_LSB | REG_MASK_AUTOINCREMENT; |
894 | I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector)); |
894 | I2CBus_Transmission(Compass_I2CPort, MAG_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector)); |
895 | } |
895 | } |
896 | else |
896 | else |
897 | { |
897 | { |
898 | TxData[TxBytes++] = REG_ACC_X_LSB | REG_MASK_AUTOINCREMENT; |
898 | TxData[TxBytes++] = REG_ACC_X_LSB | REG_MASK_AUTOINCREMENT; |
899 | // initiate transmission |
899 | // initiate transmission |
900 | I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector)); |
900 | I2CBus_Transmission(Compass_I2CPort, ACC_SLAVE_ADDRESS, TxData, TxBytes, &NCMAG_UpdateAccVector, sizeof(AccRawVector)); |
901 | } |
901 | } |
902 | } |
902 | } |
903 | } |
903 | } |
904 | 904 | ||
905 | //---------------------------------------------------------------- |
905 | //---------------------------------------------------------------- |
906 | u8 NCMAG_ConfigureSensor(void) |
906 | u8 NCMAG_ConfigureSensor(void) |
907 | { |
907 | { |
908 | switch(NCMAG_SensorType) |
908 | switch(NCMAG_SensorType) |
909 | { |
909 | { |
910 | case TYPE_HMC5843: |
910 | case TYPE_HMC5843: |
911 | MagConfig.cra = HMC5843_CRA_RATE_50HZ|CRA_MODE_NORMAL; |
911 | MagConfig.cra = HMC5843_CRA_RATE_50HZ|CRA_MODE_NORMAL; |
912 | MagConfig.crb = HMC5843_CRB_GAIN_15GA; |
912 | MagConfig.crb = HMC5843_CRB_GAIN_15GA; |
913 | MagConfig.mode = MODE_CONTINUOUS; |
913 | MagConfig.mode = MODE_CONTINUOUS; |
914 | break; |
914 | break; |
915 | 915 | ||
916 | case TYPE_LSM303DLH: |
916 | case TYPE_LSM303DLH: |
917 | case TYPE_LSM303DLM: |
917 | case TYPE_LSM303DLM: |
918 | // MagConfig.crb = LSM303DLH_CRB_GAIN_19GA; |
918 | // MagConfig.crb = LSM303DLH_CRB_GAIN_19GA; |
919 | MagConfig.crb = LSM303DLH_CRB_GAIN_40GA; // seit 2.03 -> 2.2014 |
919 | MagConfig.crb = LSM303DLH_CRB_GAIN_40GA; // seit 2.03 -> 2.2014 |
920 | MagConfig.cra = LSM303DLH_CRA_RATE_75HZ|CRA_MODE_NORMAL; |
920 | MagConfig.cra = LSM303DLH_CRA_RATE_75HZ|CRA_MODE_NORMAL; |
921 | MagConfig.mode = MODE_CONTINUOUS; |
921 | MagConfig.mode = MODE_CONTINUOUS; |
922 | break; |
922 | break; |
923 | case TYPE_LSM303D: |
923 | case TYPE_LSM303D: |
924 | // -> see defined data in NCMAG_SetMagConfig(); |
924 | // -> see defined data in NCMAG_SetMagConfig(); |
925 | break; |
925 | break; |
926 | default: |
926 | default: |
927 | return(0); |
927 | return(0); |
928 | } |
928 | } |
929 | return(NCMAG_SetMagConfig()); |
929 | return(NCMAG_SetMagConfig()); |
930 | } |
930 | } |
931 | 931 | ||
932 | 932 | ||
933 | //---------------------------------------------------------------- |
933 | //---------------------------------------------------------------- |
934 | u8 NCMAG_Init_ACCSensor(void) |
934 | u8 NCMAG_Init_ACCSensor(void) |
935 | { |
935 | { |
936 | if(NCMAG_SensorType == TYPE_LSM303D) |
936 | if(NCMAG_SensorType == TYPE_LSM303D) |
937 | { |
937 | { |
938 | return(NCMAG_SetMagConfig()); |
938 | return(NCMAG_SetMagConfig()); |
939 | } |
939 | } |
940 | else |
940 | else |
941 | { |
941 | { |
942 | AccConfig.ctrl_1 = ACC_CRTL1_PM_NORMAL|ACC_CRTL1_DR_50HZ|ACC_CRTL1_XEN|ACC_CRTL1_YEN|ACC_CRTL1_ZEN; |
942 | AccConfig.ctrl_1 = ACC_CRTL1_PM_NORMAL|ACC_CRTL1_DR_50HZ|ACC_CRTL1_XEN|ACC_CRTL1_YEN|ACC_CRTL1_ZEN; |
943 | AccConfig.ctrl_2 = 0; |
943 | AccConfig.ctrl_2 = 0; |
944 | AccConfig.ctrl_3 = 0x00; |
944 | AccConfig.ctrl_3 = 0x00; |
945 | AccConfig.ctrl_4 = ACC_CTRL4_BDU | ACC_CTRL4_FS_8G; |
945 | AccConfig.ctrl_4 = ACC_CTRL4_BDU | ACC_CTRL4_FS_8G; |
946 | AccConfig.ctrl_5 = ACC_CTRL5_STW_OFF; |
946 | AccConfig.ctrl_5 = ACC_CTRL5_STW_OFF; |
947 | return(NCMAG_SetAccConfig()); |
947 | return(NCMAG_SetAccConfig()); |
948 | } |
948 | } |
949 | } |
949 | } |
950 | // -------------------------------------------------------- |
950 | // -------------------------------------------------------- |
951 | void NCMAG_Update(u8 init) |
951 | void NCMAG_Update(u8 init) |
952 | { |
952 | { |
953 | static u32 TimerUpdate = 0; |
953 | static u32 TimerUpdate = 0; |
954 | static s8 send_config = 0; |
954 | static s8 send_config = 0; |
955 | u32 delay = 20; |
955 | u32 delay = 20; |
956 | 956 | ||
957 | if(init) TimerUpdate = SetDelay(10); |
957 | if(init) TimerUpdate = SetDelay(10); |
958 | 958 | ||
959 | if( (I2CBus(Compass_I2CPort)->State == I2C_STATE_UNDEF) /*|| !NCMAG_Present*/ ) |
959 | if( (I2CBus(Compass_I2CPort)->State == I2C_STATE_UNDEF) /*|| !NCMAG_Present*/ ) |
960 | { |
960 | { |
961 | Compass_Heading = -1; |
961 | Compass_Heading = -1; |
962 | DebugOut.Analog[14]++; // count I2C error |
962 | DebugOut.Analog[14]++; // count I2C error |
963 | TimerUpdate = SetDelay(10); |
963 | TimerUpdate = SetDelay(10); |
964 | return; |
964 | return; |
965 | } |
965 | } |
966 | if(CheckDelay(TimerUpdate)) |
966 | if(CheckDelay(TimerUpdate)) |
967 | { |
967 | { |
968 | if(Compass_Heading != -1) send_config = 0; // no re-configuration if value is valid |
968 | if(Compass_Heading != -1) send_config = 0; // no re-configuration if value is valid |
969 | if(++send_config == 25) // 500ms |
969 | if(++send_config == 25) // 500ms |
970 | { |
970 | { |
971 | send_config = -25; // next try after 1 second |
971 | send_config = -25; // next try after 1 second |
972 | NCMAG_ConfigureSensor(); |
972 | NCMAG_ConfigureSensor(); |
973 | TimerUpdate = SetDelay(20); // back into the old time-slot |
973 | TimerUpdate = SetDelay(20); // back into the old time-slot |
974 | } |
974 | } |
975 | else |
975 | else |
976 | { |
976 | { |
977 | static u8 s = 0; |
977 | static u8 s = 0; |
978 | // check for new calibration state |
978 | // check for new calibration state |
979 | Compass_UpdateCalState(); |
979 | Compass_UpdateCalState(); |
980 | if(Compass_CalState) NCMAG_Calibrate(); |
980 | if(Compass_CalState) NCMAG_Calibrate(); |
981 | 981 | ||
982 | // in case of LSM303 type |
982 | // in case of LSM303 type |
983 | switch(NCMAG_SensorType) |
983 | switch(NCMAG_SensorType) |
984 | { |
984 | { |
985 | case TYPE_HMC5843: |
985 | case TYPE_HMC5843: |
986 | delay = 20; // next cycle after 20 ms |
986 | delay = 20; // next cycle after 20 ms |
987 | NCMAG_GetMagVector(5); |
987 | NCMAG_GetMagVector(5); |
988 | break; |
988 | break; |
989 | case TYPE_LSM303DLH: |
989 | case TYPE_LSM303DLH: |
990 | case TYPE_LSM303DLM: |
990 | case TYPE_LSM303DLM: |
991 | case TYPE_LSM303D: |
991 | case TYPE_LSM303D: |
992 | delay = 20; // next cycle after 20 ms |
992 | delay = 20; // next cycle after 20 ms |
993 | if(s-- || (NCMAG_Compass_use_Orientation == 0)) |
993 | if(s-- || (NCMAG_Compass_use_Orientation == 0)) |
994 | { |
994 | { |
995 | NCMAG_GetMagVector(5); |
995 | NCMAG_GetMagVector(5); |
996 | } |
996 | } |
997 | else // having an external compass, read every 50th cycle the ACC vec |
997 | else // having an external compass, read every 50th cycle the ACC vec |
998 | { // try to initialize if no data are there |
998 | { // try to initialize if no data are there |
999 | if((AccRawVector.X + AccRawVector.Y + AccRawVector.Z) == 0) NCMAG_Init_ACCSensor(); |
999 | if((AccRawVector.X + AccRawVector.Y + AccRawVector.Z) == 0) NCMAG_Init_ACCSensor(); |
1000 | // get new data |
1000 | // get new data |
1001 | NCMAG_GetAccVector(5); |
1001 | NCMAG_GetAccVector(5); |
1002 | delay = 10; // next cycle after 10 ms |
1002 | delay = 10; // next cycle after 10 ms |
1003 | s = 40; //reset downconter about 0,8 sec |
1003 | s = 40; //reset downconter about 0,8 sec |
1004 | /* |
1004 | /* |
1005 | DebugOut.Analog[] = AccVector.X; |
1005 | DebugOut.Analog[] = AccVector.X; |
1006 | DebugOut.Analog[] = AccVector.Y; |
1006 | DebugOut.Analog[] = AccVector.Y; |
1007 | DebugOut.Analog[] = AccVector.Z; |
1007 | DebugOut.Analog[] = AccVector.Z; |
1008 | //s = 2; |
1008 | //s = 2; |
1009 | */ |
1009 | */ |
1010 | } |
1010 | } |
1011 | break; |
1011 | break; |
1012 | } |
1012 | } |
1013 | if(send_config == 24) TimerUpdate = SetDelay(15); // next event is the re-configuration |
1013 | if(send_config == 24) TimerUpdate = SetDelay(15); // next event is the re-configuration |
1014 | else TimerUpdate = SetDelay(delay); // every 20 ms are 50 Hz |
1014 | else TimerUpdate = SetDelay(delay); // every 20 ms are 50 Hz |
1015 | } |
1015 | } |
1016 | } |
1016 | } |
1017 | } |
1017 | } |
1018 | 1018 | ||
1019 | 1019 | ||
1020 | // -------------------------------------------------------- |
1020 | // -------------------------------------------------------- |
1021 | u8 NCMAG_SelfTest(void) |
1021 | u8 NCMAG_SelfTest(void) |
1022 | { |
1022 | { |
1023 | u8 msg[64]; |
1023 | u8 msg[64]; |
1024 | static u8 done = 0; |
1024 | static u8 done = 0; |
1025 | 1025 | ||
1026 | if(done) return(1); // just make it once |
1026 | if(done) return(1); // just make it once |
1027 | 1027 | ||
1028 | #define LIMITS(value, min, max) {min = (80 * value)/100; max = (120 * value)/100;} |
1028 | #define LIMITS(value, min, max) {min = (80 * value)/100; max = (120 * value)/100;} |
1029 | u32 time; |
1029 | u32 time; |
1030 | s32 XMin = 0, XMax = 0, YMin = 0, YMax = 0, ZMin = 0, ZMax = 0; |
1030 | s32 XMin = 0, XMax = 0, YMin = 0, YMax = 0, ZMin = 0, ZMax = 0; |
1031 | s16 xscale, yscale, zscale, scale_min, scale_max; |
1031 | s16 xscale, yscale, zscale, scale_min, scale_max; |
1032 | u8 crb_gain, cra_rate; |
1032 | u8 crb_gain, cra_rate; |
1033 | u8 i = 0, retval = 1; |
1033 | u8 i = 0, retval = 1; |
1034 | 1034 | ||
1035 | switch(NCMAG_SensorType) |
1035 | switch(NCMAG_SensorType) |
1036 | { |
1036 | { |
1037 | case TYPE_HMC5843: |
1037 | case TYPE_HMC5843: |
1038 | crb_gain = HMC5843_CRB_GAIN_15GA; |
1038 | crb_gain = HMC5843_CRB_GAIN_15GA; |
1039 | cra_rate = HMC5843_CRA_RATE_50HZ; |
1039 | cra_rate = HMC5843_CRA_RATE_50HZ; |
1040 | xscale = HMC5843_TEST_XSCALE; |
1040 | xscale = HMC5843_TEST_XSCALE; |
1041 | yscale = HMC5843_TEST_YSCALE; |
1041 | yscale = HMC5843_TEST_YSCALE; |
1042 | zscale = HMC5843_TEST_ZSCALE; |
1042 | zscale = HMC5843_TEST_ZSCALE; |
1043 | break; |
1043 | break; |
1044 | 1044 | ||
1045 | case TYPE_LSM303DLH: |
1045 | case TYPE_LSM303DLH: |
1046 | // crb_gain = LSM303DLH_CRB_GAIN_19GA; |
1046 | // crb_gain = LSM303DLH_CRB_GAIN_19GA; |
1047 | crb_gain = LSM303DLH_CRB_GAIN_40GA; // seit 2.03 -> 2.2014 |
1047 | crb_gain = LSM303DLH_CRB_GAIN_40GA; // seit 2.03 -> 2.2014 |
1048 | cra_rate = LSM303DLH_CRA_RATE_75HZ; |
1048 | cra_rate = LSM303DLH_CRA_RATE_75HZ; |
1049 | xscale = LSM303DLH_TEST_XSCALE; |
1049 | xscale = LSM303DLH_TEST_XSCALE; |
1050 | yscale = LSM303DLH_TEST_YSCALE; |
1050 | yscale = LSM303DLH_TEST_YSCALE; |
1051 | zscale = LSM303DLH_TEST_ZSCALE; |
1051 | zscale = LSM303DLH_TEST_ZSCALE; |
1052 | break; |
1052 | break; |
1053 | 1053 | ||
1054 | case TYPE_LSM303DLM: |
1054 | case TYPE_LSM303DLM: |
1055 | // does not support self test feature |
1055 | // does not support self test feature |
1056 | done = 1; |
1056 | done = 1; |
1057 | return(1); // always return success |
1057 | return(1); // always return success |
1058 | break; |
1058 | break; |
1059 | case TYPE_LSM303D: |
1059 | case TYPE_LSM303D: |
1060 | done = 1; |
1060 | done = 1; |
1061 | return(1); // always return success |
1061 | return(1); // always return success |
1062 | break; |
1062 | break; |
1063 | default: |
1063 | default: |
1064 | return(0); |
1064 | return(0); |
1065 | } |
1065 | } |
1066 | 1066 | ||
1067 | MagConfig.cra = cra_rate|CRA_MODE_POSBIAS; |
1067 | MagConfig.cra = cra_rate|CRA_MODE_POSBIAS; |
1068 | MagConfig.crb = crb_gain; |
1068 | MagConfig.crb = crb_gain; |
1069 | MagConfig.mode = MODE_CONTINUOUS; |
1069 | MagConfig.mode = MODE_CONTINUOUS; |
1070 | // activate positive bias field |
1070 | // activate positive bias field |
1071 | NCMAG_SetMagConfig(); |
1071 | NCMAG_SetMagConfig(); |
1072 | // wait for stable readings |
1072 | // wait for stable readings |
1073 | time = SetDelay(50); |
1073 | time = SetDelay(50); |
1074 | while(!CheckDelay(time)); |
1074 | while(!CheckDelay(time)); |
1075 | // averaging |
1075 | // averaging |
1076 | #define AVERAGE 20 |
1076 | #define AVERAGE 20 |
1077 | for(i = 0; i<AVERAGE; i++) |
1077 | for(i = 0; i<AVERAGE; i++) |
1078 | { |
1078 | { |
1079 | NCMAG_GetMagVector(5); |
1079 | NCMAG_GetMagVector(5); |
1080 | time = SetDelay(20); |
1080 | time = SetDelay(20); |
1081 | while(!CheckDelay(time)); |
1081 | while(!CheckDelay(time)); |
1082 | XMax += MagRawVector.X; |
1082 | XMax += MagRawVector.X; |
1083 | YMax += MagRawVector.Y; |
1083 | YMax += MagRawVector.Y; |
1084 | ZMax += MagRawVector.Z; |
1084 | ZMax += MagRawVector.Z; |
1085 | } |
1085 | } |
1086 | MagConfig.cra = cra_rate|CRA_MODE_NEGBIAS; |
1086 | MagConfig.cra = cra_rate|CRA_MODE_NEGBIAS; |
1087 | // activate positive bias field |
1087 | // activate positive bias field |
1088 | NCMAG_SetMagConfig(); |
1088 | NCMAG_SetMagConfig(); |
1089 | // wait for stable readings |
1089 | // wait for stable readings |
1090 | time = SetDelay(50); |
1090 | time = SetDelay(50); |
1091 | while(!CheckDelay(time)); |
1091 | while(!CheckDelay(time)); |
1092 | // averaging |
1092 | // averaging |
1093 | for(i = 0; i < AVERAGE; i++) |
1093 | for(i = 0; i < AVERAGE; i++) |
1094 | { |
1094 | { |
1095 | NCMAG_GetMagVector(5); |
1095 | NCMAG_GetMagVector(5); |
1096 | time = SetDelay(20); |
1096 | time = SetDelay(20); |
1097 | while(!CheckDelay(time)); |
1097 | while(!CheckDelay(time)); |
1098 | XMin += MagRawVector.X; |
1098 | XMin += MagRawVector.X; |
1099 | YMin += MagRawVector.Y; |
1099 | YMin += MagRawVector.Y; |
1100 | ZMin += MagRawVector.Z; |
1100 | ZMin += MagRawVector.Z; |
1101 | } |
1101 | } |
1102 | // setup final configuration |
1102 | // setup final configuration |
1103 | MagConfig.cra = cra_rate|CRA_MODE_NORMAL; |
1103 | MagConfig.cra = cra_rate|CRA_MODE_NORMAL; |
1104 | // activate positive bias field |
1104 | // activate positive bias field |
1105 | NCMAG_SetMagConfig(); |
1105 | NCMAG_SetMagConfig(); |
1106 | // check scale for all axes |
1106 | // check scale for all axes |
1107 | // prepare scale limits |
1107 | // prepare scale limits |
1108 | LIMITS(xscale, scale_min, scale_max); |
1108 | LIMITS(xscale, scale_min, scale_max); |
1109 | xscale = (XMax - XMin)/(2*AVERAGE); |
1109 | xscale = (XMax - XMin)/(2*AVERAGE); |
1110 | if((xscale > scale_max) || (xscale < scale_min)) |
1110 | if((xscale > scale_max) || (xscale < scale_min)) |
1111 | { |
1111 | { |
1112 | retval = 0; |
1112 | retval = 0; |
1113 | sprintf(msg, "\r\n Value X: %d not %d-%d !", xscale, scale_min,scale_max); |
1113 | sprintf(msg, "\r\n Value X: %d not %d-%d !", xscale, scale_min,scale_max); |
1114 | UART1_PutString(msg); |
1114 | UART1_PutString(msg); |
1115 | } |
1115 | } |
1116 | LIMITS(yscale, scale_min, scale_max); |
1116 | LIMITS(yscale, scale_min, scale_max); |
1117 | yscale = (YMax - YMin)/(2*AVERAGE); |
1117 | yscale = (YMax - YMin)/(2*AVERAGE); |
1118 | if((yscale > scale_max) || (yscale < scale_min)) |
1118 | if((yscale > scale_max) || (yscale < scale_min)) |
1119 | { |
1119 | { |
1120 | retval = 0; |
1120 | retval = 0; |
1121 | sprintf(msg, "\r\n Value Y: %d not %d-%d !", yscale, scale_min,scale_max); |
1121 | sprintf(msg, "\r\n Value Y: %d not %d-%d !", yscale, scale_min,scale_max); |
1122 | UART1_PutString(msg); |
1122 | UART1_PutString(msg); |
1123 | } |
1123 | } |
1124 | LIMITS(zscale, scale_min, scale_max); |
1124 | LIMITS(zscale, scale_min, scale_max); |
1125 | zscale = (ZMax - ZMin)/(2*AVERAGE); |
1125 | zscale = (ZMax - ZMin)/(2*AVERAGE); |
1126 | if((zscale > scale_max) || (zscale < scale_min)) |
1126 | if((zscale > scale_max) || (zscale < scale_min)) |
1127 | { |
1127 | { |
1128 | retval = 0; |
1128 | retval = 0; |
1129 | sprintf(msg, "\r\n Value Z: %d not %d-%d !", zscale, scale_min,scale_max); |
1129 | sprintf(msg, "\r\n Value Z: %d not %d-%d !", zscale, scale_min,scale_max); |
1130 | UART1_PutString(msg); |
1130 | UART1_PutString(msg); |
1131 | } |
1131 | } |
1132 | done = retval; |
1132 | done = retval; |
1133 | return(retval); |
1133 | return(retval); |
1134 | } |
1134 | } |
1135 | 1135 | ||
1136 | 1136 | ||
1137 | void NCMAG_CheckOrientation(void) |
1137 | void NCMAG_CheckOrientation(void) |
1138 | { // only for external sensor |
1138 | { // only for external sensor |
1139 | if(NCMAG_Compass_use_Orientation) |
1139 | if(NCMAG_Compass_use_Orientation) |
1140 | { |
1140 | { |
1141 | NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
1141 | NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
1142 | if(NCMAG_Orientation != (Calibration.Version>>4)) NCMAG_IsCalibrated = 0; |
1142 | if(NCMAG_Orientation != (Calibration.Version>>4)) NCMAG_IsCalibrated = 0; |
1143 | else NCMAG_IsCalibrated = 1; |
1143 | else NCMAG_IsCalibrated = 1; |
1144 | } |
1144 | } |
1145 | } |
1145 | } |
1146 | //---------------------------------------------------------------- |
1146 | //---------------------------------------------------------------- |
1147 | u8 NCMAG_Init(void) |
1147 | u8 NCMAG_Init(void) |
1148 | { |
1148 | { |
1149 | MagRawVector.X = 0; |
1149 | MagRawVector.X = 0; |
1150 | MagRawVector.Y = 0; |
1150 | MagRawVector.Y = 0; |
1151 | MagRawVector.Z = 0; |
1151 | MagRawVector.Z = 0; |
1152 | AccRawVector.X = 0; |
1152 | AccRawVector.X = 0; |
1153 | AccRawVector.Y = 0; |
1153 | AccRawVector.Y = 0; |
1154 | AccRawVector.Z = 0; |
1154 | AccRawVector.Z = 0; |
1155 | 1155 | ||
1156 | if(NCMAG_Present) // do only short init ! , full init was called before |
1156 | if(NCMAG_Present) // do only short init ! , full init was called before |
1157 | { |
1157 | { |
1158 | // reset I2C Bus |
1158 | // reset I2C Bus |
1159 | //I2CBus_Deinit(Compass_I2CPort); |
1159 | //I2CBus_Deinit(Compass_I2CPort); |
1160 | //I2CBus_Init(Compass_I2CPort); |
1160 | //I2CBus_Init(Compass_I2CPort); |
1161 | // try to reconfigure senor |
1161 | // try to reconfigure senor |
1162 | NCMAG_ConfigureSensor(); |
1162 | NCMAG_ConfigureSensor(); |
1163 | //NCMAG_Update(1); |
1163 | //NCMAG_Update(1); |
1164 | } |
1164 | } |
1165 | else // full init |
1165 | else // full init |
1166 | { |
1166 | { |
1167 | u8 msg[64]; |
1167 | u8 msg[64]; |
1168 | u8 retval = 0; |
1168 | u8 retval = 0; |
1169 | u8 repeat = 0; |
1169 | u8 repeat = 0; |
1170 | 1170 | ||
1171 | //-------------------------------------------- |
1171 | //-------------------------------------------- |
1172 | // search external sensor first |
1172 | // search external sensor first |
1173 | //-------------------------------------------- |
1173 | //-------------------------------------------- |
1174 | Compass_I2CPort = NCMAG_PORT_EXTERN; |
1174 | Compass_I2CPort = NCMAG_PORT_EXTERN; |
1175 | retval = 0; |
1175 | retval = 0; |
1176 | // get id bytes |
1176 | // get id bytes |
1177 | for(repeat = 0; repeat < 5; repeat++) |
1177 | for(repeat = 0; repeat < 5; repeat++) |
1178 | { |
1178 | { |
1179 | if(NCMAG_GetIdentification_Sub()) break; |
1179 | if(NCMAG_GetIdentification_Sub()) break; |
1180 | UART1_PutString("="); |
1180 | UART1_PutString("="); |
1181 | } |
1181 | } |
1182 | //sprintf(msg, "(WhoAmI=%02x)", NCMAG_Identification2.Sub); |
1182 | //sprintf(msg, "(WhoAmI=%02x)", NCMAG_Identification2.Sub); |
1183 | //UART1_PutString(msg); |
1183 | //UART1_PutString(msg); |
1184 | if(NCMAG_Identification2.Sub == MAG_IDF_LSM303D) |
1184 | if(NCMAG_Identification2.Sub == MAG_IDF_LSM303D) |
1185 | { |
1185 | { |
1186 | NCMAG_SensorType = TYPE_LSM303D; |
1186 | NCMAG_SensorType = TYPE_LSM303D; |
1187 | NCMAG_ConfigureSensor(); |
1187 | NCMAG_ConfigureSensor(); |
1188 | NCMAG_Compass_use_Orientation = 1; |
1188 | NCMAG_Compass_use_Orientation = 1; |
1189 | retval = 1; |
1189 | retval = 1; |
1190 | } |
1190 | } |
1191 | else |
1191 | else |
1192 | { // External Sensor not LSM303D |
1192 | { // External Sensor not LSM303D |
1193 | for(repeat = 0; repeat < 3; repeat++) // does it have ACC? |
1193 | for(repeat = 0; repeat < 3; repeat++) // does it have ACC? |
1194 | { |
1194 | { |
1195 | retval = NCMAG_GetAccConfig(); // only the external sensor with ACC is supported |
1195 | retval = NCMAG_GetAccConfig(); // only the external sensor with ACC is supported |
1196 | if(retval) break; // break loop on success |
1196 | if(retval) break; // break loop on success |
1197 | UART1_PutString("_"); |
1197 | UART1_PutString("_"); |
1198 | } |
1198 | } |
1199 | // Extenal sensor not found? |
1199 | // Extenal sensor not found? |
1200 | if(!retval) |
1200 | if(!retval) |
1201 | { |
1201 | { |
1202 | // search internal sensor afterwards |
1202 | // search internal sensor afterwards |
1203 | if(UART_VersionInfo.HWMajor >= 30) |
1203 | if(UART_VersionInfo.HWMajor >= 30) |
1204 | { |
1204 | { |
1205 | UART1_PutString(" main I2C-Bus "); |
1205 | UART1_PutString(" main I2C-Bus "); |
1206 | NCMAG_Compass_use_Orientation = 1; |
1206 | NCMAG_Compass_use_Orientation = 1; |
1207 | } |
1207 | } |
1208 | else |
1208 | else |
1209 | { |
1209 | { |
1210 | UART1_PutString(" internal sensor "); |
1210 | UART1_PutString(" internal sensor "); |
1211 | NCMAG_Compass_use_Orientation = 0; |
1211 | NCMAG_Compass_use_Orientation = 0; |
1212 | } |
1212 | } |
1213 | Compass_I2CPort = NCMAG_PORT_INTERN; |
1213 | Compass_I2CPort = NCMAG_PORT_INTERN; |
1214 | } |
1214 | } |
1215 | else |
1215 | else |
1216 | { |
1216 | { |
1217 | UART1_PutString(" external sensor "); |
1217 | UART1_PutString(" external sensor "); |
1218 | Compass_I2CPort = NCMAG_PORT_EXTERN; |
1218 | Compass_I2CPort = NCMAG_PORT_EXTERN; |
1219 | NCMAG_Compass_use_Orientation = 1; |
1219 | NCMAG_Compass_use_Orientation = 1; |
1220 | } |
1220 | } |
1221 | //------------------------------------------- |
1221 | //------------------------------------------- |
1222 | NCMAG_Present = 0; |
1222 | NCMAG_Present = 0; |
1223 | NCMAG_SensorType = TYPE_HMC5843; // assuming having an HMC5843 |
1223 | NCMAG_SensorType = TYPE_HMC5843; // assuming having an HMC5843 |
1224 | 1224 | ||
1225 | for(repeat = 0; repeat < 3; repeat++) |
1225 | for(repeat = 0; repeat < 3; repeat++) |
1226 | { |
1226 | { |
1227 | if(NCMAG_GetIdentification_Sub()) break; |
1227 | if(NCMAG_GetIdentification_Sub()) break; |
1228 | UART1_PutString("="); |
1228 | UART1_PutString("="); |
1229 | } |
1229 | } |
1230 | if(NCMAG_Identification2.Sub == MAG_IDF_LSM303D) // internal Sensor the LSM303D? |
1230 | if(NCMAG_Identification2.Sub == MAG_IDF_LSM303D) // internal Sensor the LSM303D? |
1231 | { |
1231 | { |
1232 | NCMAG_SensorType = TYPE_LSM303D; |
1232 | NCMAG_SensorType = TYPE_LSM303D; |
1233 | NCMAG_ConfigureSensor(); |
1233 | NCMAG_ConfigureSensor(); |
1234 | retval = 1; |
1234 | retval = 1; |
1235 | } |
1235 | } |
1236 | else |
1236 | else |
1237 | for(repeat = 0; repeat < 3; repeat++) // polling for LSM303DLH/DLM option by ACC address ack |
1237 | for(repeat = 0; repeat < 3; repeat++) // polling for LSM303DLH/DLM option by ACC address ack |
1238 | { |
1238 | { |
1239 | retval = NCMAG_GetAccConfig(); |
1239 | retval = NCMAG_GetAccConfig(); |
1240 | if(retval) break; // break loop on success |
1240 | if(retval) break; // break loop on success |
1241 | } |
1241 | } |
1242 | if(retval) // it is a sensor with ACC |
1242 | if(retval) // it is a sensor with ACC |
1243 | { |
1243 | { |
1244 | switch(NCMAG_Identification2.Sub) |
1244 | switch(NCMAG_Identification2.Sub) |
1245 | { |
1245 | { |
1246 | case MAG_IDF_LSM303DLM: NCMAG_SensorType = TYPE_LSM303DLM; |
1246 | case MAG_IDF_LSM303DLM: NCMAG_SensorType = TYPE_LSM303DLM; |
1247 | NCMAG_Init_ACCSensor(); |
1247 | NCMAG_Init_ACCSensor(); |
1248 | break; |
1248 | break; |
1249 | case MAG_IDF_LSM303DLH: NCMAG_SensorType = TYPE_LSM303DLH; |
1249 | case MAG_IDF_LSM303DLH: NCMAG_SensorType = TYPE_LSM303DLH; |
1250 | NCMAG_Init_ACCSensor(); |
1250 | NCMAG_Init_ACCSensor(); |
1251 | break; |
1251 | break; |
1252 | case MAG_IDF_LSM303D: NCMAG_SensorType = TYPE_LSM303D; |
1252 | case MAG_IDF_LSM303D: NCMAG_SensorType = TYPE_LSM303D; |
1253 | break; |
1253 | break; |
1254 | } |
1254 | } |
1255 | } |
1255 | } |
1256 | // get id bytes |
1256 | // get id bytes |
1257 | retval = 0; |
1257 | retval = 0; |
1258 | for(repeat = 0; repeat < 3; repeat++) |
1258 | for(repeat = 0; repeat < 3; repeat++) |
1259 | { |
1259 | { |
1260 | retval = NCMAG_GetIdentification(); |
1260 | retval = NCMAG_GetIdentification(); |
1261 | if(retval) break; // break loop on success |
1261 | if(retval) break; // break loop on success |
1262 | } |
1262 | } |
1263 | } |
1263 | } |
1264 | // if we got an answer to id request |
1264 | // if we got an answer to id request |
1265 | if(retval) |
1265 | if(retval) |
1266 | { |
1266 | { |
1267 | u8 n1[] = "\n\r HMC5843"; |
1267 | u8 n1[] = "\r\n HMC5843"; |
1268 | u8 n2[] = "\n\r LSM303DLH"; |
1268 | u8 n2[] = "\r\n LSM303DLH"; |
1269 | u8 n3[] = "\n\r LSM303DLM"; |
1269 | u8 n3[] = "\r\n LSM303DLM"; |
1270 | u8 n4[] = "\n\r LSM303D"; |
1270 | u8 n4[] = "\r\n LSM303D"; |
1271 | u8 n5[] = "\n\r ??"; |
1271 | u8 n5[] = "\r\n ??"; |
1272 | u8* pn = n5; |
1272 | u8* pn = n5; |
1273 | 1273 | ||
1274 | switch(NCMAG_SensorType) |
1274 | switch(NCMAG_SensorType) |
1275 | { |
1275 | { |
1276 | case TYPE_HMC5843: |
1276 | case TYPE_HMC5843: |
1277 | pn = n1; |
1277 | pn = n1; |
1278 | break; |
1278 | break; |
1279 | case TYPE_LSM303DLH: |
1279 | case TYPE_LSM303DLH: |
1280 | pn = n2; |
1280 | pn = n2; |
1281 | break; |
1281 | break; |
1282 | case TYPE_LSM303DLM: |
1282 | case TYPE_LSM303DLM: |
1283 | pn = n3; |
1283 | pn = n3; |
1284 | break; |
1284 | break; |
1285 | case TYPE_LSM303D: |
1285 | case TYPE_LSM303D: |
1286 | pn = n4; |
1286 | pn = n4; |
1287 | break; |
1287 | break; |
1288 | } |
1288 | } |
1289 | 1289 | ||
1290 | sprintf(msg, " %s ID 0x%02x/%02x/%02x-%02x", pn, NCMAG_Identification.A, NCMAG_Identification.B, NCMAG_Identification.C,NCMAG_Identification2.Sub); |
1290 | sprintf(msg, " %s ID 0x%02x/%02x/%02x-%02x", pn, NCMAG_Identification.A, NCMAG_Identification.B, NCMAG_Identification.C,NCMAG_Identification2.Sub); |
1291 | UART1_PutString(msg); |
1291 | UART1_PutString(msg); |
1292 | if (( (NCMAG_Identification.A == MAG_IDA) |
1292 | if (( (NCMAG_Identification.A == MAG_IDA) |
1293 | && (NCMAG_Identification.B == MAG_IDB) |
1293 | && (NCMAG_Identification.B == MAG_IDB) |
1294 | && (NCMAG_Identification.C == MAG_IDC)) |
1294 | && (NCMAG_Identification.C == MAG_IDC)) |
1295 | || NCMAG_SensorType == TYPE_LSM303D) |
1295 | || NCMAG_SensorType == TYPE_LSM303D) |
1296 | { |
1296 | { |
1297 | NCMAG_Present = 1; |
1297 | NCMAG_Present = 1; |
1298 | 1298 | ||
1299 | if(EEPROM_Init()) |
1299 | if(EEPROM_Init()) |
1300 | { |
1300 | { |
1301 | NCMAG_IsCalibrated = NCMag_CalibrationRead(Compass_I2CPort); |
1301 | NCMAG_IsCalibrated = NCMag_CalibrationRead(Compass_I2CPort); |
1302 | if(!NCMAG_IsCalibrated) UART1_PutString("\r\n Not calibrated!"); |
1302 | if(!NCMAG_IsCalibrated) UART1_PutString("\r\n Not calibrated!"); |
1303 | } |
1303 | } |
1304 | else UART1_PutString("\r\n EEPROM data not available!!!!!!!!!!!!!!!"); |
1304 | else UART1_PutString("\r\n EEPROM data not available!!!!!!!!!!!!!!!"); |
1305 | 1305 | ||
1306 | // in case of an external sensor, try to get the orientation by acc readings |
1306 | // in case of an external sensor, try to get the orientation by acc readings |
1307 | if(NCMAG_Compass_use_Orientation) |
1307 | if(NCMAG_Compass_use_Orientation) |
1308 | { |
1308 | { |
1309 | // try to get orientation by acc sensor values |
1309 | // try to get orientation by acc sensor values |
1310 | for(repeat = 0; repeat < 100; repeat++) |
1310 | for(repeat = 0; repeat < 100; repeat++) |
1311 | { |
1311 | { |
1312 | NCMAG_GetAccVector(10); // only the sensor with ACC is supported |
1312 | NCMAG_GetAccVector(10); // only the sensor with ACC is supported |
1313 | NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
1313 | NCMAG_Orientation = NCMAG_GetOrientationFromAcc(); |
1314 | if(NCMAG_Orientation && (NCMAG_Orientation == Calibration.Version >> 4)) break; |
1314 | if(NCMAG_Orientation && (NCMAG_Orientation == Calibration.Version >> 4)) break; |
1315 | } |
1315 | } |
1316 | // check orientation result if available |
1316 | // check orientation result if available |
1317 | sprintf(msg, "\r\n Orientation: "); |
1317 | sprintf(msg, "\r\n Orientation: "); |
1318 | UART1_PutString(msg); |
1318 | UART1_PutString(msg); |
1319 | if(NCMAG_Orientation) |
1319 | if(NCMAG_Orientation) |
1320 | { |
1320 | { |
1321 | sprintf(msg, "%d ", NCMAG_Orientation); |
1321 | sprintf(msg, "%d ", NCMAG_Orientation); |
1322 | UART1_PutString(msg); |
1322 | UART1_PutString(msg); |
1323 | if(NCMAG_IsCalibrated) // check against calibration data orientation |
1323 | if(NCMAG_IsCalibrated) // check against calibration data orientation |
1324 | { |
1324 | { |
1325 | if(NCMAG_Orientation != Calibration.Version >> 4) |
1325 | if(NCMAG_Orientation != Calibration.Version >> 4) |
1326 | { |
1326 | { |
1327 | sprintf(msg, "\n\r Warning: calibrated orientation was %d !",Calibration.Version >> 4); |
1327 | sprintf(msg, "\r\n Warning: calibrated orientation was %d !",Calibration.Version >> 4); |
1328 | UART1_PutString(msg); |
1328 | UART1_PutString(msg); |
1329 | //NCMAG_IsCalibrated = 0; // force new calibration! |
1329 | //NCMAG_IsCalibrated = 0; // force new calibration! |
1330 | } |
1330 | } |
1331 | } |
1331 | } |
1332 | } |
1332 | } |
1333 | else |
1333 | else |
1334 | { |
1334 | { |
1335 | UART1_PutString("unknown!"); |
1335 | UART1_PutString("unknown!"); |
1336 | } |
1336 | } |
1337 | } |
1337 | } |
1338 | 1338 | ||
1339 | 1339 | ||
1340 | // perform self test |
1340 | // perform self test |
1341 | if(!NCMAG_SelfTest()) |
1341 | if(!NCMAG_SelfTest()) |
1342 | { |
1342 | { |
1343 | UART1_PutString("\r\n Selftest failed!!!!!!!!!!!!!!!!!!!!\r\n"); |
1343 | UART1_PutString("\r\n Selftest failed!!!!!!!!!!!!!!!!!!!!\r\n"); |
1344 | LED_RED_ON; |
1344 | LED_RED_ON; |
1345 | //NCMAG_IsCalibrated = 0; |
1345 | //NCMAG_IsCalibrated = 0; |
1346 | } |
1346 | } |
1347 | else UART1_PutString("\r\n Selftest ok"); |
1347 | else UART1_PutString("\r\n Selftest ok"); |
1348 | 1348 | ||
1349 | // initialize magnetic sensor configuration |
1349 | // initialize magnetic sensor configuration |
1350 | NCMAG_ConfigureSensor(); |
1350 | NCMAG_ConfigureSensor(); |
1351 | } |
1351 | } |
1352 | else |
1352 | else |
1353 | { |
1353 | { |
1354 | UART1_PutString("\n\r Not compatible!"); |
1354 | UART1_PutString("\r\n Not compatible!"); |
1355 | UART_VersionInfo.HardwareError[0] |= NC_ERROR0_COMPASS_INCOMPATIBLE; |
1355 | UART_VersionInfo.HardwareError[0] |= NC_ERROR0_COMPASS_INCOMPATIBLE; |
1356 | LED_RED_ON; |
1356 | LED_RED_ON; |
1357 | } |
1357 | } |
1358 | } |
1358 | } |
1359 | else // nothing found |
1359 | else // nothing found |
1360 | { |
1360 | { |
1361 | NCMAG_SensorType = TYPE_NONE; |
1361 | NCMAG_SensorType = TYPE_NONE; |
1362 | UART1_PutString(" not found!"); |
1362 | UART1_PutString(" not found!"); |
1363 | } |
1363 | } |
1364 | } |
1364 | } |
1365 | return(NCMAG_Present); |
1365 | return(NCMAG_Present); |
1366 | } |
1366 | } |
1367 | 1367 | ||
1368 | 1368 |