1 |
/*! \file rprintf.h \brief printf routine and associated routines. */ |
1 |
/*! \file rprintf.h \brief printf routine and associated routines. */ |
2 |
//**************************************************************************** |
2 |
//**************************************************************************** |
3 |
// |
3 |
// |
4 |
// File Name : 'rprintf.h' |
4 |
// File Name : 'rprintf.h' |
5 |
// Title : printf routine and associated routines |
5 |
// Title : printf routine and associated routines |
6 |
// Author : Pascal Stang - Copyright (C) 2000-2002 |
6 |
// Author : Pascal Stang - Copyright (C) 2000-2002 |
7 |
// Created : 2000.12.26 |
7 |
// Created : 2000.12.26 |
8 |
// Revised : 2003.5.1 |
8 |
// Revised : 2003.5.1 |
9 |
// Version : 1.0 |
9 |
// Version : 1.0 |
10 |
// Target MCU : Atmel AVR series and other targets |
10 |
// Target MCU : Atmel AVR series and other targets |
11 |
// Editor Tabs : 4 |
11 |
// Editor Tabs : 4 |
12 |
// |
12 |
// |
13 |
// NOTE: This code is currently below version 1.0, and therefore is considered |
13 |
// NOTE: This code is currently below version 1.0, and therefore is considered |
14 |
// to be lacking in some functionality or documentation, or may not be fully |
14 |
// to be lacking in some functionality or documentation, or may not be fully |
15 |
// tested. Nonetheless, you can expect most functions to work. |
15 |
// tested. Nonetheless, you can expect most functions to work. |
16 |
// |
16 |
// |
17 |
// This code is distributed under the GNU Public License |
17 |
// This code is distributed under the GNU Public License |
18 |
// which can be found at http://www.gnu.org/licenses/gpl.txt |
18 |
// which can be found at http://www.gnu.org/licenses/gpl.txt |
19 |
// |
19 |
// |
20 |
/// \ingroup general |
20 |
/// \ingroup general |
21 |
/// \defgroup rprintf printf() Function Library (rprintf.c) |
21 |
/// \defgroup rprintf printf() Function Library (rprintf.c) |
22 |
/// \code #include "rprintf.h" \endcode |
22 |
/// \code #include "rprintf.h" \endcode |
23 |
/// \par Overview |
23 |
/// \par Overview |
24 |
/// The rprintf function library provides a simplified (reduced) version of |
24 |
/// The rprintf function library provides a simplified (reduced) version of |
25 |
/// the common C printf() function. See the code files for details about |
25 |
/// the common C printf() function. See the code files for details about |
26 |
/// which printf features are supported. Also in this library are a |
26 |
/// which printf features are supported. Also in this library are a |
27 |
/// variety of functions for fast printing of certain common data types |
27 |
/// variety of functions for fast printing of certain common data types |
28 |
/// (variable types). Functions include print string from RAM, print |
28 |
/// (variable types). Functions include print string from RAM, print |
29 |
/// string from ROM, print string snippet, print hex byte/short/long, and |
29 |
/// string from ROM, print string snippet, print hex byte/short/long, and |
30 |
/// a custom-formatted number print, as well as an optional floating-point |
30 |
/// a custom-formatted number print, as well as an optional floating-point |
31 |
/// print routine. |
31 |
/// print routine. |
32 |
/// |
32 |
/// |
33 |
/// \note All output from the rprintf library can be directed to any device |
33 |
/// \note All output from the rprintf library can be directed to any device |
34 |
/// or software which accepts characters. This means that rprintf output |
34 |
/// or software which accepts characters. This means that rprintf output |
35 |
/// can be sent to the UART (serial port) or can be used with the LCD |
35 |
/// can be sent to the UART (serial port) or can be used with the LCD |
36 |
/// display libraries to print formatted text on the screen. |
36 |
/// display libraries to print formatted text on the screen. |
37 |
// |
37 |
// |
38 |
//**************************************************************************** |
38 |
//**************************************************************************** |
39 |
//@{ |
39 |
//@{ |
40 |
|
40 |
|
41 |
#ifndef RPRINTF_H |
41 |
#ifndef RPRINTF_H |
42 |
#define RPRINTF_H |
42 |
#define RPRINTF_H |
43 |
|
43 |
|
44 |
// needed for use of PSTR below |
44 |
// needed for use of PSTR below |
45 |
#include <avr/pgmspace.h> |
45 |
#include <avr/pgmspace.h> |
46 |
|
46 |
|
47 |
// configuration |
47 |
// configuration |
48 |
// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function |
48 |
// defining RPRINTF_SIMPLE will compile a smaller, simpler, and faster printf() function |
49 |
// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function |
49 |
// defining RPRINTF_COMPLEX will compile a larger, more capable, and slower printf() function |
50 |
#ifndef RPRINTF_COMPLEX |
50 |
#ifndef RPRINTF_COMPLEX |
51 |
#define RPRINTF_SIMPLE |
51 |
#define RPRINTF_SIMPLE |
52 |
#endif |
52 |
#endif |
53 |
|
53 |
|
54 |
// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat() |
54 |
// Define RPRINTF_FLOAT to enable the floating-point printf function: rprintfFloat() |
55 |
// (adds +4600bytes or 2.2Kwords of code) |
55 |
// (adds +4600bytes or 2.2Kwords of code) |
56 |
|
56 |
|
57 |
// defines/constants |
57 |
// defines/constants |
58 |
#define STRING_IN_RAM 0 |
58 |
#define STRING_IN_RAM 0 |
59 |
#define STRING_IN_ROM 1 |
59 |
#define STRING_IN_ROM 1 |
60 |
|
60 |
|
61 |
// make a putchar for those that are used to using it |
61 |
// make a putchar for those that are used to using it |
62 |
//#define putchar(c) rprintfChar(c); |
62 |
//#define putchar(c) rprintfChar(c); |
63 |
|
63 |
|
64 |
// functions |
64 |
// functions |
65 |
|
65 |
|
66 |
//! Initializes the rprintf library for an output stream. |
66 |
//! Initializes the rprintf library for an output stream. |
67 |
/// You must call this initializer once before using any other rprintf function. |
67 |
/// You must call this initializer once before using any other rprintf function. |
68 |
/// The argument must be a character stream output function. |
68 |
/// The argument must be a character stream output function. |
69 |
void rprintfInit(void (*putchar_func)(unsigned char c)); |
69 |
void rprintfInit(void (*putchar_func)(unsigned char c)); |
70 |
|
70 |
|
71 |
//! prints a single character to the current output device |
71 |
//! prints a single character to the current output device |
72 |
void rprintfChar(unsigned char c); |
72 |
void rprintfChar(unsigned char c); |
73 |
|
73 |
|
74 |
//! prints a null-terminated string stored in RAM |
74 |
//! prints a null-terminated string stored in RAM |
75 |
void rprintfStr(char str[]); |
75 |
void rprintfStr(char str[]); |
76 |
|
76 |
|
77 |
//! Prints a section of a string stored in RAM. |
77 |
//! Prints a section of a string stored in RAM. |
78 |
/// Begins printing at position indicated by <start>, |
78 |
/// Begins printing at position indicated by <start>, |
79 |
/// and prints number of characters indicated by <len>. |
79 |
/// and prints number of characters indicated by <len>. |
80 |
void rprintfStrLen(char str[], unsigned int start, unsigned int len); |
80 |
void rprintfStrLen(char str[], unsigned int start, unsigned int len); |
81 |
|
81 |
|
82 |
//! prints a string stored in program rom |
82 |
//! prints a string stored in program rom |
83 |
/// \note This function does not actually store your string in |
83 |
/// \note This function does not actually store your string in |
84 |
/// program rom, but merely reads it assuming you stored it properly. |
84 |
/// program rom, but merely reads it assuming you stored it properly. |
85 |
void rprintfProgStr(const prog_char str[]); |
85 |
void rprintfProgStr(const prog_char str[]); |
86 |
|
86 |
|
87 |
//! Using the function rprintfProgStrM(...) automatically causes |
87 |
//! Using the function rprintfProgStrM(...) automatically causes |
88 |
/// your string to be stored in ROM, thereby not wasting precious RAM. |
88 |
/// your string to be stored in ROM, thereby not wasting precious RAM. |
89 |
/// Example usage: |
89 |
/// Example usage: |
90 |
/// \code |
90 |
/// \code |
91 |
/// rprintfProgStrM("Hello, this string is stored in program rom"); |
91 |
/// rprintfProgStrM("Hello, this string is stored in program rom"); |
92 |
/// \endcode |
92 |
/// \endcode |
93 |
#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string))) |
93 |
#define rprintfProgStrM(string) (rprintfProgStr(PSTR(string))) |
94 |
|
94 |
|
95 |
//! Prints a carriage-return and line-feed. |
95 |
//! Prints a carriage-return and line-feed. |
96 |
/// Useful when printing to serial ports/terminals. |
96 |
/// Useful when printing to serial ports/terminals. |
97 |
void rprintfCRLF(void); |
97 |
void rprintfCRLF(void); |
98 |
|
98 |
|
99 |
// Prints the number contained in "data" in hex format |
99 |
// Prints the number contained in "data" in hex format |
100 |
// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively |
100 |
// u04,u08,u16,and u32 functions handle 4,8,16,or 32 bits respectively |
101 |
void rprintfu04(unsigned char data); ///< Print 4-bit hex number. Outputs a single hex character. |
101 |
void rprintfu04(unsigned char data); ///< Print 4-bit hex number. Outputs a single hex character. |
102 |
void rprintfu08(unsigned char data); ///< Print 8-bit hex number. Outputs two hex characters. |
102 |
void rprintfu08(unsigned char data); ///< Print 8-bit hex number. Outputs two hex characters. |
103 |
void rprintfu16(unsigned short data); ///< Print 16-bit hex number. Outputs four hex characters. |
103 |
void rprintfu16(unsigned short data); ///< Print 16-bit hex number. Outputs four hex characters. |
104 |
void rprintfu32(unsigned long data); ///< Print 32-bit hex number. Outputs eight hex characters. |
104 |
void rprintfu32(unsigned long data); ///< Print 32-bit hex number. Outputs eight hex characters. |
105 |
|
105 |
|
106 |
//! A flexible integer-number printing routine. |
106 |
//! A flexible integer-number printing routine. |
107 |
/// Print the number "n" in the given "base", using exactly "numDigits". |
107 |
/// Print the number "n" in the given "base", using exactly "numDigits". |
108 |
/// Print +/- if signed flag "isSigned" is TRUE. |
108 |
/// Print +/- if signed flag "isSigned" is TRUE. |
109 |
/// The character specified in "padchar" will be used to pad extra characters. |
109 |
/// The character specified in "padchar" will be used to pad extra characters. |
110 |
/// |
110 |
/// |
111 |
/// Examples: |
111 |
/// Examples: |
112 |
/// \code |
112 |
/// \code |
113 |
/// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234" |
113 |
/// uartPrintfNum(10, 6, TRUE, ' ', 1234); --> " +1234" |
114 |
/// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234" |
114 |
/// uartPrintfNum(10, 6, FALSE, '0', 1234); --> "001234" |
115 |
/// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5" |
115 |
/// uartPrintfNum(16, 6, FALSE, '.', 0x5AA5); --> "..5AA5" |
116 |
/// \endcode |
116 |
/// \endcode |
117 |
void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n); |
117 |
void rprintfNum(char base, char numDigits, char isSigned, char padchar, long n); |
118 |
|
118 |
|
119 |
#ifdef RPRINTF_FLOAT |
119 |
#ifdef RPRINTF_FLOAT |
120 |
//! floating-point print routine |
120 |
//! floating-point print routine |
121 |
void rprintfFloat(char numDigits, double x); |
121 |
void rprintfFloat(char numDigits, double x); |
122 |
#endif |
122 |
#endif |
123 |
|
123 |
|
124 |
// NOTE: Below you'll see the function prototypes of rprintf1RamRom and |
124 |
// NOTE: Below you'll see the function prototypes of rprintf1RamRom and |
125 |
// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions |
125 |
// rprintf2RamRom. rprintf1RamRom and rprintf2RamRom are both reduced versions |
126 |
// of the regular C printf() command. However, they are modified to be able |
126 |
// of the regular C printf() command. However, they are modified to be able |
127 |
// to read their text/format strings from RAM or ROM in the Atmel microprocessors. |
127 |
// to read their text/format strings from RAM or ROM in the Atmel microprocessors. |
128 |
// Unless you really intend to, do not use the "RamRom" versions of the functions |
128 |
// Unless you really intend to, do not use the "RamRom" versions of the functions |
129 |
// directly. Instead use the #defined function versions: |
129 |
// directly. Instead use the #defined function versions: |
130 |
// |
130 |
// |
131 |
// printfx("text/format",args) ...to keep your text/format string stored in RAM |
131 |
// printfx("text/format",args) ...to keep your text/format string stored in RAM |
132 |
// - or - |
132 |
// - or - |
133 |
// printfxROM("text/format",args) ...to keep your text/format string stored in ROM |
133 |
// printfxROM("text/format",args) ...to keep your text/format string stored in ROM |
134 |
// |
134 |
// |
135 |
// where x is either 1 or 2 for the simple or more powerful version of printf() |
135 |
// where x is either 1 or 2 for the simple or more powerful version of printf() |
136 |
// |
136 |
// |
137 |
// Since there is much more ROM than RAM available in the Atmel microprocessors, |
137 |
// Since there is much more ROM than RAM available in the Atmel microprocessors, |
138 |
// and nearly all text/format strings are constant (never change in the course |
138 |
// and nearly all text/format strings are constant (never change in the course |
139 |
// of the program), you should try to use the ROM printf version exclusively. |
139 |
// of the program), you should try to use the ROM printf version exclusively. |
140 |
// This will ensure you leave as much RAM as possible for program variables and |
140 |
// This will ensure you leave as much RAM as possible for program variables and |
141 |
// data. |
141 |
// data. |
142 |
|
142 |
|
143 |
//! \fn int rprintf(const char *format, ...); |
143 |
//! \fn int rprintf(const char *format, ...); |
144 |
/// A reduced substitute for the usual C printf() function. |
144 |
/// A reduced substitute for the usual C printf() function. |
145 |
/// This function actually points to either rprintf1RamRom or rprintf2RamRom |
145 |
/// This function actually points to either rprintf1RamRom or rprintf2RamRom |
146 |
/// depending on the user's selection. Rprintf1 is a simple small fast print |
146 |
/// depending on the user's selection. Rprintf1 is a simple small fast print |
147 |
/// routine while rprintf2 is larger and slower but more capable. To choose |
147 |
/// routine while rprintf2 is larger and slower but more capable. To choose |
148 |
/// the routine you would like to use, define either RPRINTF_SIMPLE or |
148 |
/// the routine you would like to use, define either RPRINTF_SIMPLE or |
149 |
/// RPRINTF_COMPLEX in global.h. |
149 |
/// RPRINTF_COMPLEX in global.h. |
150 |
|
150 |
|
151 |
#ifdef RPRINTF_SIMPLE |
151 |
#ifdef RPRINTF_SIMPLE |
152 |
//! A simple printf routine. |
152 |
//! A simple printf routine. |
153 |
/// Called by rprintf() - does a simple printf (supports %d, %x, %c). |
153 |
/// Called by rprintf() - does a simple printf (supports %d, %x, %c). |
154 |
/// Supports: |
154 |
/// Supports: |
155 |
/// - %d - decimal |
155 |
/// - %d - decimal |
156 |
/// - %x - hex |
156 |
/// - %x - hex |
157 |
/// - %c - character |
157 |
/// - %c - character |
158 |
int rprintf1RamRom(unsigned char stringInRom, const char *format, ...); |
158 |
int rprintf1RamRom(unsigned char stringInRom, const char *format, ...); |
159 |
// #defines for RAM or ROM operation |
159 |
// #defines for RAM or ROM operation |
160 |
#define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) |
160 |
#define rprintf1(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) |
161 |
#define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args) |
161 |
#define rprintf1RAM(format, args...) rprintf1RamRom(STRING_IN_RAM, format, ## args) |
162 |
|
162 |
|
163 |
// *** Default rprintf(...) *** |
163 |
// *** Default rprintf(...) *** |
164 |
// this next line determines what the the basic rprintf() defaults to: |
164 |
// this next line determines what the the basic rprintf() defaults to: |
165 |
#define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) |
165 |
#define rprintf(format, args...) rprintf1RamRom(STRING_IN_ROM, PSTR(format), ## args) |
166 |
#endif |
166 |
#endif |
167 |
|
167 |
|
168 |
#ifdef RPRINTF_COMPLEX |
168 |
#ifdef RPRINTF_COMPLEX |
169 |
//! A more powerful printf routine. |
169 |
//! A more powerful printf routine. |
170 |
/// Called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s). |
170 |
/// Called by rprintf() - does a more powerful printf (supports %d, %u, %o, %x, %c, %s). |
171 |
/// Supports: |
171 |
/// Supports: |
172 |
/// - %d - decimal |
172 |
/// - %d - decimal |
173 |
/// - %u - unsigned decimal |
173 |
/// - %u - unsigned decimal |
174 |
/// - %o - octal |
174 |
/// - %o - octal |
175 |
/// - %x - hex |
175 |
/// - %x - hex |
176 |
/// - %c - character |
176 |
/// - %c - character |
177 |
/// - %s - strings |
177 |
/// - %s - strings |
178 |
/// - and the width,precision,padding modifiers |
178 |
/// - and the width,precision,padding modifiers |
179 |
/// \note This printf does not support floating point numbers. |
179 |
/// \note This printf does not support floating point numbers. |
180 |
int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...); |
180 |
int rprintf2RamRom(unsigned char stringInRom, const char *sfmt, ...); |
181 |
// #defines for RAM or ROM operation |
181 |
// #defines for RAM or ROM operation |
182 |
#define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args) |
182 |
#define rprintf2(format, args...) rprintf2RamRom(STRING_IN_ROM, format, ## args) |
183 |
#define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args) |
183 |
#define rprintf2RAM(format, args...) rprintf2RamRom(STRING_IN_RAM, format, ## args) |
184 |
|
184 |
|
185 |
// *** Default rprintf(...) *** |
185 |
// *** Default rprintf(...) *** |
186 |
// this next line determines what the the basic rprintf() defaults to: |
186 |
// this next line determines what the the basic rprintf() defaults to: |
187 |
#define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args) |
187 |
#define rprintf(format, args...) rprintf2RamRom(STRING_IN_ROM, PSTR(format), ## args) |
188 |
#endif |
188 |
#endif |
189 |
|
189 |
|
190 |
#endif |
190 |
#endif |
191 |
//@} |
191 |
//@} |