Subversion Repositories NaviCtrl

Rev

Rev 494 | Rev 496 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 494 Rev 495
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 <ctype.h>
56
#include <ctype.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 "waypoints.h"
61
#include "waypoints.h"
62
#include "uart1.h"
62
#include "uart1.h"
63
#include "fat16.h"
63
#include "fat16.h"
64
 
64
 
65
// the waypoints list
65
// the waypoints list
66
#define MAX_LIST_LEN 101
66
#define MAX_LIST_LEN 101
67
 
67
 
68
Point_t PointList[MAX_LIST_LEN];
68
Point_t PointList[MAX_LIST_LEN];
69
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
69
u8 WPIndex = 0;         // list index of GPS point representig the current WP, can be maximal WPCount
70
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
70
u8 POIIndex = 0;        // list index of GPS Point representing the current POI, can be maximal WPCount
71
u8 WPCount = 0;         // number of waypoints
71
u8 WPCount = 0;         // number of waypoints
72
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
72
u8 PointCount = 0;      // number of points in the list can be maximal equal to MAX_LIST_LEN
73
u8 POICount = 0;        // number of point of interest in the list
73
u8 POICount = 0;        // number of point of interest in the list
74
 
74
 
75
u8 WPActive = FALSE;
75
u8 WPActive = FALSE;
76
 
76
 
77
u8 PointList_Init(void)
77
u8 PointList_Init(void)
78
{
78
{
79
        return PointList_Clear();
79
        return PointList_Clear();
80
}
80
}
81
 
81
 
82
u8 PointList_Clear(void)
82
u8 PointList_Clear(void)
83
{
83
{
84
        u8 i;
84
        u8 i;
85
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
85
        WPIndex = 0;    // real list position are 1 ,2, 3 ...
86
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
86
        POIIndex = 0;   // real list position are 1 ,2, 3 ...
87
        WPCount = 0;    // no waypoints
87
        WPCount = 0;    // no waypoints
88
    POICount = 0;
88
    POICount = 0;
89
        PointCount = 0; // no contents
89
        PointCount = 0; // no contents
90
        WPActive = FALSE;
90
        WPActive = FALSE;
91
        NaviData.WaypointNumber = WPCount;
91
        NaviData.WaypointNumber = WPCount;
92
        NaviData.WaypointIndex = 0;
92
        NaviData.WaypointIndex = 0;
93
 
93
 
94
        for(i = 0; i < MAX_LIST_LEN; i++)
94
        for(i = 0; i < MAX_LIST_LEN; i++)
95
        {
95
        {
96
                PointList[i].Position.Status = INVALID;
96
                PointList[i].Position.Status = INVALID;
97
                PointList[i].Position.Latitude = 0;
97
                PointList[i].Position.Latitude = 0;
98
                PointList[i].Position.Longitude = 0;
98
                PointList[i].Position.Longitude = 0;
99
                PointList[i].Position.Altitude = 0;
99
                PointList[i].Position.Altitude = 0;
100
                PointList[i].Heading = 361;             // invalid value
100
                PointList[i].Heading = 361;             // invalid value
101
                PointList[i].ToleranceRadius = 0;       // in meters, if the MK is within that range around the target, then the next target is triggered
101
                PointList[i].ToleranceRadius = 0;       // in meters, if the MK is within that range around the target, then the next target is triggered
102
                PointList[i].HoldTime = 0;                      // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered
102
                PointList[i].HoldTime = 0;                      // in seconds, if the was once in the tolerance area around a WP, this time defines the delay before the next WP is triggered
103
                PointList[i].Event_Flag = 0;            // future implementation
103
                PointList[i].Event_Flag = 0;            // future implementation
104
                PointList[i].Index = 0;
104
                PointList[i].Index = 0;
105
                PointList[i].Type = POINT_TYPE_INVALID;
105
                PointList[i].Type = POINT_TYPE_INVALID;
106
                PointList[i].WP_EventChannelValue = 0;
106
                PointList[i].WP_EventChannelValue = 0;
107
                PointList[i].AltitudeRate = 0;          // no change of setpoint
107
                PointList[i].AltitudeRate = 0;          // no change of setpoint
108
                PointList[i].Speed = 0;
108
                PointList[i].Speed = 0;
109
                PointList[i].CamAngle = 0;
109
                PointList[i].CamAngle = 0;
110
                PointList[i].Name[0] = 0;
110
                PointList[i].Name[0] = 0;
111
        }
111
        }
112
        return TRUE;           
112
        return TRUE;           
113
}
113
}
114
 
114
 
115
u8 PointList_GetCount(void)
115
u8 PointList_GetCount(void)
116
{
116
{
117
        return PointCount; // number of points in the list
117
        return PointCount; // number of points in the list
118
}
118
}
119
 
119
 
120
Point_t* PointList_GetAt(u8 index)
120
Point_t* PointList_GetAt(u8 index)
121
{
121
{
122
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
122
        if((index > 0) && (index <= PointCount)) return(&(PointList[index-1])); // return pointer to this waypoint
123
        else return(NULL);
123
        else return(NULL);
124
}
124
}
125
 
125
 
126
u8 PointList_SetAt(Point_t* pPoint)
126
u8 PointList_SetAt(Point_t* pPoint)
127
{
127
{
128
        // if index is in range
128
        // if index is in range
129
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
129
        if((pPoint->Index > 0) && (pPoint->Index <= MAX_LIST_LEN))
130
        {
130
        {
131
                // check list entry before update
131
                // check list entry before update
132
                switch(PointList[pPoint->Index-1].Type)
132
                switch(PointList[pPoint->Index-1].Type)
133
                {
133
                {
134
                        case POINT_TYPE_INVALID: // was invalid
134
                        case POINT_TYPE_INVALID: // was invalid
135
                                switch(pPoint->Type)
135
                                switch(pPoint->Type)
136
                                {
136
                                {
137
                                        default:
137
                                        default:
138
                                        case POINT_TYPE_INVALID:
138
                                        case POINT_TYPE_INVALID:
139
                                                // nothing to do
139
                                                // nothing to do
140
                                                break;
140
                                                break;
141
 
141
 
142
                                        case POINT_TYPE_WP:
142
                                        case POINT_TYPE_WP:
143
                                                WPCount++;
143
                                                WPCount++;
144
                                                PointCount++;
144
                                                PointCount++;
145
                                                break;
145
                                                break;
146
                                       
146
                                       
147
                                        case POINT_TYPE_POI:
147
                                        case POINT_TYPE_POI:
148
                                                POICount++;
148
                                                POICount++;
149
                                                PointCount++;
149
                                                PointCount++;
150
                                                break;
150
                                                break;
151
                                }
151
                                }
152
                                break;
152
                                break;
153
                               
153
                               
154
                        case POINT_TYPE_WP: // was a waypoint
154
                        case POINT_TYPE_WP: // was a waypoint
155
                                switch(pPoint->Type)
155
                                switch(pPoint->Type)
156
                                {
156
                                {
157
                                        case POINT_TYPE_INVALID:
157
                                        case POINT_TYPE_INVALID:
158
                                                WPCount--;
158
                                                WPCount--;
159
                                                PointCount--;
159
                                                PointCount--;
160
                                                break;
160
                                                break;
161
 
161
 
162
                                        default:
162
                                        default:
163
                                        case POINT_TYPE_WP:
163
                                        case POINT_TYPE_WP:
164
                                                //nothing to do
164
                                                //nothing to do
165
                                                break;
165
                                                break;
166
                                       
166
                                       
167
                                        case POINT_TYPE_POI:
167
                                        case POINT_TYPE_POI:
168
                                                POICount++;
168
                                                POICount++;
169
                                                WPCount--;
169
                                                WPCount--;
170
                                                break;
170
                                                break;
171
                                }
171
                                }
172
                                break;
172
                                break;
173
                               
173
                               
174
                        case POINT_TYPE_POI: // was a poi
174
                        case POINT_TYPE_POI: // was a poi
175
                                switch(pPoint->Type)
175
                                switch(pPoint->Type)
176
                                {
176
                                {
177
                                        case POINT_TYPE_INVALID:
177
                                        case POINT_TYPE_INVALID:
178
                                                POICount--;
178
                                                POICount--;
179
                                                PointCount--;
179
                                                PointCount--;
180
                                                break;
180
                                                break;
181
 
181
 
182
                                        case POINT_TYPE_WP:
182
                                        case POINT_TYPE_WP:
183
                                                WPCount++;
183
                                                WPCount++;
184
                                                POICount--;
184
                                                POICount--;
185
                                                break;
185
                                                break;
186
                                       
186
                                       
187
                                        case POINT_TYPE_POI:
187
                                        case POINT_TYPE_POI:
188
                                        default:
188
                                        default:
189
                                                // nothing to do
189
                                                // nothing to do
190
                                                break;
190
                                                break;
191
                                }
191
                                }
192
                                break;         
192
                                break;         
193
                }
193
                }
194
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
194
                memcpy(&PointList[pPoint->Index-1], pPoint, sizeof(Point_t)); // copy data to list entry                                                                                
195
                NaviData.WaypointNumber = WPCount;
195
                NaviData.WaypointNumber = WPCount;
196
                return pPoint->Index;
196
                return pPoint->Index;
197
        }
197
        }
198
        else return(0);
198
        else return(0);
199
}
199
}
200
 
200
 
201
// returns the pointer to the first waypoint within the list
201
// returns the pointer to the first waypoint within the list
202
Point_t* PointList_WPBegin(void)
202
Point_t* PointList_WPBegin(void)
203
{
203
{
204
        u8 i;
204
        u8 i;
205
        WPIndex = 0; // set list position invalid
205
        WPIndex = 0; // set list position invalid
206
 
206
 
207
        if(WPActive == FALSE) return(NULL);
207
        if(WPActive == FALSE) return(NULL);
208
 
208
 
209
        POIIndex = 0; // set invalid POI
209
        POIIndex = 0; // set invalid POI
210
        if(PointCount > 0)
210
        if(PointCount > 0)
211
        {
211
        {
212
                // search for first wp in list
212
                // search for first wp in list
213
                for(i = 0; i <MAX_LIST_LEN; i++)
213
                for(i = 0; i <MAX_LIST_LEN; i++)
214
                {
214
                {
215
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))
215
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID))
216
                        {
216
                        {
217
                                WPIndex = i + 1;
217
                                WPIndex = i + 1;
218
                                break;
218
                                break;
219
                        }
219
                        }
220
                }
220
                }
221
                if(WPIndex) // found a WP in the list
221
                if(WPIndex) // found a WP in the list
222
                {
222
                {
223
                        NaviData.WaypointIndex = 1;
223
                        NaviData.WaypointIndex = 1;
224
                        // update index to POI
224
                        // update index to POI
225
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
225
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
226
                        else POIIndex = 0;                     
226
                        else POIIndex = 0;                     
227
                }
227
                }
228
                else // some points in the list but no WP found
228
                else // some points in the list but no WP found
229
                {
229
                {
230
                        NaviData.WaypointIndex = 0;
230
                        NaviData.WaypointIndex = 0;
231
                        //Check for an existing POI
231
                        //Check for an existing POI
232
                        for(i = 0; i < MAX_LIST_LEN; i++)
232
                        for(i = 0; i < MAX_LIST_LEN; i++)
233
                        {
233
                        {
234
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
234
                                if((PointList[i].Type == POINT_TYPE_POI) && (PointList[i].Position.Status != INVALID))
235
                                {
235
                                {
236
                                        POIIndex = i + 1;
236
                                        POIIndex = i + 1;
237
                                        break;
237
                                        break;
238
                                }
238
                                }
239
                        }
239
                        }
240
                }
240
                }
241
        }
241
        }
242
        else // no point in the list
242
        else // no point in the list
243
        {
243
        {
244
                POIIndex = 0;
244
                POIIndex = 0;
245
                NaviData.WaypointIndex = 0;    
245
                NaviData.WaypointIndex = 0;    
246
        }
246
        }
247
 
247
 
248
        if(WPIndex) return(&(PointList[WPIndex-1]));
248
        if(WPIndex) return(&(PointList[WPIndex-1]));
249
        else return(NULL);
249
        else return(NULL);
250
}
250
}
251
 
251
 
252
// returns the last waypoint
252
// returns the last waypoint
253
Point_t* PointList_WPEnd(void)
253
Point_t* PointList_WPEnd(void)
254
{
254
{
255
       
255
       
256
        u8 i;
256
        u8 i;
257
        WPIndex = 0; // set list position invalid
257
        WPIndex = 0; // set list position invalid
258
        POIIndex = 0; // set invalid
258
        POIIndex = 0; // set invalid
259
 
259
 
260
        if(WPActive == FALSE) return(NULL);
260
        if(WPActive == FALSE) return(NULL);
261
 
261
 
262
        if(PointCount > 0)
262
        if(PointCount > 0)
263
        {
263
        {
264
                // search backward!
264
                // search backward!
265
                for(i = 1; i <= MAX_LIST_LEN; i++)
265
                for(i = 1; i <= MAX_LIST_LEN; i++)
266
                {
266
                {
267
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
267
                        if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_WP) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
268
                        {      
268
                        {      
269
                                WPIndex = MAX_LIST_LEN - i + 1;
269
                                WPIndex = MAX_LIST_LEN - i + 1;
270
                                break;
270
                                break;
271
                        }
271
                        }
272
                }
272
                }
273
                if(WPIndex) // found a WP within the list
273
                if(WPIndex) // found a WP within the list
274
                {
274
                {
275
                        NaviData.WaypointIndex = WPCount;
275
                        NaviData.WaypointIndex = WPCount;
276
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
276
                        if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
277
                        else POIIndex = 0;     
277
                        else POIIndex = 0;     
278
                }
278
                }
279
                else // list contains some points but no WP in the list
279
                else // list contains some points but no WP in the list
280
                {
280
                {
281
                        // search backward for a POI!
281
                        // search backward for a POI!
282
                        for(i = 1; i <= MAX_LIST_LEN; i++)
282
                        for(i = 1; i <= MAX_LIST_LEN; i++)
283
                        {
283
                        {
284
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
284
                                if((PointList[MAX_LIST_LEN - i].Type == POINT_TYPE_POI) && (PointList[MAX_LIST_LEN - i].Position.Status != INVALID))
285
                                {      
285
                                {      
286
                                        POIIndex = MAX_LIST_LEN - i + 1;
286
                                        POIIndex = MAX_LIST_LEN - i + 1;
287
                                        break;
287
                                        break;
288
                                }
288
                                }
289
                        }
289
                        }
290
                        NaviData.WaypointIndex = 0;    
290
                        NaviData.WaypointIndex = 0;    
291
                }
291
                }
292
        }
292
        }
293
        else // no point in the list
293
        else // no point in the list
294
        {
294
        {
295
                POIIndex = 0;
295
                POIIndex = 0;
296
                NaviData.WaypointIndex = 0;
296
                NaviData.WaypointIndex = 0;
297
        }
297
        }
298
        if(WPIndex) return(&(PointList[WPIndex-1]));
298
        if(WPIndex) return(&(PointList[WPIndex-1]));
299
        else return(NULL);
299
        else return(NULL);
300
}
300
}
301
 
301
 
302
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
302
// returns a pointer to the next waypoint or NULL if the end of the list has been reached
303
Point_t* PointList_WPNext(void)
303
Point_t* PointList_WPNext(void)
304
{
304
{
305
        u8 wp_found = 0;
305
        u8 wp_found = 0;
306
        if(WPActive == FALSE) return(NULL);
306
        if(WPActive == FALSE) return(NULL);
307
               
307
               
308
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
308
        if(WPIndex < MAX_LIST_LEN) // if there is a next entry in the list
309
        {
309
        {
310
                u8 i;
310
                u8 i;
311
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
311
                for(i = WPIndex; i < MAX_LIST_LEN; i++) // start search for next at next list entry
312
                {
312
                {
313
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs
313
                        if((PointList[i].Type == POINT_TYPE_WP) && (PointList[i].Position.Status != INVALID)) // jump over POIs
314
                        {
314
                        {
315
                                wp_found = i+1;
315
                                wp_found = i+1;
316
                                break;
316
                                break;
317
                        }
317
                        }
318
                }
318
                }
319
        }
319
        }
320
        if(wp_found)
320
        if(wp_found)
321
        {
321
        {
322
                WPIndex = wp_found; // update list position
322
                WPIndex = wp_found; // update list position
323
                NaviData.WaypointIndex++;
323
                NaviData.WaypointIndex++;
324
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
324
                if(PointList[WPIndex-1].Heading < 0) POIIndex = (u8)(-PointList[WPIndex-1].Heading);
325
                else POIIndex = 0;
325
                else POIIndex = 0;
326
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
326
                return(&(PointList[WPIndex-1]));        // return pointer to this waypoint
327
        }
327
        }
328
        else
328
        else
329
        {  // no next wp found
329
        {  // no next wp found
330
                NaviData.WaypointIndex = 0;    
330
                NaviData.WaypointIndex = 0;    
331
                POIIndex = 0;
331
                POIIndex = 0;
332
                return(NULL);
332
                return(NULL);
333
        }
333
        }
334
}      
334
}      
335
 
335
 
336
void PointList_WPActive(u8 set)
336
void PointList_WPActive(u8 set)
337
{
337
{
338
        if(set)
338
        if(set)
339
        {      
339
        {      
340
                WPActive = TRUE;
340
                WPActive = TRUE;
341
                PointList_WPBegin(); // updates POI index
341
                PointList_WPBegin(); // updates POI index
342
        }
342
        }
343
        else
343
        else
344
        {
344
        {
345
                WPActive = FALSE;
345
                WPActive = FALSE;
346
                POIIndex = 0;  // disable POI also
346
                POIIndex = 0;  // disable POI also
347
        }
347
        }
348
}
348
}
349
 
349
 
350
Point_t* PointList_GetPOI(void)
350
Point_t* PointList_GetPOI(void)
351
{
351
{
352
        return PointList_GetAt(POIIndex);      
352
        return PointList_GetAt(POIIndex);      
353
}
353
}
354
 
354
 
355
#define LINE_MAX 70
355
#define LINE_MAX 70
356
#define WP_FILE_VERSION_COMPATIBLE 3
356
#define WP_FILE_VERSION_COMPATIBLE 3
357
// save actual point list to SD card
357
// save actual point list to SD card
358
u8 PointList_SaveToFile(u8 place, s8 * name)
358
u8 PointList_SaveToFile(WPL_Store_t * pWPL_Store)
359
{
359
{
360
        File_t *fp;
360
        File_t *fp;
361
        s8 wpline[LINE_MAX], retval = 0;
361
        s8 wpline[LINE_MAX];
-
 
362
        u8 retval = WPL_ERROR;
362
        // user absolute path, i.e. leading /
363
        // user absolute path, i.e. leading /
363
 
364
       
364
        sprintf(wpline, "/list_%03d.wpl", place);
-
 
365
 
-
 
366
        UART1_PutString("\n\r Write ");
-
 
367
        UART1_PutString(wpline);
-
 
368
        UART1_PutString("...");
365
        sprintf(wpline, "/list_%03d.wpl", pWPL_Store->Index);
369
 
366
 
370
        UART1_PutString("\n\r Save WPL...");
367
        UART1_PutString("\n\r Save WPL...");
371
 
368
 
372
        if(Fat16_IsValid())
369
        if(Fat16_IsValid())
373
        {       // check if wpl file is existing
370
        {       // check if wpl file is existing
-
 
371
                if(fexist_(wpline))
-
 
372
                {       //file is existent
-
 
373
                        if(!(pWPL_Store->OverwriteFile))
-
 
374
                        {
-
 
375
                                UART1_PutString("Error: file exist!\r\n");
-
 
376
                                return(WPL_FILEEXIST);
-
 
377
                        }      
-
 
378
                }
374
                fp = fopen_(wpline, 'w');               // try to open the file
379
                fp = fopen_(wpline, 'w');               // try to open the file
375
                if(fp == NULL)
380
                if(fp == NULL)
376
                {
381
                {
377
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
382
                        UART1_PutString("ERROR: Creating waypoint file!\r\n");
378
                        return(retval);
383
                        return(retval);
379
                }
384
                }
380
                // Create general section and key entries
385
                // Create general section and key entries
381
                fputs_("[General]\r\n", fp);
386
                fputs_("[General]\r\n", fp);
382
                sprintf(wpline, "Name=%s\r\n", name);
387
                sprintf(wpline, "Name=%s\r\n",  pWPL_Store->Name);
-
 
388
                fputs_(wpline, fp);
-
 
389
                sprintf(wpline, "PositionType=%d\r\n",  pWPL_Store->Type);
383
                fputs_(wpline, fp);
390
                fputs_(wpline, fp);
384
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
391
                sprintf(wpline, "FileVersion=%d\r\n", WP_FILE_VERSION_COMPATIBLE);
385
                fputs_(wpline, fp);
392
                fputs_(wpline, fp);
386
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
393
                sprintf(wpline, "NumberOfWaypoints=%d\r\n", PointCount);
387
                fputs_(wpline, fp);
394
                fputs_(wpline, fp);
388
                // dump all points if existent
395
                // dump all points if existent
389
                if(PointCount)
396
                if(PointCount)
390
                {
397
                {
391
                        u8 i, u8_1;
398
                        u8 i, u8_1;
392
                        s32 i32_1, i32_2;
399
                        s32 i32_1, i32_2;
393
 
400
 
394
                        for (i = 0; i < PointCount; i++)
401
                        for (i = 0; i < PointCount; i++)
395
                        {
402
                        {
396
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
403
                                sprintf(wpline, "[Point%d]\r\n",PointList[i].Index);
397
                                fputs_(wpline, fp);
404
                                fputs_(wpline, fp);
398
                                // write latitude in deg
405
                                // write latitude in deg
399
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
406
                                if(PointList[i].Position.Latitude < 0) u8_1 = '-';
400
                                else u8_1 = '+';
407
                                else u8_1 = '+';
401
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
408
                                i32_1 = abs(PointList[i].Position.Latitude)/10000000L;
402
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
409
                                i32_2 = abs(PointList[i].Position.Latitude)%10000000L;
403
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
410
                                sprintf(wpline, "Latitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
404
                                fputs_(wpline, fp);
411
                                fputs_(wpline, fp);
405
                                // write longitude in deg
412
                                // write longitude in deg
406
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
413
                                if(PointList[i].Position.Longitude < 0) u8_1 = '-';
407
                                else u8_1 = '+';
414
                                else u8_1 = '+';
408
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
415
                                i32_1 = abs(PointList[i].Position.Longitude)/10000000L;
409
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
416
                                i32_2 = abs(PointList[i].Position.Longitude)%10000000L;
410
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
417
                                sprintf(wpline, "Longitude=%c%ld.%07ld\r\n", u8_1, i32_1, i32_2);
411
                                fputs_(wpline, fp);
418
                                fputs_(wpline, fp);
412
                                // write tolerace radius in m
419
                                // write tolerace radius in m
413
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
420
                                sprintf(wpline, "Radius=%d\r\n", PointList[i].ToleranceRadius);
414
                                fputs_(wpline, fp);
421
                                fputs_(wpline, fp);
415
                                // write altitude in m
422
                                // write altitude in m
416
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
423
                                if(PointList[i].Position.Altitude < 0) u8_1 = '-';
417
                                else u8_1 = '+';
424
                                else u8_1 = '+';
418
                                if(PointList[i].Type == POINT_TYPE_POI)
425
                                if(PointList[i].Type == POINT_TYPE_POI)
419
                                {
426
                                {
420
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
427
                                        i32_1 = abs(PointList[i].Position.Altitude)/100L;  // cm --> m
421
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
428
                                        i32_2 = abs(PointList[i].Position.Altitude)%100L;
422
                                }
429
                                }
423
                                else
430
                                else
424
                                {
431
                                {
425
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
432
                                        i32_1 = abs(PointList[i].Position.Altitude)/10L; // dm --> m
426
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
433
                                        i32_2 = abs(PointList[i].Position.Altitude)%10L;
427
                                }
434
                                }
428
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
435
                                sprintf(wpline, "Altitude=%c%ld.%01ld\r\n",  u8_1, i32_1, i32_2);
429
                                fputs_(wpline, fp);
436
                                fputs_(wpline, fp);
430
                                // write climb rate in 0.1 m/s
437
                                // write climb rate in 0.1 m/s
431
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
438
                                sprintf(wpline, "ClimbRate=%d\r\n", PointList[i].AltitudeRate);
432
                                fputs_(wpline, fp);
439
                                fputs_(wpline, fp);
433
                                // write hold time in s
440
                                // write hold time in s
434
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
441
                                sprintf(wpline, "DelayTime=%d\r\n", PointList[i].HoldTime);
435
                                fputs_(wpline, fp);
442
                                fputs_(wpline, fp);
436
                                // write event channel value
443
                                // write event channel value
437
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
444
                                sprintf(wpline, "WP_Event_Channel_Value=%d\r\n", PointList[i].WP_EventChannelValue);
438
                                fputs_(wpline, fp);
445
                                fputs_(wpline, fp);
439
                                // write heading in deg (0= nothing, neg. values index to poi)
446
                                // write heading in deg (0= nothing, neg. values index to poi)
440
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
447
                                sprintf(wpline, "Heading=%d\r\n", PointList[i].Heading);
441
                                fputs_(wpline, fp);
448
                                fputs_(wpline, fp);
442
                                // write speed in 0.1 m/s
449
                                // write speed in 0.1 m/s
443
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
450
                                sprintf(wpline, "Speed=%d\r\n", PointList[i].Speed);
444
                                fputs_(wpline, fp);
451
                                fputs_(wpline, fp);
445
                                // write cam angle in degree (255 -> POI-Automatic)
452
                                // write cam angle in degree (255 -> POI-Automatic)
446
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
453
                                sprintf(wpline, "CAM-Nick=%d\r\n", PointList[i].CamAngle);
447
                                fputs_(wpline, fp);
454
                                fputs_(wpline, fp);
448
                                // write point type
455
                                // write point type
449
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
456
                                sprintf(wpline, "Type=%d\r\n", PointList[i].Type + 1);
450
                                fputs_(wpline, fp);    
457
                                fputs_(wpline, fp);    
451
                                // write prefix 
458
                                // write prefix 
452
                                //if(PointList[i].Type == POINT_TYPE_WP) u8_1 = 'P';
459
                                //if(PointList[i].Type == POINT_TYPE_WP) u8_1 = 'P';
453
                                //else u8_1 = '0';
460
                                //else u8_1 = '0';
454
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
461
                                sprintf(wpline, "Prefix=%s\r\n", PointList[i].Name);
455
                                fputs_(wpline, fp);
462
                                fputs_(wpline, fp);
456
                        } // EOF loop over all points
463
                        } // EOF loop over all points
457
                } // EOF if(PointCount)
464
                } // EOF if(PointCount)
458
                if(EOF == fclose_(fp))
465
                if(EOF == fclose_(fp))
459
                {
466
                {
460
                        UART1_PutString("failed!\r\n");
467
                        UART1_PutString("failed!\r\n");
461
                }
468
                }
462
                else
469
                else
463
                {
470
                {
464
                        UART1_PutString("ok\r\n");
471
                        UART1_PutString("ok\r\n");
465
                        retval = 1;
472
                        retval = WPL_OK;
466
                }                                
473
                }                                
467
        } // EOF if(Fat16_IsValid())
474
        } // EOF if(Fat16_IsValid())
468
        else UART1_PutString("no file system found!\r\n");     
475
        else UART1_PutString("no file system found!\r\n");     
469
        return(retval);
476
        return(retval);
470
}
477
}
471
 
478
 
472
// load actual point list from SD card
479
// load actual point list from SD card
473
u8 PointList_ReadFromFile(u8 place)
480
u8 PointList_ReadFromFile(WPL_Store_t * pWPL_Store)
474
{
481
{
475
        File_t *fp;
482
        File_t *fp;
476
        s8 wpline[LINE_MAX], retval = 0;
483
        s8 wpline[LINE_MAX], retval = 0;
477
       
484
       
478
        s8 *name, *value;
485
        s8 *name, *value;
479
        u8 i;
486
        u8 i;
480
 
487
 
481
        u8 IsGeneralSection = 0;
488
        u8 IsGeneralSection = 0;
482
        u8 IsPointSection  = 0;
489
        u8 IsPointSection  = 0;
483
        u8 WPNumber = 0;
490
        u8 WPNumber = 0;
484
 
491
 
485
        // user absolute path, i.e. leading /
492
        // user absolute path, i.e. leading /
486
        sprintf(wpline, "/list_%03d.wpl", place);
493
        sprintf(wpline, "/list_%03d.wpl", pWPL_Store->Index);
487
 
494
 
488
        UART1_PutString("\n\r Read ");
495
        UART1_PutString("\n\r Read ");
489
        UART1_PutString(wpline);
496
        UART1_PutString(wpline);
490
        UART1_PutString("...");
497
        UART1_PutString("...");
491
 
498
 
492
        if(Fat16_IsValid())
499
        if(Fat16_IsValid())
493
        {       // check if wpl file is existing
500
        {       // check if wpl file is existing
494
                fp = fopen_(wpline, 'r');               // try to open the file
501
                fp = fopen_(wpline, 'r');               // try to open the file
495
                if(fp == NULL)
502
                if(fp == NULL)
496
                {
503
                {
497
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
504
                        UART1_PutString("ERROR: Reading waypoint file!\r\n");
498
                        return(0);
505
                        return(0);
499
                }
506
                }
500
                // clear point list first
507
                // clear point list first
501
                PointList_Clear();
508
                PointList_Clear();
502
                // read all lines from file
509
                // read all lines from file
503
                while(fgets_(wpline, LINE_MAX, fp) != 0)
510
                while(fgets_(wpline, LINE_MAX, fp) != 0)
504
                {
511
                {
505
                        if ( // ignorelines starting with \r,\n,' ',';','#'
512
                        if ( // ignorelines starting with \r,\n,' ',';','#'
506
                                (wpline[0] != '\n') &&
513
                                (wpline[0] != '\n') &&
507
                                (wpline[0] != '\r') &&
514
                                (wpline[0] != '\r') &&
508
                                (wpline[0] != ' ' ) &&
515
                                (wpline[0] != ' ' ) &&
509
                                (wpline[0] != ';' ) &&
516
                                (wpline[0] != ';' ) &&
510
                                (wpline[0] != '#' )
517
                                (wpline[0] != '#' )
511
                                )
518
                                )
512
                        {
519
                        {
513
                                // check for section line found
520
                                // check for section line found
514
                                if(wpline[0] == '[')
521
                                if(wpline[0] == '[')
515
                                {
522
                                {
516
                                        // next section found
523
                                        // next section found
517
                                        IsGeneralSection = 0;
524
                                        IsGeneralSection = 0;
518
                                        IsPointSection = 0;
525
                                        IsPointSection = 0;
519
 
526
 
520
                                        name  = strtok(&wpline[1], "]");
527
                                        name  = strtok(&wpline[1], "]");
521
                                        if(name != NULL)   // if section name
528
                                        if(name != NULL)   // if section name
522
                                        {
529
                                        {
523
                                                // check section type
530
                                                // check section type
524
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
531
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
525
 
532
 
526
                                                if(strncmp(name, "POINT", 5) == 0)
533
                                                if(strncmp(name, "POINT", 5) == 0)
527
                                                {
534
                                                {
528
                                                        IsPointSection = (u8)atoi(&name[5]);
535
                                                        IsPointSection = (u8)atoi(&name[5]);
529
                                                        PointCount++;
536
                                                        PointCount++;
530
                                                }
537
                                                }
531
                                                else if(strcmp(name, "GENERAL") == 0)
538
                                                else if(strcmp(name, "GENERAL") == 0)
532
                                                {
539
                                                {
533
                                                        IsGeneralSection = 1;
540
                                                        IsGeneralSection = 1;
534
                                                }
541
                                                }
535
                                                else
542
                                                else
536
                                                {
543
                                                {
537
                                                        UART1_PutString("Unknown section: ");
544
                                                        UART1_PutString("Unknown section: ");
538
                                                        UART1_PutString(name);
545
                                                        UART1_PutString(name);
539
                                                        UART1_PutString("\r\n");
546
                                                        UART1_PutString("\r\n");
540
                                                }
547
                                                }
541
                                        }
548
                                        }
542
                                } // EOF section line
549
                                } // EOF section line
543
                                else
550
                                else
544
                                {       // look for key entrys of each sections
551
                                {       // look for key entrys of each sections
545
                                        name  = strtok(wpline, "="); // get name
552
                                        name  = strtok(wpline, "="); // get name
546
                                        value = strtok(NULL, "="); // get value
553
                                        value = strtok(NULL, "="); // get value
547
                                        if ((name != NULL) && (value != NULL))
554
                                        if ((name != NULL) && (value != NULL))
548
                                        {
555
                                        {
549
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
556
                                                for(i=0; name[i]; i++) name[i] = toupper(name[i]); // convert to upper case
550
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
557
                                                if(IsPointSection &&  (IsPointSection <= WPNumber))
551
                                                {
558
                                                {
552
                                                        if(strcmp(name, "LATITUDE") == 0)
559
                                                        if(strcmp(name, "LATITUDE") == 0)
553
                                                        {
560
                                                        {
554
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
561
                                                                PointList[IsPointSection-1].Position.Latitude = (s32)(atof(value) * 1E7);
555
                                                        }
562
                                                        }
556
                                                        else if(strcmp(name, "LONGITUDE") == 0)
563
                                                        else if(strcmp(name, "LONGITUDE") == 0)
557
                                                        {
564
                                                        {
558
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
565
                                                                PointList[IsPointSection-1].Position.Longitude = (s32)(atof(value) * 1E7);
559
                                                        }
566
                                                        }
560
                                                        else if(strcmp(name, "RADIUS") == 0)
567
                                                        else if(strcmp(name, "RADIUS") == 0)
561
                                                        {
568
                                                        {
562
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
569
                                                                PointList[IsPointSection-1].ToleranceRadius = (u8)atoi(value);
563
                                                        }
570
                                                        }
564
                                                        else if(strcmp(name, "ALTITUDE") == 0)
571
                                                        else if(strcmp(name, "ALTITUDE") == 0)
565
                                                        {
572
                                                        {
566
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
573
                                                                PointList[IsPointSection-1].Position.Altitude = (s32)(atof(value) * 100.0);      // in cm
567
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
574
                                                                PointList[IsPointSection-1].Position.Status = NEWDATA;
568
                                                        }
575
                                                        }
569
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
576
                                                        else if(strcmp(name, "CLIMBRATE") == 0)
570
                                                        {
577
                                                        {
571
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
578
                                                                PointList[IsPointSection-1].AltitudeRate = (u8)atoi(value);
572
                                                        }
579
                                                        }
573
                                                        else if(strcmp(name, "DELAYTIME") == 0)
580
                                                        else if(strcmp(name, "DELAYTIME") == 0)
574
                                                        {
581
                                                        {
575
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
582
                                                                PointList[IsPointSection-1].HoldTime = (u8)atoi(value);
576
                                                        }
583
                                                        }
577
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
584
                                                        else if(strcmp(name, "WP_EVENT_CHANNEL_VALUE") == 0)
578
                                                        {
585
                                                        {
579
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
586
                                                                PointList[IsPointSection-1].WP_EventChannelValue = (u8)atoi(value);
580
                                                        }
587
                                                        }
581
                                                        else if(strcmp(name, "HEADING") == 0)
588
                                                        else if(strcmp(name, "HEADING") == 0)
582
                                                        {
589
                                                        {
583
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
590
                                                                PointList[IsPointSection-1].Heading = (s16)atoi(value);
584
                                                        }
591
                                                        }
585
                                                        else if(strcmp(name, "SPEED") == 0)
592
                                                        else if(strcmp(name, "SPEED") == 0)
586
                                                        {
593
                                                        {
587
                                                                PointList[IsPointSection-1].Speed = (u8)atoi(value);
594
                                                                PointList[IsPointSection-1].Speed = (u8)atoi(value);
588
                                                        }
595
                                                        }
589
                                                        else if(strcmp(name, "CAM-NICK") == 0)
596
                                                        else if(strcmp(name, "CAM-NICK") == 0)
590
                                                        {
597
                                                        {
591
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
598
                                                                PointList[IsPointSection-1].CamAngle = (u8)atoi(value);
592
                                                        }
599
                                                        }
593
                                                        else if(strcmp(name, "TYPE") == 0)
600
                                                        else if(strcmp(name, "TYPE") == 0)
594
                                                        {
601
                                                        {
595
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
602
                                                                PointList[IsPointSection-1].Type = (u8)atoi(value);
596
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
603
                                                                if(PointList[IsPointSection-1].Type > 0) PointList[IsPointSection-1].Type--;  // index shift
597
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
604
                                                                else PointList[IsPointSection-1].Type = POINT_TYPE_INVALID;
598
                                                       
605
                                                       
599
                                                                switch(PointList[IsPointSection-1].Type)
606
                                                                switch(PointList[IsPointSection-1].Type)
600
                                                                {
607
                                                                {
601
                                                                        case POINT_TYPE_WP:
608
                                                                        case POINT_TYPE_WP:
602
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
609
                                                                                // this works only if altitude key is set before point type key in WPL file     !!
603
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
610
                                                                                PointList[IsPointSection-1].Position.Altitude /= 10; // dm only for WPs 
604
                                                                                WPCount++;
611
                                                                                WPCount++;
605
                                                                                break;
612
                                                                                break;
606
 
613
 
607
                                                                        case POINT_TYPE_POI:
614
                                                                        case POINT_TYPE_POI:
608
                                                                                POICount++;
615
                                                                                POICount++;
609
                                                                                break;
616
                                                                                break;
610
                                                                }
617
                                                                }
611
                                                        }
618
                                                        }
612
                                                        else if(strcmp(name, "PREFIX") == 0)
619
                                                        else if(strcmp(name, "PREFIX") == 0)
613
                                                        {
620
                                                        {
614
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
621
                                                                strncpy(PointList[IsPointSection-1].Name, value, 4);
615
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
622
                                                                PointList[IsPointSection-1].Name[3] = 0; // Terminate string
616
                                                        }
623
                                                        }
617
                                                        else
624
                                                        else
618
                                                        {
625
                                                        {
619
                                                                UART1_PutString("Unknown key: ");
626
                                                                UART1_PutString("Unknown key: ");
620
                                                                UART1_PutString(name);
627
                                                                UART1_PutString(name);
621
                                                                UART1_PutString("\r\n");
628
                                                                UART1_PutString("\r\n");
622
                                                        }      
629
                                                        }      
623
                                                } // EOF point section
630
                                                } // EOF point section
624
                                                else if(IsGeneralSection)
631
                                                else if(IsGeneralSection)
625
                                                {
632
                                                {
626
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
633
                                                        if(strcmp(name, "NUMBEROFWAYPOINTS") == 0)
627
                                                        {      
634
                                                        {      
628
                                                                WPNumber = (u8)atoi(value);
635
                                                                WPNumber = (u8)atoi(value);
629
                                                                if(!WPNumber) // no waypoints in file
636
                                                                if(!WPNumber) // no waypoints in file
630
                                                                {
637
                                                                {
631
                                                                        return(1); // we are done here  
638
                                                                        return(1); // we are done here  
632
                                                                }
639
                                                                }
633
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
640
                                                                else if(WPNumber > MAX_LIST_LEN) // number o points larger than ram list
634
                                                                {
641
                                                                {
635
                                                                        UART1_PutString("To much points!");
642
                                                                        UART1_PutString("To much points!");
636
                                                                        return(0);
643
                                                                        return(0);
637
                                                                }
644
                                                                }
638
                                                        }
645
                                                        }
639
                                                        else if (strcmp(name, "FILEVERSION") == 0)
646
                                                        else if (strcmp(name, "FILEVERSION") == 0)
640
                                                        {
647
                                                        {
641
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
648
                                                                if((u8)atoi(value) != WP_FILE_VERSION_COMPATIBLE)
642
                                                                {
649
                                                                {
643
                                                                        UART1_PutString("Bad file version!\r\n");
650
                                                                        UART1_PutString("Bad file version!\r\n");
644
                                                                        return(0);     
651
                                                                        return(0);     
645
                                                                }
652
                                                                }
646
                                                        }
653
                                                        }
-
 
654
                                                        else if (strcmp(name, "NAME") == 0)
-
 
655
                                                        {
-
 
656
                                                                u8 len = strlen(value);
-
 
657
                                                                if(len > 11)
-
 
658
                                                                value[11] = 0;
-
 
659
                                                                memcpy(pWPL_Store->Name, value, 12);
-
 
660
                                                        }
-
 
661
                                                        else if (strcmp(name, "POSITIONTYPE") == 0)
-
 
662
                                                        {
-
 
663
                                                                pWPL_Store->Type = (u8)atoi(value);
-
 
664
                                                        }
647
                                                        else
665
                                                        else
648
                                                        {
666
                                                        {
649
                                                                UART1_PutString("Unknown key: ");
667
                                                                UART1_PutString("Unknown key: ");
650
                                                                UART1_PutString(name);
668
                                                                UART1_PutString(name);
651
                                                                UART1_PutString("\r\n");
669
                                                                UART1_PutString("\r\n");
652
                                                        }
670
                                                        }
653
                                                } // EOF general section
671
                                                } // EOF general section
654
                                        } // EOF valid key entry
672
                                        } // EOF valid key entry
655
                                } // EOF key entry line
673
                                } // EOF key entry line
656
                        } // valid line
674
                        } // valid line
657
                } // EOF loop over all lines
675
                } // EOF loop over all lines
658
                fclose_(fp);
676
                fclose_(fp);
659
                NaviData.WaypointNumber = WPCount;
677
                NaviData.WaypointNumber = WPCount;
660
                UART1_PutString("ok\r\n");
678
                UART1_PutString("ok\r\n");
661
                retval = 1;                              
679
                retval = 1;                              
662
        } // EOF if(Fat16_IsValid())
680
        } // EOF if(Fat16_IsValid())
663
        else UART1_PutString("no file system found!\r\n");     
681
        else UART1_PutString("no file system found!\r\n");     
664
        return(retval);
682
        return(retval);
665
}
683
}
666
 
684
 
667
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
685
// move actual point list to ref pos., the point in the list marked by index gets the RefPos afterwards
668
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos)
686
u8 PointList_Move(u8 RefIndex, GPS_Pos_t* pRefPos)
669
{
687
{
670
        u8 retval = 0;
688
        u8 retval = 0;
671
        GPS_Pos_t RefPos_old;
689
        GPS_Pos_t RefPos_old;
672
        GPS_Pos_Deviation_t RefDeviation;
690
        GPS_Pos_Deviation_t RefDeviation;
673
         
691
         
674
        // check inputs for plausibility;
692
        // check inputs for plausibility;
675
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
693
        if((RefIndex == 0) || (RefIndex > PointCount)) return(retval); 
676
        if(pRefPos == NULL) return(retval);
694
        if(pRefPos == NULL) return(retval);
677
        if(pRefPos->Status == INVALID) return(retval);
695
        if(pRefPos->Status == INVALID) return(retval);
678
 
696
 
679
        // try to copy the old reference in point list to a local buffer
697
        // try to copy the old reference in point list to a local buffer
680
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &RefPos_old))
698
        if(GPSPos_Copy(&(PointList[RefIndex-1].Position), &RefPos_old))
681
        {
699
        {
682
                u8 i;
700
                u8 i;
683
                // for each point position in the list
701
                // for each point position in the list
684
                for(i = 0; i < PointCount; i++)
702
                for(i = 0; i < PointCount; i++)
685
                {
703
                {
686
                        retval = 0;
704
                        retval = 0;
687
                    // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
705
                    // calculate deviation form old ref, i.e the north and east shift of each point in the list from the reference position
688
                        if(!GPSPos_Deviation(&(PointList[i].Position), &RefPos_old, &RefDeviation)) break;
706
                        if(!GPSPos_Deviation(&(PointList[i].Position), &RefPos_old, &RefDeviation)) break;
689
                        // copy of the new reference position into this list place
707
                        // copy of the new reference position into this list place
690
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
708
                        if(!GPSPos_Copy(pRefPos, &(PointList[i].Position))) break;
691
                        // move new reference according to the deviation of the old reference
709
                        // move new reference according to the deviation of the old reference
692
                        retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
710
                        retval = GPSPos_ShiftCartesian(&(PointList[i].Position), RefDeviation.North, RefDeviation.East);
693
                        if(!retval) break;             
711
                        if(!retval) break;             
694
                }
712
                }
695
        } // else ref pos old not copied!
713
        } // else ref pos old not copied!
696
        if(!retval) PointList_Clear();
714
        if(!retval) PointList_Clear();
697
        return(retval);
715
        return(retval);
698
}
716
}
699
 
717
 
700
 
718
 
701
 
719
 
702
 
720