diff --git a/libraries/AP_HAL/AP_HAL.h b/libraries/AP_HAL/AP_HAL.h index 014e046095..65febcfe4f 100644 --- a/libraries/AP_HAL/AP_HAL.h +++ b/libraries/AP_HAL/AP_HAL.h @@ -16,6 +16,10 @@ #include "PPMInput.h" #include "PWMOutput.h" +#include "utility/Print.h" +#include "utility/Stream.h" +#include "utility/BetterStream.h" + /* HAL Class definition */ #include "HAL.h" diff --git a/libraries/AP_HAL/AP_HAL_Namespace.h b/libraries/AP_HAL/AP_HAL_Namespace.h index 65cc87860f..8e50df992a 100644 --- a/libraries/AP_HAL/AP_HAL_Namespace.h +++ b/libraries/AP_HAL/AP_HAL_Namespace.h @@ -34,6 +34,11 @@ namespace AP_HAL { class APM2PPMInput; class APM1PWMOutput; class APM2PWMOutput; + + /* Utility Classes */ + class Print; + class Stream; + class BetterStream; } diff --git a/libraries/AP_HAL/HAL.h b/libraries/AP_HAL/HAL.h index 020bf391c9..dc58e97791 100644 --- a/libraries/AP_HAL/HAL.h +++ b/libraries/AP_HAL/HAL.h @@ -49,11 +49,9 @@ public: AP_HAL::UARTDriver* uart1; AP_HAL::UARTDriver* uart2; AP_HAL::UARTDriver* uart3; - AP_HAL::I2CDriver* i2c; AP_HAL::SPIDriver* spi; AP_HAL::AnalogIn* analogIn; - AP_HAL::Storage* storage; AP_HAL::Log* log; AP_HAL::Console* console; diff --git a/libraries/AP_HAL/UARTDriver.h b/libraries/AP_HAL/UARTDriver.h index 8e4f6cb8e7..b365af3160 100644 --- a/libraries/AP_HAL/UARTDriver.h +++ b/libraries/AP_HAL/UARTDriver.h @@ -5,15 +5,46 @@ #include #include "AP_HAL_Namespace.h" +#include "utility/BetterStream.h" /* Pure virtual UARTDriver class */ - -class AP_HAL::UARTDriver { +class AP_HAL::UARTDriver : public AP_HAL::BetterStream { public: UARTDriver() {} - virtual void init(uint16_t baud) = 0; - /* XXX stub */ + virtual void begin(long baud) = 0; + virtual void begin(long baud, + unsigned int rxSpace, + unsigned int txSpace) = 0; + virtual void end() = 0; + virtual void flush() = 0; }; +/* Concrete EmptyUARTDriver class provided for convenience */ +class AP_HAL::EmptyUARTDriver : public AP_HAL::UARTDriver { +public: + EmptyUARTDriver() {} + /* Empty implementations of UARTDriver virtual methods */ + void begin(long b) {} + void begin(long b, unsigned int rxS, unsigned int txS) {} + void end() {} + void flush() {} + + /* Empty implementations of BetterStream virtual methods */ + void print_P(const prog_char_t *pstr) {} + void println_P(const prog_char_t *pstr) {} + void printf(const char *pstr, ...) {} + void _printf_P(const prog_char_t *pstr, ...) {} + int txspace() { return 1; } + + /* Empty implementations of Stream virtual methods */ + int available() { return 0; } + int read() { return -1; } + int peek() { return -1; } + + /* Empty implementations of Print virtual methods */ + size_t write(uint8_t c) { return 0; } +}; + + #endif // __AP_HAL_UART_DRIVER_H__ diff --git a/libraries/AP_HAL/utility/BetterStream.h b/libraries/AP_HAL/utility/BetterStream.h index 454f89f724..402e49051e 100644 --- a/libraries/AP_HAL/utility/BetterStream.h +++ b/libraries/AP_HAL/utility/BetterStream.h @@ -10,25 +10,39 @@ #ifndef __AP_HAL_UTILITY_BETTERSTREAM_H__ #define __AP_HAL_UTILITY_BETTERSTREAM_H__ +#include "../AP_HAL_Namespace.h" +#include "Stream.h" + +/* prog_char_t: */ +#include +#include + +/* AP_HAL::BetterStream is derived from Michael Smith's FastSerial library for + * Arduino. Mike's library has an implementation of _vprintf() for AVR. + * Please provide your own platform-specic implementation for this library. + * + * TODO: Segregate prog_char_t dependent functions to be available on AVR + * platform only, with default implementations elsewhere. + */ class AP_HAL::BetterStream : public AP_HAL::Stream { public: BetterStream(void) {} // Stream extensions - void print_P(const prog_char_t *); - void println_P(const prog_char_t *); - void printf(const char *, ...) - __attribute__ ((format(__printf__, 2, 3))); - void _printf_P(const prog_char *, ...) - __attribute__ ((format(__printf__, 2, 3))); + virtual void print_P(const prog_char_t *); + virtual void println_P(const prog_char_t *); + virtual void printf(const char *, ...) + __attribute__ ((format(__printf__, 2, 3))); + virtual void _printf_P(const prog_char *, ...) + __attribute__ ((format(__printf__, 2, 3))); virtual int txspace(void); #define printf_P(fmt, ...) _printf_P((const prog_char *)fmt, ## __VA_ARGS__) private: - void _vprintf(unsigned char, const char *, va_list) + virtual void _vprintf(unsigned char, const char *, va_list) __attribute__ ((format(__printf__, 3, 0))); diff --git a/libraries/AP_HAL/utility/Print.cpp b/libraries/AP_HAL/utility/Print.cpp new file mode 100644 index 0000000000..5c00b7d3ed --- /dev/null +++ b/libraries/AP_HAL/utility/Print.cpp @@ -0,0 +1,216 @@ +/* + Print.cpp - Base class that provides print() and println() + Copyright (c) 2008 David A. Mellis. All right reserved. + + This library 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. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + */ + +#include +#include +#include +#include + + +#include "../AP_HAL_Namespace.h" +#include "Print.h" +using namespace AP_HAL; + +/* default implementation: may be overridden */ +size_t Print::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; +} + +size_t Print::print(const char str[]) +{ + return write(str); +} + +size_t Print::print(char c) +{ + return write(c); +} + +size_t Print::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t Print::print(int n, int base) +{ + return print((long) n, base); +} + +size_t Print::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t Print::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t Print::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t Print::print(float n, int digits) +{ + return printFloat(n, digits); +} + +size_t Print::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t Print::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t Print::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t Print::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(float num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + +// Private Methods ///////////////////////////////////////////////////////////// + +size_t Print::printNumber(unsigned long n, uint8_t base) { + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t Print::printFloat(float number, uint8_t digits) +{ + size_t n = 0; + + // Handle negative numbers + if (number < 0.0) + { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + float rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) + { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} diff --git a/libraries/AP_HAL/utility/Print.h b/libraries/AP_HAL/utility/Print.h index 06d1cd9a30..2f6b70fd3f 100644 --- a/libraries/AP_HAL/utility/Print.h +++ b/libraries/AP_HAL/utility/Print.h @@ -20,6 +20,8 @@ #ifndef __AP_HAL_UTILITY_PRINT_H__ #define __AP_HAL_UTILITY_PRINT_H__ +#include "../AP_HAL_Namespace.h" + #include #include @@ -28,7 +30,6 @@ * - Removed methods for class String or _FlashStringHelper * - printFloat takes a float, not a double. (double === float on AVR, but * not on other platforms) - * - Integers use stdint names */ #define DEC 10 @@ -55,7 +56,7 @@ class AP_HAL::Print { size_t print(unsigned int, int = DEC); size_t print(long, int = DEC); size_t print(unsigned long, int = DEC); - size_t print(double, int = 2); + size_t print(float , int = 2); size_t println(const char[]); size_t println(char); @@ -64,7 +65,7 @@ class AP_HAL::Print { size_t println(unsigned int, int = DEC); size_t println(long, int = DEC); size_t println(unsigned long, int = DEC); - size_t println(double, int = 2); + size_t println(float , int = 2); size_t println(void); }; diff --git a/libraries/AP_HAL/utility/Stream.h b/libraries/AP_HAL/utility/Stream.h index 63d401c822..6cb6aba57e 100644 --- a/libraries/AP_HAL/utility/Stream.h +++ b/libraries/AP_HAL/utility/Stream.h @@ -2,6 +2,7 @@ #ifndef __AP_HAL_UTILITY_STREAM_H__ #define __AP_HAL_UTILITY_STREAM_H__ +#include "../AP_HAL_Namespace.h" #include "Print.h" /* A simple Stream library modeled after the bits we actually use diff --git a/libraries/AP_HAL_AVR/examples/APM1/APM1.pde b/libraries/AP_HAL_AVR/examples/APM1/APM1.pde index 6990a55432..2a6d8c752f 100644 --- a/libraries/AP_HAL_AVR/examples/APM1/APM1.pde +++ b/libraries/AP_HAL_AVR/examples/APM1/APM1.pde @@ -1,4 +1,5 @@ +#include #include #include