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 |