Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1702 - 1
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2
//
3
// This is free software; you can redistribute it and/or modify it under
4
// the terms of the GNU Lesser General Public License as published by the
5
// Free Software Foundation; either version 2.1 of the License, or (at
6
// your option) any later version.
7
//
8
 
9
///
10
/// @file               AP_Common.h
11
/// @brief              Common definitions and utility routines for the ArduPilot
12
///                             libraries.
13
///
14
 
15
#ifndef _AP_COMMON_H
16
#define _AP_COMMON_H
17
 
18
// Get the common arduino functions
19
#if defined(ARDUINO) && ARDUINO >= 100
20
        #include "Arduino.h"
21
#else
22
        #include "wiring.h"
23
#endif
24
// ... and remove some of their stupid macros
25
#undef round
26
#undef abs
27
 
28
// prog_char_t is used as a wrapper type for prog_char, which is
29
// a character stored in flash. By using this wrapper type we can
30
// auto-detect at compile time if a call to a string function is using
31
// a flash-stored string or not
32
typedef struct {
33
    char c;
34
} prog_char_t;
35
 
36
#include <stdint.h>
37
#include "include/menu.h"               /// simple menu subsystem
38
#include "c++.h" // c++ additions
39
//#include "AP_Vector.h"
40
//#include "AP_Loop.h"
41
 
42
// default to AP_Param system, unless USE_AP_VAR is defined
43
#ifdef USE_AP_VAR
44
#include "AP_Var.h"
45
#else
46
#include "AP_Param.h"
47
#endif
48
 
49
////////////////////////////////////////////////////////////////////////////////
50
/// @name       Warning control
51
//@{
52
//
53
// Turn on/off warnings of interest.
54
//
55
// These warnings are normally suppressed by the Arduino IDE,
56
// but with some minor hacks it's possible to have warnings
57
// emitted.  This helps greatly when diagnosing subtle issues.
58
//
59
#pragma GCC diagnostic warning "-Wall"
60
#pragma GCC diagnostic warning "-Wextra"
61
#pragma GCC diagnostic warning "-Wlogical-op"
62
#pragma GCC diagnostic ignored "-Wredundant-decls"
63
 
64
// Make some dire warnings into errors
65
//
66
// Some warnings indicate questionable code; rather than let
67
// these slide, we force them to become errors so that the
68
// developer has to find a safer alternative.
69
//
70
//#pragma GCC diagnostic error "-Wfloat-equal"
71
 
72
// The following is strictly for type-checking arguments to printf_P calls
73
// in conjunction with a suitably modified Arduino IDE; never define for
74
// production as it generates bad code.
75
//
76
#if PRINTF_FORMAT_WARNING_DEBUG
77
# undef PSTR
78
# define PSTR(_x)               _x              // help the compiler with printf_P
79
# define float double                   // silence spurious format warnings for %f
80
#else
81
// This is a workaround for GCC bug c++/34734.
82
//
83
// The C++ compiler normally emits many spurious warnings for the use
84
// of PSTR (even though it generates correct code).  This workaround
85
// has an equivalent effect but avoids the warnings, which otherwise
86
// make finding real issues difficult.
87
//
88
#ifdef DESKTOP_BUILD
89
# undef PROGMEM
90
# define PROGMEM __attribute__(())
91
#else
92
# undef PROGMEM
93
# define PROGMEM __attribute__(( section(".progmem.data") ))
94
#endif
95
 
96
# undef PSTR
97
# define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \
98
                (prog_char_t *)&__c[0];}))
99
#endif
100
 
101
// a varient of PSTR() for progmem strings passed to %S in printf()
102
// this gets the gcc __format__ checking right
103
#define FPSTR(s) (wchar_t *)(s)
104
 
105
 
106
static inline int strcasecmp_P(const char *str1, const prog_char_t *pstr)
107
{
108
    return strcasecmp_P(str1, (const prog_char *)pstr);
109
}
110
 
111
static inline int strcmp_P(const char *str1, const prog_char_t *pstr)
112
{
113
    return strcmp_P(str1, (const prog_char *)pstr);
114
}
115
 
116
static inline size_t strlen_P(const prog_char_t *pstr)
117
{
118
    return strlen_P((const prog_char *)pstr);
119
}
120
 
121
static inline void *memcpy_P(void *dest, const prog_char_t *src, size_t n)
122
{
123
    return memcpy_P(dest, (const prog_char *)src, n);
124
}
125
 
126
// strlcat_P() in AVR libc seems to be broken 
127
static inline size_t strlcat_P(char *d, const prog_char_t *s, size_t bufsize)
128
{
129
        size_t len1 = strlen(d);
130
        size_t len2 = strlen_P(s);
131
        size_t ret = len1 + len2;
132
 
133
        if (len1+len2 >= bufsize) {
134
                if (bufsize < (len1+1)) {
135
                        return ret;
136
                }
137
                len2 = bufsize - (len1+1);
138
        }
139
        if (len2 > 0) {
140
                memcpy_P(d+len1, s, len2);
141
                d[len1+len2] = 0;
142
        }
143
        return ret;
144
}
145
 
146
static inline char *strncpy_P(char *buffer, const prog_char_t *pstr, size_t buffer_size)
147
{
148
    return strncpy_P(buffer, (const prog_char *)pstr, buffer_size);
149
}
150
 
151
 
152
// read something the size of a pointer. This makes the menu code more
153
// portable
154
static inline uintptr_t pgm_read_pointer(const void *s)
155
{
156
    if (sizeof(uintptr_t) == sizeof(uint16_t)) {
157
        return (uintptr_t)pgm_read_word(s);
158
    } else {
159
        union {
160
            uintptr_t p;
161
            uint8_t a[sizeof(uintptr_t)];
162
        } u;
163
        uint8_t i;
164
        for (i=0; i< sizeof(uintptr_t); i++) {
165
            u.a[i] = pgm_read_byte(i + (const prog_char *)s);
166
        }
167
        return u.p;
168
    }
169
}
170
 
171
//@}
172
 
173
 
174
///
175
/// @name Macros
176
/// @{
177
 
178
/// Define a constant string in program memory.  This is a little more obvious
179
/// and less error-prone than typing the declaration out by hand.  It's required
180
/// when passing PROGMEM strings to static object constructors because the PSTR
181
/// hack can't be used at global scope.
182
///
183
#define PROGMEM_STRING(_v, _s)  static const char _v[] PROGMEM = _s
184
 
185
#define ToRad(x) (x*0.01745329252)      // *pi/180
186
#define ToDeg(x) (x*57.2957795131)      // *180/pi
187
// @}
188
 
189
 
190
////////////////////////////////////////////////////////////////////////////////
191
/// @name       Types
192
///
193
/// Data structures and types used throughout the libraries and applications. 0 = default
194
/// bit 0: Altitude is stored                       0: Absolute,        1: Relative
195
/// bit 1: Chnage Alt between WP                    0: Gradually,       1: ASAP
196
/// bit 2:
197
/// bit 3: Req.to hit WP.alt to continue    0: No,          1: Yes
198
/// bit 4: Relative to Home                                     0: No,                  1: Yes
199
/// bit 5:
200
/// bit 6:
201
/// bit 7: Move to next Command                     0: YES,             1: Loiter until commanded
202
 
203
//@{
204
 
205
struct Location {
206
    uint8_t             id;                                     ///< command id
207
    uint8_t             options;                        ///< options bitmask (1<<0 = relative altitude)
208
    uint8_t             p1;                                     ///< param 1
209
    int32_t             alt;                            ///< param 2 - Altitude in centimeters (meters * 100)
210
    int32_t             lat;                            ///< param 3 - Lattitude * 10**7
211
    int32_t             lng;                            ///< param 4 - Longitude * 10**7
212
};
213
 
214
//@}
215
 
216
////////////////////////////////////////////////////////////////////////////////
217
/// @name       Conversions
218
///
219
/// Conversion macros and factors.
220
///
221
//@{
222
 
223
/// XXX this should probably be replaced with radians()/degrees(), but their
224
/// inclusion in wiring.h makes doing that here difficult.
225
#define ToDeg(x) (x*57.2957795131)      // *180/pi
226
#define ToRad(x) (x*0.01745329252)      // *pi/180
227
 
228
//@}
229
 
230
#ifdef DESKTOP_BUILD
231
// used to report serious errors in autotest
232
# define SITL_debug(fmt, args...)  fprintf(stdout, "%s:%u " fmt, __FUNCTION__, __LINE__, ##args)
233
#else
234
# define SITL_debug(fmt, args...)
235
#endif
236
 
237
/*  Product IDs for all supported products follow */
238
 
239
#define AP_PRODUCT_ID_NONE                      0x00    // Hardware in the loop
240
#define AP_PRODUCT_ID_APM1_1280         0x01    // APM1 with 1280 CPUs
241
#define AP_PRODUCT_ID_APM1_2560         0x02    // APM1 with 2560 CPUs
242
#define AP_PRODUCT_ID_SITL                      0x03    // Software in the loop
243
#define AP_PRODUCT_ID_APM2ES_REV_C4 0x14        // APM2 with MPU6000ES_REV_C4
244
#define AP_PRODUCT_ID_APM2ES_REV_C5     0x15    // APM2 with MPU6000ES_REV_C5
245
#define AP_PRODUCT_ID_APM2ES_REV_D6     0x16    // APM2 with MPU6000ES_REV_D6
246
#define AP_PRODUCT_ID_APM2ES_REV_D7     0x17    // APM2 with MPU6000ES_REV_D7
247
#define AP_PRODUCT_ID_APM2ES_REV_D8     0x18    // APM2 with MPU6000ES_REV_D8   
248
#define AP_PRODUCT_ID_APM2_REV_C4       0x54    // APM2 with MPU6000_REV_C4     
249
#define AP_PRODUCT_ID_APM2_REV_C5       0x55    // APM2 with MPU6000_REV_C5     
250
#define AP_PRODUCT_ID_APM2_REV_D6       0x56    // APM2 with MPU6000_REV_D6             
251
#define AP_PRODUCT_ID_APM2_REV_D7       0x57    // APM2 with MPU6000_REV_D7     
252
#define AP_PRODUCT_ID_APM2_REV_D8       0x58    // APM2 with MPU6000_REV_D8     
253
#define AP_PRODUCT_ID_APM2_REV_D9       0x59    // APM2 with MPU6000_REV_D9     
254
 
255
#endif // _AP_COMMON_H