2011-03-21 04:25:48 -03:00
|
|
|
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
2010-09-11 03:13:28 -03:00
|
|
|
//
|
|
|
|
// This is free software; you can redistribute it and/or modify it under
|
|
|
|
// the terms of the GNU Lesser General Public License as published by the
|
|
|
|
// Free Software Foundation; either version 2.1 of the License, or (at
|
|
|
|
// your option) any later version.
|
|
|
|
//
|
|
|
|
|
|
|
|
///
|
|
|
|
/// @file AP_Common.h
|
|
|
|
/// @brief Common definitions and utility routines for the ArduPilot
|
|
|
|
/// libraries.
|
|
|
|
///
|
|
|
|
|
2010-09-24 02:50:02 -03:00
|
|
|
#ifndef _AP_COMMON_H
|
|
|
|
#define _AP_COMMON_H
|
|
|
|
|
2011-01-23 22:44:31 -04:00
|
|
|
// Get the common arduino functions
|
2012-01-27 23:25:47 -04:00
|
|
|
#if defined(ARDUINO) && ARDUINO >= 100
|
|
|
|
#include "Arduino.h"
|
|
|
|
#else
|
|
|
|
#include "wiring.h"
|
|
|
|
#endif
|
2011-01-23 22:44:31 -04:00
|
|
|
// ... and remove some of their stupid macros
|
|
|
|
#undef round
|
|
|
|
#undef abs
|
|
|
|
|
2011-03-21 04:25:48 -03:00
|
|
|
// prog_char_t is used as a wrapper type for prog_char, which is
|
|
|
|
// a character stored in flash. By using this wrapper type we can
|
|
|
|
// auto-detect at compile time if a call to a string function is using
|
|
|
|
// a flash-stored string or not
|
|
|
|
typedef struct {
|
2011-10-28 15:43:43 -03:00
|
|
|
char c;
|
2011-03-21 04:25:48 -03:00
|
|
|
} prog_char_t;
|
|
|
|
|
2010-09-24 02:50:02 -03:00
|
|
|
#include <stdint.h>
|
|
|
|
#include "include/menu.h" /// simple menu subsystem
|
2010-12-23 19:02:51 -04:00
|
|
|
#include "c++.h" // c++ additions
|
2011-01-23 19:48:07 -04:00
|
|
|
//#include "AP_Vector.h"
|
|
|
|
//#include "AP_Loop.h"
|
2012-02-11 07:52:54 -04:00
|
|
|
#include "AP_Param.h"
|
2011-01-23 22:44:31 -04:00
|
|
|
|
|
|
|
|
2010-11-27 19:27:08 -04:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// @name Warning control
|
|
|
|
//@{
|
|
|
|
//
|
|
|
|
// Turn on/off warnings of interest.
|
|
|
|
//
|
|
|
|
// These warnings are normally suppressed by the Arduino IDE,
|
|
|
|
// but with some minor hacks it's possible to have warnings
|
|
|
|
// emitted. This helps greatly when diagnosing subtle issues.
|
|
|
|
//
|
|
|
|
#pragma GCC diagnostic warning "-Wall"
|
|
|
|
#pragma GCC diagnostic warning "-Wextra"
|
|
|
|
#pragma GCC diagnostic warning "-Wlogical-op"
|
|
|
|
#pragma GCC diagnostic ignored "-Wredundant-decls"
|
|
|
|
|
|
|
|
// Make some dire warnings into errors
|
|
|
|
//
|
|
|
|
// Some warnings indicate questionable code; rather than let
|
|
|
|
// these slide, we force them to become errors so that the
|
|
|
|
// developer has to find a safer alternative.
|
|
|
|
//
|
2011-06-22 02:54:55 -03:00
|
|
|
//#pragma GCC diagnostic error "-Wfloat-equal"
|
2010-11-27 19:27:08 -04:00
|
|
|
|
|
|
|
// The following is strictly for type-checking arguments to printf_P calls
|
|
|
|
// in conjunction with a suitably modified Arduino IDE; never define for
|
|
|
|
// production as it generates bad code.
|
|
|
|
//
|
|
|
|
#if PRINTF_FORMAT_WARNING_DEBUG
|
|
|
|
# undef PSTR
|
|
|
|
# define PSTR(_x) _x // help the compiler with printf_P
|
|
|
|
# define float double // silence spurious format warnings for %f
|
|
|
|
#else
|
|
|
|
// This is a workaround for GCC bug c++/34734.
|
|
|
|
//
|
|
|
|
// The C++ compiler normally emits many spurious warnings for the use
|
|
|
|
// of PSTR (even though it generates correct code). This workaround
|
|
|
|
// has an equivalent effect but avoids the warnings, which otherwise
|
|
|
|
// make finding real issues difficult.
|
|
|
|
//
|
2011-10-09 08:03:42 -03:00
|
|
|
#ifdef DESKTOP_BUILD
|
2011-10-07 19:16:52 -03:00
|
|
|
# undef PROGMEM
|
|
|
|
# define PROGMEM __attribute__(())
|
|
|
|
#else
|
2010-12-28 19:51:12 -04:00
|
|
|
# undef PROGMEM
|
|
|
|
# define PROGMEM __attribute__(( section(".progmem.data") ))
|
2011-10-07 19:16:52 -03:00
|
|
|
#endif
|
|
|
|
|
2010-12-28 19:51:12 -04:00
|
|
|
# undef PSTR
|
2011-03-21 04:25:48 -03:00
|
|
|
# define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \
|
|
|
|
(prog_char_t *)&__c[0];}))
|
2010-11-27 19:27:08 -04:00
|
|
|
#endif
|
2011-03-21 04:25:48 -03:00
|
|
|
|
2011-03-21 04:26:03 -03:00
|
|
|
// a varient of PSTR() for progmem strings passed to %S in printf()
|
|
|
|
// this gets the gcc __format__ checking right
|
|
|
|
#define FPSTR(s) (wchar_t *)(s)
|
|
|
|
|
|
|
|
|
2011-03-21 04:25:48 -03:00
|
|
|
static inline int strcasecmp_P(const char *str1, const prog_char_t *pstr)
|
|
|
|
{
|
2011-10-28 15:43:43 -03:00
|
|
|
return strcasecmp_P(str1, (const prog_char *)pstr);
|
2011-03-21 04:25:48 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int strcmp_P(const char *str1, const prog_char_t *pstr)
|
|
|
|
{
|
2011-10-28 15:43:43 -03:00
|
|
|
return strcmp_P(str1, (const prog_char *)pstr);
|
2011-03-21 04:25:48 -03:00
|
|
|
}
|
|
|
|
|
2011-11-26 02:01:33 -04:00
|
|
|
static inline size_t strlen_P(const prog_char_t *pstr)
|
2011-03-21 04:25:48 -03:00
|
|
|
{
|
2011-11-26 02:01:33 -04:00
|
|
|
return strlen_P((const prog_char *)pstr);
|
|
|
|
}
|
|
|
|
|
2011-11-26 02:17:50 -04:00
|
|
|
static inline void *memcpy_P(void *dest, const prog_char_t *src, size_t n)
|
|
|
|
{
|
|
|
|
return memcpy_P(dest, (const prog_char *)src, n);
|
|
|
|
}
|
|
|
|
|
2011-11-26 02:01:33 -04:00
|
|
|
// strlcat_P() in AVR libc seems to be broken
|
|
|
|
static inline size_t strlcat_P(char *d, const prog_char_t *s, size_t bufsize)
|
|
|
|
{
|
|
|
|
size_t len1 = strlen(d);
|
|
|
|
size_t len2 = strlen_P(s);
|
|
|
|
size_t ret = len1 + len2;
|
|
|
|
|
|
|
|
if (len1+len2 >= bufsize) {
|
|
|
|
if (bufsize < (len1+1)) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
len2 = bufsize - (len1+1);
|
|
|
|
}
|
|
|
|
if (len2 > 0) {
|
|
|
|
memcpy_P(d+len1, s, len2);
|
|
|
|
d[len1+len2] = 0;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline char *strncpy_P(char *buffer, const prog_char_t *pstr, size_t buffer_size)
|
|
|
|
{
|
|
|
|
return strncpy_P(buffer, (const prog_char *)pstr, buffer_size);
|
2011-03-21 04:25:48 -03:00
|
|
|
}
|
|
|
|
|
2011-11-07 05:50:19 -04:00
|
|
|
|
|
|
|
// read something the size of a pointer. This makes the menu code more
|
|
|
|
// portable
|
|
|
|
static inline uintptr_t pgm_read_pointer(const void *s)
|
|
|
|
{
|
|
|
|
if (sizeof(uintptr_t) == sizeof(uint16_t)) {
|
|
|
|
return (uintptr_t)pgm_read_word(s);
|
|
|
|
} else {
|
|
|
|
union {
|
|
|
|
uintptr_t p;
|
|
|
|
uint8_t a[sizeof(uintptr_t)];
|
|
|
|
} u;
|
|
|
|
uint8_t i;
|
|
|
|
for (i=0; i< sizeof(uintptr_t); i++) {
|
|
|
|
u.a[i] = pgm_read_byte(i + (const prog_char *)s);
|
|
|
|
}
|
|
|
|
return u.p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-11-27 19:27:08 -04:00
|
|
|
//@}
|
|
|
|
|
2011-01-09 21:42:59 -04:00
|
|
|
|
2010-12-28 17:30:29 -04:00
|
|
|
///
|
|
|
|
/// @name Macros
|
|
|
|
/// @{
|
2011-01-09 21:42:59 -04:00
|
|
|
|
|
|
|
/// Define a constant string in program memory. This is a little more obvious
|
|
|
|
/// and less error-prone than typing the declaration out by hand. It's required
|
|
|
|
/// when passing PROGMEM strings to static object constructors because the PSTR
|
|
|
|
/// hack can't be used at global scope.
|
|
|
|
///
|
|
|
|
#define PROGMEM_STRING(_v, _s) static const char _v[] PROGMEM = _s
|
|
|
|
|
2010-12-28 17:30:29 -04:00
|
|
|
#define ToRad(x) (x*0.01745329252) // *pi/180
|
|
|
|
#define ToDeg(x) (x*57.2957795131) // *180/pi
|
|
|
|
// @}
|
|
|
|
|
|
|
|
|
2010-09-11 03:13:28 -03:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// @name Types
|
|
|
|
///
|
2011-03-05 00:39:23 -04:00
|
|
|
/// Data structures and types used throughout the libraries and applications. 0 = default
|
2011-04-16 01:49:46 -03:00
|
|
|
/// bit 0: Altitude is stored 0: Absolute, 1: Relative
|
|
|
|
/// bit 1: Chnage Alt between WP 0: Gradually, 1: ASAP
|
2011-05-01 01:55:07 -03:00
|
|
|
/// bit 2:
|
2011-04-16 01:49:46 -03:00
|
|
|
/// bit 3: Req.to hit WP.alt to continue 0: No, 1: Yes
|
|
|
|
/// bit 4: Relative to Home 0: No, 1: Yes
|
2011-03-05 00:39:23 -04:00
|
|
|
/// bit 5:
|
|
|
|
/// bit 6:
|
2011-04-16 01:49:46 -03:00
|
|
|
/// bit 7: Move to next Command 0: YES, 1: Loiter until commanded
|
2011-03-05 00:39:23 -04:00
|
|
|
|
2010-09-11 03:13:28 -03:00
|
|
|
//@{
|
|
|
|
|
|
|
|
struct Location {
|
2011-10-28 15:43:43 -03:00
|
|
|
uint8_t id; ///< command id
|
|
|
|
uint8_t options; ///< options bitmask (1<<0 = relative altitude)
|
|
|
|
uint8_t p1; ///< param 1
|
|
|
|
int32_t alt; ///< param 2 - Altitude in centimeters (meters * 100)
|
|
|
|
int32_t lat; ///< param 3 - Lattitude * 10**7
|
|
|
|
int32_t lng; ///< param 4 - Longitude * 10**7
|
2010-09-11 03:13:28 -03:00
|
|
|
};
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// @name Conversions
|
|
|
|
///
|
|
|
|
/// Conversion macros and factors.
|
|
|
|
///
|
|
|
|
//@{
|
|
|
|
|
|
|
|
/// XXX this should probably be replaced with radians()/degrees(), but their
|
|
|
|
/// inclusion in wiring.h makes doing that here difficult.
|
|
|
|
#define ToDeg(x) (x*57.2957795131) // *180/pi
|
2010-12-28 19:30:09 -04:00
|
|
|
#define ToRad(x) (x*0.01745329252) // *pi/180
|
2010-09-11 03:13:28 -03:00
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
|
|
|
|
#endif // _AP_COMMON_H
|