Statistics
| Branch: | Tag: | Revision:

root / tidsense / debug.h @ 166:1a6a85e8d2e7

History | View | Annotate | Download (8.8 kB)

1
#ifndef __debug_h_
2
#define __debug_h_
3
4
#include <avr/pgmspace.h>
5
#include <stdio.h>
6
#include <stdlib.h>
7
8
#include <config.h>
9
10
#ifdef UART_BUFFERED_OUTPUT
11
#   include "uart_buffered_proto.h"
12
#else
13
#   include "uart.h"
14
#endif
15
16
#include "sensors.h"
17
18
#if(DEBUG)
19
    /**
20
     * printf-style macro for debugging.  Operates identically to printf.
21
     * The format string will be stored in program memory to minimize RAM
22
     * usage.
23
     */
24
#   define debugf(format, ...) { \
25
        debug_printf(PSTR(format), ## __VA_ARGS__); \
26
    }
27
28
/** Constant string "OK" that is used in various debug output */
29
extern const PROGMEM char debug_str_ok[];
30
31
/** Constant string "FAIL" that is used in various debug output */
32
extern const PROGMEM char debug_str_fail[];
33
34
/** Constant string "true" that is used in JSON output */
35
extern const PROGMEM char debug_str_true[];
36
37
/** Constant string "false" that is used in JSON output */
38
extern const PROGMEM char debug_str_false[];
39
40
/** Global state that keeps track of when to insert commas in the JSON output */
41
extern uint8_t debug_json_comma_status;
42
43
/**
44
 * Prints the status of something, intended to be used in sensor
45
 * initialization.  Success is assumed to be indicated by 0 and anything else
46
 * is considered an error.  The status code is also printed out.
47
 * @param name a string literal naming the sensor
48
 * @param status the status code to report
49
 */
50
#   define debug_sensor_status(name, status) \
51
        debugf("  % 10S:  %S (%d)\n", PSTR(name), (status) == 0 ? debug_str_ok : \
52
            debug_str_fail, status)
53
54
#   if(JSON_OUTPUT)
55
        /**
56
         * Inserts a comma into the JSON output if one is necessary.
57
         */
58
#       define debug_json_comma() { if(!debug_json_comma_status) { \
59
            debug_json_comma_status = 1; \
60
            } else { debugf(",\n") } }
61
62
        /**
63
         * Begins printing JSON output for senor data.
64
         */
65
#       define debug_json_start(name) { debug_json_comma_status = 0; \
66
            debugf("'%S': {\n", PSTR(name)) }
67
            
68
        /* json output for sensor values */
69
        /**
70
         * Outputs an integer sensor value as JSON.
71
         * @param name a string literal identifying the sensor.
72
         * @param value the value to print
73
         */
74
#       define debug_json_sensor_int(name, value) { debug_json_comma(); \
75
            debugf("    '%S': %d", PSTR(name), value) }
76
77
        /**
78
         * Outputs an integer sensor value as JSON.
79
         * @param name a string literal identifying the sensor.
80
         * @param value the value to print
81
         */
82
#       define debug_json_sensor_uint(name, value) { debug_json_comma(); \
83
            debugf("    '%S': %u", PSTR(name), value) }
84
85
#       define debug_json_sensor_dec(fmt, name, value, frac) { \
86
            debug_json_comma(); \
87
            ldiv_t res = ldiv(value, frac); \
88
            char neg = ' '; \
89
            if(value < 0) { \
90
                res.quot *= -1; \
91
                res.rem *= -1; \
92
                neg = '-'; \
93
            } \
94
            debugf(fmt, name, neg, res.quot, res.rem);\
95
        }
96
97
98
        /**
99
         * Outputs a fixed point decimal sensor value as JSON, with 1 digit 
100
         * following the decimal point.
101
         * @param name a string literal identifying the sensor.
102
         * @param value the value to print
103
         */
104
#       define debug_json_sensor_dec1(name, value) \
105
            debug_json_sensor_dec("    '%S': %c%ld.%01ld", PSTR(name), \
106
                value, 10L)
107
108
        /**
109
         * Outputs a fixed point decimal sensor value as JSON, with 2 digits
110
         * following the decimal point.
111
         * @param name a string literal identifying the sensor.
112
         * @param value the value to print
113
         */
114
#       define debug_json_sensor_dec2(name, value) \
115
            debug_json_sensor_dec("    '%S': %c%ld.%02ld", PSTR(name), \
116
                value, 100L)
117
118
        /**
119
         * Outputs a fixed point decimal sensor value as JSON, with 3 digits 
120
         * following the decimal point.
121
         * @param name a string literal identifying the sensor.
122
         * @param value the value to print
123
         */
124
#       define debug_json_sensor_dec3(name, value) \
125
            debug_json_sensor_dec("    '%S': %c%ld.%03ld", PSTR(name), \
126
                value, 1000L)
127
128
        /**
129
         * Outputs a fixed point decimal sensor value as JSON, with 4 digits 
130
         * following the decimal point.
131
         * @param name a string literal identifying the sensor.
132
         * @param value the value to print
133
         */
134
#       define debug_json_sensor_dec4(name, value) \
135
            debug_json_sensor_dec("    '%S': %c%ld.%04ld", PSTR(name), \
136
                value, 10000L)
137
138
        /**
139
         * Outputs a boolean sensor value as JSON.
140
         * @param name a string literal identifying the sensor.
141
         * @param value the value to print
142
         */
143
#       define debug_json_sensor_bool(name, value) { debug_json_comma(); \
144
            debugf("    '%S': %S", PSTR(name), value ? debug_str_true : \
145
            debug_str_false) }
146
147
#       define debug_json_sensor_pstr(name, value) { debug_json_comma(); \
148
            debugf("    '%S': %S", PSTR(name), value) }
149
150
        /**
151
         * Outputs an integer as a 16-bit hex value as JSON.
152
         * @param name a string literal identifying the number
153
         * @param value the value to print
154
         */
155
#       define debug_json_addr(name, value) { debug_json_comma(); \
156
            debugf("    '%S': \"0x%04X\"", PSTR(name), value) }
157
158
        /* variant where sensor name is not a string constant */
159
        /**
160
         * Outputs an integer sensor value as JSON.
161
         * @param name a pointer to a string in program memory identifying the
162
         * sensor.
163
         * @param value the value to print
164
         */
165
#       define debug_json_sensorn_int(name, value) { debug_json_comma(); \
166
            debugf("    '%S': %d", name, value) }
167
168
        /**
169
         * Outputs a fixed-point decimal sensor value as JSON, with 1 digit
170
         * following the decimal point.
171
         * @param name a pointer to a string in program memory identifying the
172
         * sensor.
173
         * @param value the value to print
174
         */
175
#       define debug_json_sensorn_uint(name, value) { debug_json_comma(); \
176
            debugf("    '%S': %u", name, value) }
177
178
        /**
179
         * Outputs a fixed-point decimal sensor value as JSON, with 1 digit
180
         * following the decimal point.
181
         * @param name a pointer to a string in program memory identifying the
182
         * sensor.
183
         * @param value the value to print
184
         */
185
#       define debug_json_sensorn_dec1(name, value) \
186
            debug_json_sensor_dec("    '%S': %c%ld.%01ld", name, \
187
                value, 10L)
188
189
        /**
190
         * Outputs a fixed-point decimal sensor value as JSON, with 2 digits
191
         * following the decimal point.
192
         * @param name a pointer to a string in program memory identifying the
193
         * sensor.
194
         * @param value the value to print
195
         */
196
#       define debug_json_sensorn_dec2(name, value) \
197
            debug_json_sensor_dec("    '%S': %c%ld.%02ld", name, \
198
                value, 100L)
199
200
        /**
201
         * Outputs a fixed-point decimal sensor value as JSON, with 3 digits
202
         * following the decimal point.
203
         * @param name a pointer to a string in program memory identifying the
204
         * sensor.
205
         * @param value the value to print
206
         */
207
#       define debug_json_sensorn_dec3(name, value) \
208
            debug_json_sensor_dec("    '%S': %c%ld.%03ld", name, \
209
                value, 1000L)
210
211
        /**
212
         * Outputs a fixed-point decimal sensor value as JSON, with 4 digits
213
         * following the decimal point.
214
         * @param name a pointer to a string in program memory identifying the
215
         * sensor.
216
         * @param value the value to print
217
         */
218
#       define debug_json_sensorn_dec4(name, value) \
219
            debug_json_sensor_dec("    '%S': %c%ld.%04ld", name, \
220
                value, 10000L)
221
222
        /**
223
         * Closes the JSON output of sensor data.
224
         */
225
#       define debug_json_end() debugf("\n}\n")
226
#   else
227
        #define debug_json_start()
228
        #define debug_json_sensor_int(name, value)
229
        #define debug_json_sensor_dec2(name, value, prec)
230
        #define debug_json_sensor_dec1(name, value, prec)
231
        #define debug_json_end()
232
#   endif
233
234
#else
235
#define debugf(format, ...)
236
#define debug(str)
237
#endif
238
239
/**
240
 * Internal function for sending debug output; this should not be called
241
 * directly (using the macros instead will omit the strings from the 
242
 * executable if debugging is turned off, while calling this directly
243
 * won't)
244
 */
245
void debug_printf(const char *fmt, ...);
246
247
/**
248
 * Initializes the debug system with the given serial port.
249
 * @param uart the UART to use for debugging output, if debugging is enabled.
250
 */
251
void debug_setup(uart_t *uart);
252
253
#endif // __debug_h_
254