summaryrefslogtreecommitdiff
path: root/at91lib/utility
diff options
context:
space:
mode:
Diffstat (limited to 'at91lib/utility')
-rw-r--r--at91lib/utility/assert.h114
-rw-r--r--at91lib/utility/led.c162
-rw-r--r--at91lib/utility/led.h70
-rw-r--r--at91lib/utility/math.c91
-rw-r--r--at91lib/utility/math.h45
-rw-r--r--at91lib/utility/stdio.c512
-rw-r--r--at91lib/utility/trace.h236
7 files changed, 1230 insertions, 0 deletions
diff --git a/at91lib/utility/assert.h b/at91lib/utility/assert.h
new file mode 100644
index 0000000..5cccb61
--- /dev/null
+++ b/at91lib/utility/assert.h
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Definition of the ASSERT() and SANITY_CHECK() macros, which are used for
+/// runtime condition & parameter verifying.
+///
+/// !Usage
+///
+/// -# Use ASSERT() in your code to check the value of function parameters,
+/// return values, etc. *Warning:* the ASSERT() condition must not have
+/// any side-effect; otherwise, the program may not work properly
+/// anymore when assertions are disabled.
+/// -# Use SANITY_CHECK() to perform checks with a default error message
+/// (outputs the file and line number where the error occured). This
+/// reduces memory overhead caused by assertion error strings.
+/// -# Initialize the dbgu to see failed assertions at run-time.
+/// -# Assertions can be entirely disabled by defining the NOASSERT symbol
+/// at compilation time.
+//------------------------------------------------------------------------------
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <stdio.h>
+#include "trace.h"
+
+//------------------------------------------------------------------------------
+// Definitions
+//------------------------------------------------------------------------------
+#if defined(NOASSERT)
+ #define ASSERT(...)
+ #define SANITY_CHECK(...)
+#else
+
+ #if (TRACE_LEVEL == 0)
+ /// Checks that the given condition is true,
+ /// otherwise stops the program execution.
+ /// \param condition Condition to verify.
+ #define ASSERT(condition, ...) { \
+ if (!(condition)) { \
+ while (1); \
+ } \
+ }
+
+ /// Performs the same duty as the ASSERT() macro
+ /// \param condition Condition to verify.
+ #define SANITY_CHECK(condition) ASSERT(condition, ...)
+
+ #else
+ /// Checks that the given condition is true, otherwise displays an error
+ /// message and stops the program execution.
+ /// \param condition Condition to verify.
+ #define ASSERT(condition, ...) { \
+ if (!(condition)) { \
+ printf("-F- ASSERT: "); \
+ printf(__VA_ARGS__); \
+ while (1); \
+ } \
+ }
+ #define SANITY_ERROR "Sanity check failed at %s:%d\n\r"
+
+ /// Performs the same duty as the ASSERT() macro, except a default error
+ /// message is output if the condition is false.
+ /// \param condition Condition to verify.
+ #define SANITY_CHECK(condition) ASSERT(condition, SANITY_ERROR, __FILE__, __LINE__)
+ #endif
+#endif
+
+
+
+
+
+
+
+
+
+
+#endif //#ifndef ASSERT_H
+
diff --git a/at91lib/utility/led.c b/at91lib/utility/led.c
new file mode 100644
index 0000000..7048b2a
--- /dev/null
+++ b/at91lib/utility/led.c
@@ -0,0 +1,162 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "led.h"
+#include <board.h>
+#include <pio/pio.h>
+
+//------------------------------------------------------------------------------
+// Local Variables
+//------------------------------------------------------------------------------
+
+#ifdef PINS_LEDS
+static const Pin pinsLeds[] = {PINS_LEDS};
+static const unsigned int numLeds = PIO_LISTSIZE(pinsLeds);
+#endif
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Configures the pin associated with the given LED number. If the LED does
+/// not exist on the board, the function does nothing.
+/// \param led Number of the LED to configure.
+/// \return 1 if the LED exists and has been configured; otherwise 0.
+//------------------------------------------------------------------------------
+unsigned char LED_Configure(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check that LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Configure LED
+ return (PIO_Configure(&pinsLeds[led], 1));
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Turns the given LED on if it exists; otherwise does nothing.
+/// \param led Number of the LED to turn on.
+/// \return 1 if the LED has been turned on; 0 otherwise.
+//------------------------------------------------------------------------------
+unsigned char LED_Set(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Turn LED on
+ if (pinsLeds[led].type == PIO_OUTPUT_0) {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Turns a LED off.
+/// \param led Number of the LED to turn off.
+/// \param 1 if the LED has been turned off; 0 otherwise.
+//------------------------------------------------------------------------------
+unsigned char LED_Clear(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Turn LED off
+ if (pinsLeds[led].type == PIO_OUTPUT_0) {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//------------------------------------------------------------------------------
+/// Toggles the current state of a LED.
+/// \param led Number of the LED to toggle.
+/// \return 1 if the LED has been toggled; otherwise 0.
+//------------------------------------------------------------------------------
+unsigned char LED_Toggle(unsigned int led)
+{
+#ifdef PINS_LEDS
+ // Check if LED exists
+ if (led >= numLeds) {
+
+ return 0;
+ }
+
+ // Toggle LED
+ if (PIO_GetOutputDataStatus(&pinsLeds[led])) {
+
+ PIO_Clear(&pinsLeds[led]);
+ }
+ else {
+
+ PIO_Set(&pinsLeds[led]);
+ }
+
+ return 1;
+#else
+ return 0;
+#endif
+}
+
diff --git a/at91lib/utility/led.h b/at91lib/utility/led.h
new file mode 100644
index 0000000..3f4878f
--- /dev/null
+++ b/at91lib/utility/led.h
@@ -0,0 +1,70 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Small set of functions for simple and portable LED usage.
+///
+/// !Usage
+///
+/// -# Configure one or more LEDs using LED_Configure and
+/// LED_ConfigureAll.
+/// -# Set, clear and toggle LEDs using LED_Set, LED_Clear and
+/// LED_Toggle.
+///
+/// LEDs are numbered starting from 0; the number of LEDs depend on the
+/// board being used. All the functions defined here will compile properly
+/// regardless of whether the LED is defined or not; they will simply
+/// return 0 when a LED which does not exist is given as an argument.
+/// Also, these functions take into account how each LED is connected on to
+/// board; thus, <LED_Set> might change the level on the corresponding pin
+/// to 0 or 1, but it will always light the LED on; same thing for the other
+/// methods.
+//------------------------------------------------------------------------------
+
+#ifndef LED_H
+#define LED_H
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+extern unsigned char LED_Configure(unsigned int led);
+
+extern unsigned char LED_Set(unsigned int led);
+
+extern unsigned char LED_Clear(unsigned int led);
+
+extern unsigned char LED_Toggle(unsigned int led);
+
+#endif //#ifndef LED_H
+
diff --git a/at91lib/utility/math.c b/at91lib/utility/math.c
new file mode 100644
index 0000000..6012385
--- /dev/null
+++ b/at91lib/utility/math.c
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include "math.h"
+#include "trace.h"
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Returns the minimum value between two integers.
+/// \param a First integer to compare.
+/// \param b Second integer to compare.
+//------------------------------------------------------------------------------
+unsigned int min(unsigned int a, unsigned int b)
+{
+ if (a < b) {
+
+ return a;
+ }
+ else {
+
+ return b;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Returns the absolute value of an integer.
+/// \param value Integer value.
+//------------------------------------------------------------------------------
+// Do not call this function "abs", problem with gcc !
+unsigned int absv(signed int value)
+{
+ if (value < 0) {
+
+ return -value;
+ }
+ else {
+
+ return value;
+ }
+}
+
+//------------------------------------------------------------------------------
+/// Computes and returns x power of y.
+/// \param x Value.
+/// \param y Power.
+//------------------------------------------------------------------------------
+unsigned int power(unsigned int x, unsigned int y)
+{
+ unsigned int result = 1;
+
+ while (y > 0) {
+
+ result *= x;
+ y--;
+ }
+ return result;
+}
+
diff --git a/at91lib/utility/math.h b/at91lib/utility/math.h
new file mode 100644
index 0000000..3406075
--- /dev/null
+++ b/at91lib/utility/math.h
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef MATH_H
+#define MATH_H
+
+//------------------------------------------------------------------------------
+// Exported functions
+//------------------------------------------------------------------------------
+
+extern unsigned int min(unsigned int a, unsigned int b);
+extern unsigned int absv(signed int value);
+#if defined(__ARMCC_VERSION)
+extern unsigned int pow(unsigned int x, unsigned int y);
+#else
+extern unsigned int power(unsigned int x, unsigned int y);
+#endif
+#endif //#ifndef MATH_H
+
diff --git a/at91lib/utility/stdio.c b/at91lib/utility/stdio.c
new file mode 100644
index 0000000..3e76ddc
--- /dev/null
+++ b/at91lib/utility/stdio.c
@@ -0,0 +1,512 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Implementation of several stdio.h methods, such as printf(), sprintf() and
+/// so on. This reduces the memory footprint of the binary when using those
+/// methods, compared to the libc implementation.
+///
+/// !Usage
+///
+/// Adds stdio.c to the list of file to compile for the project. This will
+/// automatically replace libc methods by the custom ones.
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdarg.h>
+
+//------------------------------------------------------------------------------
+// Local Definitions
+//------------------------------------------------------------------------------
+
+// Maximum string size allowed (in bytes).
+#define MAX_STRING_SIZE 100
+
+//------------------------------------------------------------------------------
+// Global Variables
+//------------------------------------------------------------------------------
+
+// Required for proper compilation.
+struct _reent r = {0, (FILE *) 0, (FILE *) 1, (FILE *) 0};
+struct _reent *_impure_ptr = &r;
+
+//------------------------------------------------------------------------------
+// Local Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+// Writes a character inside the given string. Returns 1.
+// \param pStr Storage string.
+// \param c Character to write.
+//------------------------------------------------------------------------------
+signed int PutChar(char *pStr, char c)
+{
+ *pStr = c;
+ return 1;
+}
+
+//------------------------------------------------------------------------------
+// Writes a string inside the given string.
+// Returns the size of the written
+// string.
+// \param pStr Storage string.
+// \param pSource Source string.
+//------------------------------------------------------------------------------
+signed int PutString(char *pStr, const char *pSource)
+{
+ signed int num = 0;
+
+ while (*pSource != 0) {
+
+ *pStr++ = *pSource++;
+ num++;
+ }
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an unsigned int inside the given string, using the provided fill &
+// width parameters.
+// Returns the size in characters of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param value Integer value.
+//------------------------------------------------------------------------------
+signed int PutUnsignedInt(
+ char *pStr,
+ char fill,
+ signed int width,
+ unsigned int value)
+{
+ signed int num = 0;
+
+ // Take current digit into account when calculating width
+ width--;
+
+ // Recursively write upper digits
+ if ((value / 10) > 0) {
+
+ num = PutUnsignedInt(pStr, fill, width, value / 10);
+ pStr += num;
+ }
+ // Write filler characters
+ else {
+
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+ }
+
+ // Write lower digit
+ num += PutChar(pStr, (value % 10) + '0');
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes a signed int inside the given string, using the provided fill & width
+// parameters.
+// Returns the size of the written integer.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param value Signed integer value.
+//------------------------------------------------------------------------------
+signed int PutSignedInt(
+ char *pStr,
+ char fill,
+ signed int width,
+ signed int value)
+{
+ signed int num = 0;
+ unsigned int absolute;
+
+ // Compute absolute value
+ if (value < 0) {
+
+ absolute = -value;
+ }
+ else {
+
+ absolute = value;
+ }
+
+ // Take current digit into account when calculating width
+ width--;
+
+ // Recursively write upper digits
+ if ((absolute / 10) > 0) {
+
+ if (value < 0) {
+
+ num = PutSignedInt(pStr, fill, width, -(absolute / 10));
+ }
+ else {
+
+ num = PutSignedInt(pStr, fill, width, absolute / 10);
+ }
+ pStr += num;
+ }
+ else {
+
+ // Reserve space for sign
+ if (value < 0) {
+
+ width--;
+ }
+
+ // Write filler characters
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+
+ // Write sign
+ if (value < 0) {
+
+ num += PutChar(pStr, '-');
+ pStr++;
+ }
+ }
+
+ // Write lower digit
+ num += PutChar(pStr, (absolute % 10) + '0');
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Writes an hexadecimal value into a string, using the given fill, width &
+// capital parameters.
+// Returns the number of char written.
+// \param pStr Storage string.
+// \param fill Fill character.
+// \param width Minimum integer width.
+// \param maj Indicates if the letters must be printed in lower- or upper-case.
+// \param value Hexadecimal value.
+//------------------------------------------------------------------------------
+signed int PutHexa(
+ char *pStr,
+ char fill,
+ signed int width,
+ unsigned char maj,
+ unsigned int value)
+{
+ signed int num = 0;
+
+ // Decrement width
+ width--;
+
+ // Recursively output upper digits
+ if ((value >> 4) > 0) {
+
+ num += PutHexa(pStr, fill, width, maj, value >> 4);
+ pStr += num;
+ }
+ // Write filler chars
+ else {
+
+ while (width > 0) {
+
+ PutChar(pStr, fill);
+ pStr++;
+ num++;
+ width--;
+ }
+ }
+
+ // Write current digit
+ if ((value & 0xF) < 10) {
+
+ PutChar(pStr, (value & 0xF) + '0');
+ }
+ else if (maj) {
+
+ PutChar(pStr, (value & 0xF) - 10 + 'A');
+ }
+ else {
+
+ PutChar(pStr, (value & 0xF) - 10 + 'a');
+ }
+ num++;
+
+ return num;
+}
+
+//------------------------------------------------------------------------------
+// Global Functions
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pStr Destination string.
+/// \param length Length of Destination string.
+/// \param pFormat Format string.
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vsnprintf(char *pStr, size_t length, const char *pFormat, va_list ap)
+{
+ char fill;
+ unsigned char width;
+ signed int num = 0;
+ signed int size = 0;
+
+ // Clear the string
+ if (pStr) {
+
+ *pStr = 0;
+ }
+
+ // Phase string
+ while (*pFormat != 0 && size < length) {
+
+ // Normal character
+ if (*pFormat != '%') {
+
+ *pStr++ = *pFormat++;
+ size++;
+ }
+ // Escaped '%'
+ else if (*(pFormat+1) == '%') {
+
+ *pStr++ = '%';
+ pFormat += 2;
+ size++;
+ }
+ // Token delimiter
+ else {
+
+ fill = ' ';
+ width = 0;
+ pFormat++;
+
+ // Parse filler
+ if (*pFormat == '0') {
+
+ fill = '0';
+ pFormat++;
+ }
+
+ // Parse width
+ while ((*pFormat >= '0') && (*pFormat <= '9')) {
+
+ width = (width*10) + *pFormat-'0';
+ pFormat++;
+ }
+
+ // Check if there is enough space
+ if (size + width > length) {
+
+ width = length - size;
+ }
+
+ // Parse type
+ switch (*pFormat) {
+ case 'd':
+ case 'i': num = PutSignedInt(pStr, fill, width, va_arg(ap, signed int)); break;
+ case 'u': num = PutUnsignedInt(pStr, fill, width, va_arg(ap, unsigned int)); break;
+ case 'x': num = PutHexa(pStr, fill, width, 0, va_arg(ap, unsigned int)); break;
+ case 'X': num = PutHexa(pStr, fill, width, 1, va_arg(ap, unsigned int)); break;
+ case 's': num = PutString(pStr, va_arg(ap, char *)); break;
+ case 'c': num = PutChar(pStr, va_arg(ap, unsigned int)); break;
+ default:
+ return EOF;
+ }
+
+ pFormat++;
+ pStr += num;
+ size += num;
+ }
+ }
+
+ // NULL-terminated (final \0 is not counted)
+ if (size < length) {
+
+ *pStr = 0;
+ }
+ else {
+
+ *(--pStr) = 0;
+ size--;
+ }
+
+ return size;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString Destination string.
+/// \param length Length of Destination string.
+/// \param pFormat Format string.
+/// \param ... Other arguments
+//------------------------------------------------------------------------------
+signed int snprintf(char *pString, size_t length, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int rc;
+
+ va_start(ap, pFormat);
+ rc = vsnprintf(pString, length, pFormat, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+//------------------------------------------------------------------------------
+/// Stores the result of a formatted string into another string. Format
+/// arguments are given in a va_list instance.
+/// Return the number of characters written.
+/// \param pString Destination string.
+/// \param pFormat Format string.
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vsprintf(char *pString, const char *pFormat, va_list ap)
+{
+ return vsnprintf(pString, MAX_STRING_SIZE, pFormat, ap);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the given stream. Format arguments are given
+/// in a va_list instance.
+/// \param pStream Output stream.
+/// \param pFormat Format string
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vfprintf(FILE *pStream, const char *pFormat, va_list ap)
+{
+ char pStr[MAX_STRING_SIZE];
+ char pError[] = "stdio.c: increase MAX_STRING_SIZE\n\r";
+
+ // Write formatted string in buffer
+ if (vsprintf(pStr, pFormat, ap) >= MAX_STRING_SIZE) {
+
+ fputs(pError, stderr);
+ while (1); // Increase MAX_STRING_SIZE
+ }
+
+ // Display string
+ return fputs(pStr, pStream);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream. Format arguments are given
+/// in a va_list instance.
+/// \param pFormat Format string
+/// \param ap Argument list.
+//------------------------------------------------------------------------------
+signed int vprintf(const char *pFormat, va_list ap)
+{
+ return vfprintf(stdout, pFormat, ap);
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the given stream, using a variable number of
+/// arguments.
+/// \param pStream Output stream.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int fprintf(FILE *pStream, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vfprintf
+ va_start(ap, pFormat);
+ result = vfprintf(pStream, pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string on the DBGU stream, using a variable number of
+/// arguments.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int printf(const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vprintf
+ va_start(ap, pFormat);
+ result = vprintf(pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Writes a formatted string inside another string.
+/// \param pStr Storage string.
+/// \param pFormat Format string.
+//------------------------------------------------------------------------------
+signed int sprintf(char *pStr, const char *pFormat, ...)
+{
+ va_list ap;
+ signed int result;
+
+ // Forward call to vsprintf
+ va_start(ap, pFormat);
+ result = vsprintf(pStr, pFormat, ap);
+ va_end(ap);
+
+ return result;
+}
+
+//------------------------------------------------------------------------------
+/// Outputs a string on stdout.
+/// \param pStr String to output.
+//------------------------------------------------------------------------------
+signed int puts(const char *pStr)
+{
+ return fputs(pStr, stdout);
+}
+
diff --git a/at91lib/utility/trace.h b/at91lib/utility/trace.h
new file mode 100644
index 0000000..d996dcd
--- /dev/null
+++ b/at91lib/utility/trace.h
@@ -0,0 +1,236 @@
+/* ----------------------------------------------------------------------------
+ * ATMEL Microcontroller Software Support
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2008, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+//------------------------------------------------------------------------------
+/// \unit
+///
+/// !Purpose
+///
+/// Standard output methods for reporting debug information, warnings and
+/// errors, which can be easily be turned on/off.
+///
+/// !Usage
+/// -# Initialize the DBGU using TRACE_CONFIGURE() if you intend to eventually
+/// disable ALL traces; otherwise use DBGU_Configure().
+/// -# Uses the TRACE_DEBUG(), TRACE_INFO(), TRACE_WARNING(), TRACE_ERROR()
+/// TRACE_FATAL() macros to output traces throughout the program.
+/// -# Each type of trace has a level : Debug 5, Info 4, Warning 3, Error 2
+/// and Fatal 1. Disable a group of traces by changing the value of
+/// TRACE_LEVEL during compilation; traces with a level bigger than TRACE_LEVEL
+/// are not generated. To generate no trace, use the reserved value 0.
+/// -# Trace disabling can be static or dynamic. If dynamic disabling is selected
+/// the trace level can be modified in runtime. If static disabling is selected
+/// the disabled traces are not compiled.
+///
+/// !Trace level description
+/// -# TRACE_DEBUG (5): Traces whose only purpose is for debugging the program,
+/// and which do not produce meaningful information otherwise.
+/// -# TRACE_INFO (4): Informational trace about the program execution. Should
+/// enable the user to see the execution flow.
+/// -# TRACE_WARNING (3): Indicates that a minor error has happened. In most case
+/// it can be discarded safely; it may even be expected.
+/// -# TRACE_ERROR (2): Indicates an error which may not stop the program execution,
+/// but which indicates there is a problem with the code.
+/// -# TRACE_FATAL (1): Indicates a major error which prevents the program from going
+/// any further.
+
+//------------------------------------------------------------------------------
+
+#ifndef TRACE_H
+#define TRACE_H
+
+//------------------------------------------------------------------------------
+// Headers
+//------------------------------------------------------------------------------
+
+#include <board.h>
+#include <dbgu/dbgu.h>
+#include <pio/pio.h>
+#include <stdio.h>
+
+//------------------------------------------------------------------------------
+// Global Definitions
+//------------------------------------------------------------------------------
+
+/// Softpack Version
+#define SOFTPACK_VERSION "1.5"
+
+#define TRACE_LEVEL_DEBUG 5
+#define TRACE_LEVEL_INFO 4
+#define TRACE_LEVEL_WARNING 3
+#define TRACE_LEVEL_ERROR 2
+#define TRACE_LEVEL_FATAL 1
+#define TRACE_LEVEL_NO_TRACE 0
+
+// By default, all traces are output except the debug one.
+#if !defined(TRACE_LEVEL)
+#define TRACE_LEVEL TRACE_LEVEL_INFO
+#endif
+
+// By default, trace level is static (not dynamic)
+#if !defined(DYN_TRACES)
+#define DYN_TRACES 0
+#endif
+
+#if defined(NOTRACE)
+#error "Error: NOTRACE has to be not defined !"
+#endif
+
+#undef NOTRACE
+#if (TRACE_LEVEL == TRACE_LEVEL_NO_TRACE)
+#define NOTRACE
+#endif
+
+
+
+//------------------------------------------------------------------------------
+// Global Macros
+//------------------------------------------------------------------------------
+
+//------------------------------------------------------------------------------
+/// Initializes the DBGU
+/// \param mode DBGU mode.
+/// \param baudrate DBGU baudrate.
+/// \param mck Master clock frequency.
+//------------------------------------------------------------------------------
+#define TRACE_CONFIGURE(mode, baudrate, mck) { \
+ const Pin pinsDbgu[] = {PINS_DBGU}; \
+ PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu)); \
+ DBGU_Configure(mode, baudrate, mck); \
+ }
+
+//------------------------------------------------------------------------------
+/// Initializes the DBGU for ISP project
+/// \param mode DBGU mode.
+/// \param baudrate DBGU baudrate.
+/// \param mck Master clock frequency.
+//------------------------------------------------------------------------------
+#if (TRACE_LEVEL==0) && (DYNTRACE==0)
+#define TRACE_CONFIGURE_ISP(mode, baudrate, mck) {}
+#else
+#define TRACE_CONFIGURE_ISP(mode, baudrate, mck) { \
+ const Pin pinsDbgu[] = {PINS_DBGU}; \
+ PIO_Configure(pinsDbgu, PIO_LISTSIZE(pinsDbgu)); \
+ DBGU_Configure(mode, baudrate, mck); \
+ }
+#endif
+
+//------------------------------------------------------------------------------
+/// Outputs a formatted string using <printf> if the log level is high
+/// enough. Can be disabled by defining TRACE_LEVEL=0 during compilation.
+/// \param format Formatted string to output.
+/// \param ... Additional parameters depending on formatted string.
+//------------------------------------------------------------------------------
+#if defined(NOTRACE)
+
+// Empty macro
+#define TRACE_DEBUG(...) { }
+#define TRACE_INFO(...) { }
+#define TRACE_WARNING(...) { }
+#define TRACE_ERROR(...) { }
+#define TRACE_FATAL(...) { while(1); }
+
+#define TRACE_DEBUG_WP(...) { }
+#define TRACE_INFO_WP(...) { }
+#define TRACE_WARNING_WP(...) { }
+#define TRACE_ERROR_WP(...) { }
+#define TRACE_FATAL_WP(...) { while(1); }
+
+#elif (DYN_TRACES == 1)
+
+// Trace output depends on traceLevel value
+#define TRACE_DEBUG(...) { if (traceLevel >= TRACE_LEVEL_DEBUG) { printf("-D- " __VA_ARGS__); } }
+#define TRACE_INFO(...) { if (traceLevel >= TRACE_LEVEL_INFO) { printf("-I- " __VA_ARGS__); } }
+#define TRACE_WARNING(...) { if (traceLevel >= TRACE_LEVEL_WARNING) { printf("-W- " __VA_ARGS__); } }
+#define TRACE_ERROR(...) { if (traceLevel >= TRACE_LEVEL_ERROR) { printf("-E- " __VA_ARGS__); } }
+#define TRACE_FATAL(...) { if (traceLevel >= TRACE_LEVEL_FATAL) { printf("-F- " __VA_ARGS__); while(1); } }
+
+#define TRACE_DEBUG_WP(...) { if (traceLevel >= TRACE_LEVEL_DEBUG) { printf(__VA_ARGS__); } }
+#define TRACE_INFO_WP(...) { if (traceLevel >= TRACE_LEVEL_INFO) { printf(__VA_ARGS__); } }
+#define TRACE_WARNING_WP(...) { if (traceLevel >= TRACE_LEVEL_WARNING) { printf(__VA_ARGS__); } }
+#define TRACE_ERROR_WP(...) { if (traceLevel >= TRACE_LEVEL_ERROR) { printf(__VA_ARGS__); } }
+#define TRACE_FATAL_WP(...) { if (traceLevel >= TRACE_LEVEL_FATAL) { printf(__VA_ARGS__); while(1); } }
+
+#else
+
+// Trace compilation depends on TRACE_LEVEL value
+#if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
+#define TRACE_DEBUG(...) { printf("-D- " __VA_ARGS__); }
+#define TRACE_DEBUG_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_DEBUG(...) { }
+#define TRACE_DEBUG_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
+#define TRACE_INFO(...) { printf("-I- " __VA_ARGS__); }
+#define TRACE_INFO_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_INFO(...) { }
+#define TRACE_INFO_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_WARNING)
+#define TRACE_WARNING(...) { printf("-W- " __VA_ARGS__); }
+#define TRACE_WARNING_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_WARNING(...) { }
+#define TRACE_WARNING_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_ERROR)
+#define TRACE_ERROR(...) { printf("-E- " __VA_ARGS__); }
+#define TRACE_ERROR_WP(...) { printf(__VA_ARGS__); }
+#else
+#define TRACE_ERROR(...) { }
+#define TRACE_ERROR_WP(...) { }
+#endif
+
+#if (TRACE_LEVEL >= TRACE_LEVEL_FATAL)
+#define TRACE_FATAL(...) { printf("-F- " __VA_ARGS__); while(1); }
+#define TRACE_FATAL_WP(...) { printf(__VA_ARGS__); while(1); }
+#else
+#define TRACE_FATAL(...) { while(1); }
+#define TRACE_FATAL_WP(...) { while(1); }
+#endif
+
+#endif
+
+
+//------------------------------------------------------------------------------
+// Exported variables
+//------------------------------------------------------------------------------
+// Depending on DYN_TRACES, traceLevel is a modifable runtime variable
+// or a define
+#if !defined(NOTRACE) && (DYN_TRACES == 1)
+ extern unsigned int traceLevel;
+#endif
+
+#endif //#ifndef TRACE_H
+
personal git repositories of Harald Welte. Your mileage may vary