1 /**
2  * \file
3  *
4  * \brief ADP service implementation
5  *
6  * Copyright (C) 2015 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 
47 #ifndef ADP_H_INCLUDED
48 #define ADP_H_INCLUDED
49 
50 #include <compiler.h>
51 
52 /** Version of ADP implemented here */
53 #define ADP_VERSION                 1
54 
55 /** Start token for ADP data */
56 #define ADP_TOKEN                   0xFF
57 
58 /** Maximum number of streams from PC to target */
59 #define ADP_MAX_INCOMMING_STREAMS   5
60 /** Maximum number of streams from target to PC */
61 #define ADP_MAX_OUTGOING_STREAMS    5
62 
63 /** Maximum number of bytes target can request from PC in one request */
64 #define ADP_MAX_BYTE_REQUEST        20
65 
66 /** Length of ADP packet header: Token, Message ID, Data Length */
67 #define ADP_LENGTH_PACKET_HEADER    4
68 
69 /** Maximum number of bytes in data part of ADP packet */
70 #define ADP_MAX_PACKET_DATA_SIZE    254
71 
72 /** Maximum number of all bytes in ADP packet */
73 #define  ADP_MAX_PACKET_LENGTH (ADP_LENGTH_PACKET_HEADER + ADP_MAX_PACKET_DATA_SIZE)
74 
75 /** Key used to identify proper handshake message */
76 #define ADP_HANDSHAKE_KEY {0x58, 0x99, 0xAB, 0xC9, 0x0F, 0xE2, 0xF7, 0xAA}
77 
78 /** ADP RGB color definitions. Other RGB values can be used as well */
79 #define ADP_COLOR_WHITE   0xFF, 0xFF, 0xFF
80 #define ADP_COLOR_BLACK   0x00, 0x00, 0x00
81 #define ADP_COLOR_SILVER  0xC0, 0xC0, 0xC0
82 #define ADP_COLOR_GRAY    0x80, 0x80, 0x80
83 #define ADP_COLOR_MAROON  0x80, 0x00, 0x00
84 #define ADP_COLOR_RED     0xFF, 0x00, 0x00
85 #define ADP_COLOR_PURPLE  0x80, 0x00, 0x80
86 #define ADP_COLOR_FUCHSIA 0xFF, 0x00, 0xFF
87 #define ADP_COLOR_GREEN   0x00, 0x80, 0x00
88 #define ADP_COLOR_LIME    0x00, 0xFF, 0x00
89 #define ADP_COLOR_OLIVE   0x80, 0x80, 0x00
90 #define ADP_COLOR_YELLOW  0xFF, 0xFF, 0x00
91 #define ADP_COLOR_NAVY    0x00, 0x00, 0x80
92 #define ADP_COLOR_BLUE    0x00, 0x00, 0xFF
93 #define ADP_COLOR_TEAL    0x00, 0x80, 0x80
94 #define ADP_COLOR_AQUA    0x00, 0xFF, 0xFF
95 #define ADP_COLOR_ORANGE  0xFF, 0xA5, 0x00
96 
97 /** States in receive state machine */
98 enum rx_state_e {
99 	/** We are idle, waiting for a new packet */
100 	RX_STATE_IDLE,
101 	/** Start symbol received, waiting for Message ID */
102 	RX_STATE_WAIT_MSG_ID,
103 	/** Message ID received, waiting for data length */
104 	RX_STATE_WAIT_LENGTH_LSB,
105 	/** Message ID received, waiting for data length */
106 	RX_STATE_WAIT_LENGTH_MSB,
107 	/** Length received; we are receiving packet data */
108 	RX_STATE_GET_DATA,
109 	/** Start symbol received */
110 	RX_STATE_GOT_SYMBOL,
111 };
112 
113 /** Max length of labels */
114  #define ADP_CONF_MAX_LABEL 20
115 
adp_set_color(uint8_t * struct_member,uint8_t c_red,uint8_t c_green,uint8_t c_blue)116 static inline void adp_set_color(uint8_t* struct_member, uint8_t c_red, uint8_t c_green, uint8_t c_blue)
117 {
118 	struct_member[0] = c_red;
119 	struct_member[1] = c_green;
120 	struct_member[2] = c_blue;
121 }
122 
123 
124 #define adp_set_string(struct_member, string)                  \
125 		Assert(sizeof(struct_member));                         \
126 		strncpy(struct_member, string, sizeof(struct_member)); \
127 		struct_member[sizeof(struct_member)-1] = '\0';
128 
129 /* MESSAGE FORMAT */
130 SHORTENUM struct adp_msg_format {
131 	/* Start token for ADP data */
132 	uint8_t protocol_token;
133 	/* Describes what data is sent */
134 	uint8_t protocol_msg_id;
135 	/* Length of data packet */
136 	uint16_t data_length;
137 	/* Data packet for the message */
138 	uint8_t data[ADP_MAX_PACKET_DATA_SIZE];
139 };
140 
141 
142 /* MSG_REQ_HANDSHAKE */
143 #define MSG_REQ_HANDSHAKE 0x00
144 #define MSQ_REQ_HANDSHAKE_LEN 10
145 enum adp_handshake_options {
146 	/* Use GPIO */
147 	ADP_HANDSHAKE_OPTIONS_GPIO,
148 	/* Lock configuration */
149 	ADP_HANDSHAKE_OPTIONS_LOCK,
150 };
151 SHORTENUM struct adp_msg_request_handshake {
152 	/* Version of protocol on target */
153 	uint8_t protocol_version;
154 	/* Is GPIO in use in this app?
155 	 * Can user change configuration on PC side?
156 	 */
157 	uint8_t options;
158 	/* Token used to verify ADP protocol */
159 	uint8_t key[8];
160 };
161 
162 /* MSG_RES_HANDSHAKE */
163 #define MSG_RES_HANDSHAKE 0x10
164 enum adp_handshake_status {
165 	/* Handshake accepted */
166 	ADP_HANDSHAKE_ACCEPTED,
167 	/* Handshake rejected. Invalid protocol version */
168 	ADP_HANDSHAKE_REJECTED_PROTOCOL,
169 	/* Handshake rejected. Other reason */
170 	ADP_HANDSHAKE_REJECTED_OTHER,
171 };
172 SHORTENUM struct adp_msg_response_handshake {
173 	enum adp_handshake_status status;
174 };
175 
176 enum adp_handshake_status adp_wait_for_handshake(void);
177 
178 /* MSG_REQ_STATUS */
179 #define MSG_REQ_STATUS 0x02
180 #define MSG_REQ_STATUS_LEN 0
181 /* This message has no data */
182 
183 /* MSG_RES_STATUS */
184 #define MSG_RES_STATUS 0x12
185 enum adp_status_code {
186 	/* Invalid packet received */
187 	ADP_STATUS_INVALID_PACKET,
188 	/* Invalid configuration data received */
189 	ADP_STATUS_INVALID_CONFIGURATION,
190 	/* Data ready to be transmitted to target */
191 	ADP_STATUS_DATA_READY,
192 	/* Invalid stream request (req_data) */
193 	ADP_STATUS_INVALID_REQUEST,
194 	/* No data available on stream (req_data) */
195 	ADP_STATUS_NO_DATA,
196 	/* Request target software reset */
197 	ADP_STATUS_RESET,
198 };
199 SHORTENUM struct adp_msg_response_status {
200 	enum adp_status_code status;
201 };
202 
203 enum adp_status_code adp_request_status(void);
204 
205 /* MSG_RES_DATA */
206 #define MSG_RES_DATA 0x14
207 #define MSG_RES_DATA_MAX_LEN (ADP_MAX_BYTE_REQUEST + 4)
208 SHORTENUM struct adp_msg_response_data {
209 	/* ID of stream */
210 	uint8_t stream_id;
211 	/* Number of bytes in packet.
212 	 * If the target has requested data from an unknown stream, or if stream
213 	 * has no data to send, this field should be set to 0 and the appropriate
214 	 * status flag should be set.
215 	 */
216 	uint8_t bytes_sent;
217 	/* The data */
218 	uint8_t data[ADP_MAX_BYTE_REQUEST];
219 };
220 
221 void adp_request_data(uint8_t stream_id, uint8_t bytes_to_send, struct adp_msg_response_data *response);
222 
223 #define MSG_RES_PACKET_DATA_MAX_LEN (ADP_MAX_BYTE_REQUEST + 2)
224 SHORTENUM struct adp_msg_packet_data {
225 	uint16_t stream_id;
226 	uint8_t bytes_sent;
227 	uint8_t data[ADP_MAX_BYTE_REQUEST];
228 };
229 bool adp_receive_packet_data(uint8_t *receive_buf);
230 
231 /* MSG_CONF_STREAM */
232 enum adp_stream_type {
233 	ADP_STREAM_EVENT,
234 	ADP_STREAM_STRING,
235 	ADP_STREAM_UINT_8,
236 	ADP_STREAM_INT_8,
237 	ADP_STREAM_UINT_16,
238 	ADP_STREAM_INT_16,
239 	ADP_STREAM_UINT_32,
240 	ADP_STREAM_INT_32,
241 	ADP_STREAM_XY_8,
242 	ADP_STREAM_XY_16,
243 	ADP_STREAM_XY_32,
244 	ADP_STREAM_BOOL,
245 	ADP_STREAM_FLOAT,
246 };
247 
248 enum adp_stream_state {
249 	ADP_STREAM_OFF,
250 	ADP_STREAM_ON,
251 };
252 
253 enum adp_stream_mode {
254 	/* Incoming (normal) */
255 	ADP_STREAM_IN,
256 	/* Incoming (single value) */
257 	ADP_STREAM_IN_SINGLE,
258 	/* Outgoing */
259 	ADP_STREAM_OUT,
260 };
261 
262 #define MSG_CONF_ACK       0x30
263 #define ADP_ACK_NOT_OK     0
264 #define ADP_ACK_OK         1
265 
266 #define MSG_CONF_INFO      0x28
267 #define MSG_CONF_INFO_LEN
268 bool adp_configure_info(const char* title, const char* description);
269 
270 #define MSG_CONF_STREAM     0x20
271 #define MSG_CONF_STREAM_LEN 5
272 SHORTENUM struct adp_msg_configure_stream {
273 	/* ID of stream */
274 	uint16_t stream_id;
275 	/* Stream type */
276 	enum adp_stream_type type;
277 	/* Stream mode/direction */
278 	enum adp_stream_mode mode;
279 	/* Stream state */
280 	enum adp_stream_state state;
281 };
282 
adp_configure_stream_get_defaults(struct adp_msg_configure_stream * const config)283 static inline void adp_configure_stream_get_defaults(struct adp_msg_configure_stream *const config)
284 {
285 	Assert(config);
286 	config->stream_id = 0;
287 	config->type = ADP_STREAM_UINT_8;
288 	config->mode = ADP_STREAM_OUT;
289 	config->state = ADP_STREAM_ON;
290 }
291 
292 bool adp_configure_stream(struct adp_msg_configure_stream *const config, const char* label);
293 
294 /* MSG_CONF_TOGGLE_STREAM */
295 #define MSG_CONF_TOGGLE_STREAM   0x21
296 #define MSG_CONF_TOGGLE_STREAM_LEN 3
297 SHORTENUM struct adp_msg_toggle_stream {
298 	uint16_t               stream_id;
299 	enum adp_stream_state  state;
300 };
301 bool adp_toggle_stream(struct adp_msg_toggle_stream *const config);
302 
303 /* MSG_CONF_GRAPH */
304 #define MSG_CONF_GRAPH           0x22
305 #define MSG_CONF_GRAPH_LEN       23
306 
307 enum adp_graph_scale_mode {
308 	ADP_GRAPH_SCALE_OFF,
309 	ADP_GRAPH_SCALE_AUTO
310 };
311 
312 enum adp_graph_scroll_mode {
313 	/* No scrolling */
314 	ADP_GRAPH_SCROLL_OFF,
315 	/* Stepping */
316 	ADP_GRAPH_SCROLL_STEP,
317 	/* Scroll */
318 	ADP_GRAPH_SCROLL_SCROLL,
319 	/* Circular/sweep */
320 	ADP_GRAPH_SCROLL_CIRCULAR
321 };
322 
323 SHORTENUM struct adp_msg_configure_graph {
324 	/* ID of new graph */
325 	uint8_t graph_id;
326 	/* Range Xmin value */
327 	uint32_t x_min;
328 	/* Range Xmax value */
329 	uint32_t x_max;
330 	/* Xscale numerator */
331 	uint32_t x_scale_numerator;
332 	/* X range scale value. Set to 0 to enable auto range */
333 	uint32_t x_scale_denominator;
334 	/* Vertical scaling */
335 	enum adp_graph_scale_mode scale_mode;
336 	/* RGB background color */
337 	uint8_t background_color[3];
338 	/* Horizontal scrolling */
339 	enum adp_graph_scroll_mode scroll_mode;
340 };
341 
adp_configure_graph_get_defaults(struct adp_msg_configure_graph * const config)342 static inline void adp_configure_graph_get_defaults(struct adp_msg_configure_graph *const config)
343 {
344 	Assert(config);
345 	config->graph_id = 0;
346 	config->x_min = 0;
347 	config->x_max = 0;
348 	config->x_scale_numerator = 0;
349 	config->x_scale_denominator = 0;
350 	config->scale_mode = ADP_GRAPH_SCALE_OFF;
351 	adp_set_color(config->background_color, ADP_COLOR_WHITE);
352 	config->scroll_mode = ADP_GRAPH_SCROLL_SCROLL;
353 }
354 
355 bool adp_configure_graph(struct adp_msg_configure_graph *const config, \
356 						const char* graph_label, const char* x_label);
357 
358 /* MSG_CONF_AXIS */
359 #define MSG_CONF_AXIS       0x29
360 #define MSG_CONF_AXIS_LEN   24
361 SHORTENUM struct adp_msg_conf_axis {
362 	/* ID of new axis */
363 	uint16_t axis_id;
364 	/* ID of graph */
365 	uint16_t graph_id;
366 	/* Range Ymin value */
367 	int32_t y_min;
368 	/* Range Ymax value */
369 	int32_t y_max;
370 	/* X range scale value.	Set to 0 to enable auto range */
371 	uint32_t x_scale_numerator;
372 	/* X range scale value.	Set to 0 to enable auto range */
373 	uint32_t x_scale_denominator;
374 	/* Mode */
375 	uint8_t mode;                                         // TODO
376 	/* RGB color */
377 	uint8_t color[3];
378 };
379 
adp_add_axis_to_graph_get_defaults(struct adp_msg_conf_axis * const config)380 static inline void adp_add_axis_to_graph_get_defaults(struct adp_msg_conf_axis *const config)
381 {
382 	Assert(config);
383 	config->axis_id = 0;
384 	config->graph_id = 0;
385 	config->y_min = 0;
386 	config->y_max = 0;
387 	config->x_scale_numerator = 0;
388 	config->x_scale_denominator = 0;
389 	config->mode = 0;
390 	adp_set_color(config->color, ADP_COLOR_BLACK);
391 }
392 
393 bool adp_add_axis_to_graph(struct adp_msg_conf_axis *const config, const char* label);
394 
395 /* MSG_CONF_ADD_STREAM_TO_GRAPH */
396 #define MSG_CONF_ADD_STREAM_TO_AXIS       0x23
397 #define MSG_CONF_ADD_STREAM_TO_AXIS_LEN   32
398 
399 #define ADP_AXIS_LINE_bm    0x01
400 #define ADP_AXIS_POINTS_bm  0x02
401 
402 SHORTENUM struct adp_msg_add_stream_to_axis {
403 	/* ID of graph */
404 	uint16_t graph_id;
405 	/* ID of new axis */
406 	uint16_t axis_id;
407 	/* ID of stream */
408 	uint16_t stream_id;
409 	/* Sample rate of stream, set to 0 if NA */
410 	uint32_t sample_rate_numerator;
411 	/* Sample rate of stream, set to 0 if NA */
412 	uint32_t sample_rate_denominator;
413 	/* Range Ymin value */
414 	uint32_t y_scale_numerator;
415 	/* Range Ymax value */
416 	uint32_t y_scale_denominator;
417 	/* Offset of values */
418 	uint32_t y_offset;
419 	/* Adjust the transparency */
420 	uint8_t transparency;
421 	/* For graphs:  bit 0 = line on/off
422 	 *              bit 1 = points on/off
423 	 * For text:    bit 0 = flag
424 	 *              bit 1 = text
425 	 */
426 	uint8_t mode;                           // TODO
427 	/* Thickness of line */
428 	uint8_t line_thickness;
429 	/* RGB color of line */
430 	uint8_t line_color[3];
431 };
432 
adp_add_stream_to_axis_get_defaults(struct adp_msg_add_stream_to_axis * const config)433 static inline void adp_add_stream_to_axis_get_defaults(struct adp_msg_add_stream_to_axis *const config)
434 {
435 	Assert(config);
436 	config->graph_id = 0;
437 	config->axis_id = 0;
438 	config->stream_id = 0;
439 	config->sample_rate_numerator = 0;
440 	config->sample_rate_denominator = 0;
441 	config->y_scale_numerator = 0;
442 	config->y_scale_denominator = 0;
443 	config->y_offset = 0;
444 	config->transparency = 0;
445 	config->mode = ADP_AXIS_LINE_bm;
446 	config->line_thickness = 1;
447 	adp_set_color(config->line_color, ADP_COLOR_BLACK);
448 }
449 
450 bool adp_add_stream_to_axis(struct adp_msg_add_stream_to_axis *const config);
451 
452 /* MSG_CONF_CURSOR_TO_GRAPH */
453 #define MSG_CONF_CURSOR_TO_GRAPH     0x24
454 #define MSG_CONF_CURSOR_TO_GRAPH_LEN 35
455 SHORTENUM struct adp_msg_add_cursor_to_graph {
456 	/* ID of streama */
457 	uint16_t stream_id;
458 	/* ID of graph */
459 	uint16_t graph_id;
460 	/* ID of axis */
461 	uint16_t axis_id;
462 	/* Thickness of line */
463 	uint8_t thickness;
464 	/* RGB color of cursor */
465 	uint8_t color[3];
466 	/* Starting point of cursor */
467 	uint32_t initial_value;
468 	/* Minimum allowed value */
469 	uint32_t minimum_value;
470 	/* Maximum */
471 	uint32_t maximum_value;
472 	/* Numerator of scaling value */
473 	uint32_t scale_numerator;
474 	/* Denominator of scaling value */
475 	uint32_t scale_denominator;
476 	/* Offset of value */
477 	uint32_t scale_offset;
478 	/* The style of line: Solid, dashed, dotted.. */
479 	uint8_t line_style;          // TODO
480 };
481 
adp_add_cursor_to_graph_get_defaults(struct adp_msg_add_cursor_to_graph * const config)482 static inline void adp_add_cursor_to_graph_get_defaults(struct adp_msg_add_cursor_to_graph *const config)
483 {
484 	Assert(config);
485 	config->stream_id = 0;
486 	config->graph_id = 0;
487 	config->axis_id = 0;
488 	config->thickness = 1;
489 	adp_set_color(config->color, ADP_COLOR_WHITE);
490 	config->initial_value = 0;
491 	config->minimum_value = 0;
492 	config->maximum_value = 0;
493 	config->scale_numerator = 0;
494 	config->scale_denominator = 0;
495 	config->scale_offset = 0;
496 	config->line_style = 0;
497 }
498 
499 bool adp_add_cursor_to_graph(struct adp_msg_add_cursor_to_graph *const config, const char* label);
500 
501 /* MSG_CONF_GPIO_TO_GRAPH */
502 #define MSG_CONF_GPIO_TO_GRAPH       0x25
503 #define MSG_CONF_GPIO_TO_GRAPH_LEN   15
504 SHORTENUM struct adp_msg_conf_gpio_to_graph {
505 	/* ID of graph */
506 	uint16_t graph_id;
507 	/* GPIO number to add to graph. Bit 0: GPIO0. bit 1: GPIO1 etc. */
508 	uint8_t gpio_number;
509 	/* Used to group graphs and cursors to the same scale */
510 	uint8_t group_id;
511 	/* Adjust the transparency */
512 	uint8_t transparency;
513 	/* Mode */
514 	uint16_t mode;                                    // TODO
515 	/* Thickness of line */
516 	uint8_t line_thickness;
517 	/* RGB color of line when GPIO pin is high */
518 	uint8_t line_color_high_state[3];
519 	/* RGB color of line when GPIO pin is low */
520 	uint8_t line_color_low_state[3];
521 	/* The style of line */
522 	uint8_t line_style;
523 };
524 
adp_gpio_to_graph_get_defaults(struct adp_msg_conf_gpio_to_graph * const config)525 static inline void adp_gpio_to_graph_get_defaults(struct adp_msg_conf_gpio_to_graph *const config)
526 {
527 	Assert(config);
528 	config->graph_id = 0;
529 	config->gpio_number = 0;
530 	config->group_id = 0;
531 	config->transparency = 0;
532 	config->mode = 0;
533 	config->line_thickness = 1;
534 	adp_set_color(config->line_color_high_state, ADP_COLOR_WHITE);
535 	adp_set_color(config->line_color_low_state, ADP_COLOR_WHITE);
536 	config->line_style = 0;
537 }
538 
539 bool adp_add_gpio_to_graph(struct adp_msg_conf_gpio_to_graph *const config, \
540 						const char* tag_high_state, const char* tag_low_state);
541 
542 /* MSG_CONF_TERMINAL */
543 #define MSG_CONF_TERMINAL        0x26
544 #define MSG_CONF_TERMINAL_LEN    10
545 SHORTENUM struct adp_msg_conf_terminal {
546 	/* ID of terminal */
547 	uint16_t terminal_id;
548 	/* Number of characters wide */
549 	uint8_t width;
550 	/* Number of characters high */
551 	uint8_t height;
552 	/* RGB background color */
553 	uint8_t background_color[3];
554 	/* RGB background color */
555 	uint8_t foreground_color[3];
556 };
557 
adp_configure_terminal_get_defaults(struct adp_msg_conf_terminal * const config)558 static inline void adp_configure_terminal_get_defaults(struct adp_msg_conf_terminal *const config)
559 {
560 	Assert(config);
561 	config->terminal_id = 0;
562 	config->width = 80;
563 	config->height = 25;
564 	adp_set_color(config->background_color, ADP_COLOR_WHITE);
565 	adp_set_color(config->foreground_color, ADP_COLOR_BLACK);
566 }
567 
568 bool adp_configure_terminal(struct adp_msg_conf_terminal *const config, const char* label);
569 
570 /* MSG_CONF_ADD_TO_TERMINAL */
571 #define MSG_CONF_ADD_TO_TERMINAL       0x27
572 #define MSG_CONF_ADD_TO_TERMINAL_LEN   11
573 SHORTENUM struct adp_msg_add_stream_to_terminal {
574 	/* ID of Terminal */
575 	uint16_t terminal_id;
576 	/* ID of stream */
577 	uint16_t stream_id;
578 	/* 0bx x x N T S F F
579 	 * N = implicit newline in incoming text
580 	 * T = enable tag
581 	 * S = timestamped
582 	 * F = format (Hex, decimal, binary, ascii)
583 	 */
584 	uint8_t mode;                                    // TODO
585 	/* RGB color of the text stream received */
586 	uint8_t text_color[3];
587 	/* RGB color of the tag text */
588 	uint8_t tag_text_color[3];
589 };
590 
adp_add_stream_to_terminal_get_defaults(struct adp_msg_add_stream_to_terminal * const config)591 static inline void adp_add_stream_to_terminal_get_defaults(struct adp_msg_add_stream_to_terminal *const config)
592 {
593 	Assert(config);
594 	config->terminal_id = 0;
595 	config->stream_id = 0;
596 	config->mode = 0;
597 	adp_set_color(config->text_color, ADP_COLOR_BLACK);
598 	adp_set_color(config->tag_text_color, ADP_COLOR_BLACK);
599 }
600 
601 bool adp_add_stream_to_terminal(struct adp_msg_add_stream_to_terminal *const config, const char* tag_text);
602 
603 /* MSG_CONF_DASHBOARD */
604 #define MSG_CONF_DASHBOARD       0x2A
605 #define MSG_CONF_DASHBOARD_LEN   7
606 SHORTENUM struct adp_msg_conf_dashboard {
607 	uint16_t dashboard_id;
608 	uint8_t color[3];
609 	uint16_t height;
610 };
611 
adp_conf_dashboard_get_defaults(struct adp_msg_conf_dashboard * const config)612 static inline void adp_conf_dashboard_get_defaults(struct adp_msg_conf_dashboard *const config)
613 {
614 	Assert(config);
615 	config->dashboard_id = 0;
616 	adp_set_color(config->color, ADP_COLOR_BLACK);
617 	config->height = 100;
618 }
619 
620 bool adp_add_dashboard(struct adp_msg_conf_dashboard *const config, const char* label);
621 
622 /* MSG_CONF_DASHBOARD_ELEMENT */
623 #define MSG_CONF_DASHBOARD_ELEMENT 0x2B
624 
625 enum adp_dashboard_element_type {
626 	ADP_ELEMENT_TYPE_LABEL,
627 	ADP_ELEMENT_TYPE_BUTTON,
628 	ADP_ELEMENT_TYPE_SLIDER,
629 	ADP_ELEMENT_TYPE_PROGRESS,
630 	ADP_ELEMENT_TYPE_SIGNAL,
631 	ADP_ELEMENT_TYPE_SEGMENT,
632 	ADP_ELEMENT_TYPE_GRAPH,
633 	ADP_ELEMENT_TYPE_TEXT,
634 	ADP_ELEMENT_TYPE_RADIO,
635 	ADP_ELEMENT_TYPE_PIE,
636 };
637 
638 #define MSG_CONF_DASHBOARD_COMMON_LEN    14
639 #define ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS \
640 	uint16_t  dashboard_id; \
641 	uint16_t  element_id;   \
642 	uint8_t   z_index;      \
643 	uint16_t  x;            \
644 	uint16_t  y;            \
645 	uint16_t  width;        \
646 	uint16_t  height;       \
647 	enum adp_dashboard_element_type element_type
648 
649 SHORTENUM struct adp_msg_conf_dashboard_element_common {
650 	/* Dashboard ID */
651 	uint16_t  dashboard_id;
652 	/* Unique ID of element */
653 	uint16_t  element_id;
654 	/* Order index */
655 	uint8_t   z_index;
656 	/* X-coordinate of element location. 0 is leftmost position on dashboard */
657 	uint16_t  x;
658 	/* Y-coordinate of element location. 0 is topmost position on dashboard */
659 	uint16_t  y;
660 	/* Width of element */
661 	uint16_t  width;
662 	/* Height of element */
663 	uint16_t  height;
664 	/* See each element type below */
665 	enum adp_dashboard_element_type element_type;
666 };
667 
adp_conf_dashboard_element_get_defaults(struct adp_msg_conf_dashboard_element_common * const config)668 static inline void adp_conf_dashboard_element_get_defaults(struct adp_msg_conf_dashboard_element_common *const config)
669 {
670 	Assert(config);
671 	config->dashboard_id = 0;
672 	config->element_id = 0;
673 	config->z_index = 0;
674 	config->x = 0;
675 	config->y = 0;
676 	config->width = 0;
677 	config->height = 0;
678 }
679 
680 enum adp_label_attribute_alignment {
681 	BOLD_OFF_ITALIC_OFF,
682 	BOLD_ON_ITALIC_OFF,
683 	BOLD_OFF_ITALIC_ON,
684 	BOLD_ON_ITALIC_ON,
685 };
686 
687 enum adp_label_horisontal_alignment {
688 	HORISONTAL_ALIGNMENT_LEFT,
689 	HORISONTAL_ALIGNMENT_CENTER,
690 	HORISONTAL_ALIGNMENT_RIGHT,
691 };
692 
693 enum adp_label_vertical_alignment {
694 	VERTICAL_ALIGNMENT_TOP,
695 	VERTICAL_ALIGNMENT_CENTER,
696 	VERTICAL_ALIGNMENT_BOTTOM,
697 };
698 
699 #define ADP_ELEMENT_TYPE_LABEL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
700 SHORTENUM struct adp_msg_conf_dashboard_element_label {
701 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
702 	uint8_t                             font_size;
703 	uint8_t                             attribute;                               // TODO
704 	enum adp_label_horisontal_alignment horisontal_alignment;
705 	enum adp_label_vertical_alignment   vertical_alignment;
706 	uint8_t                             background_transparency;
707 	uint8_t                             background_color[3];
708 	uint8_t                             foreground_transparency;
709 	uint8_t                             foreground_color[3];
710 };
711 
adp_conf_dashboard_label_get_defaults(struct adp_msg_conf_dashboard_element_label * const config)712 static inline void adp_conf_dashboard_label_get_defaults(struct adp_msg_conf_dashboard_element_label *const config)
713 {
714 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
715 	config->element_type = ADP_ELEMENT_TYPE_LABEL;
716 	config->font_size = 10;
717 	config->attribute = 0;
718 	config->horisontal_alignment = HORISONTAL_ALIGNMENT_LEFT;
719 	config->vertical_alignment = VERTICAL_ALIGNMENT_CENTER;
720 	config->background_transparency = 0;
721 	adp_set_color(config->background_color, ADP_COLOR_BLACK);
722 	config->foreground_transparency = 0;
723 	adp_set_color(config->foreground_color, ADP_COLOR_BLACK);
724 }
725 
726 bool adp_add_label_to_dashboard(struct adp_msg_conf_dashboard_element_label *const config, const char* label);
727 
728 #define ADP_ELEMENT_TYPE_BUTTON_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 1)
729 
730 SHORTENUM struct adp_msg_conf_dashboard_element_button {
731 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
732 	uint8_t font_size;
733 };
734 
adp_conf_dashboard_button_get_defaults(struct adp_msg_conf_dashboard_element_button * const config)735 static inline void adp_conf_dashboard_button_get_defaults(struct adp_msg_conf_dashboard_element_button *const config)
736 {
737 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
738 	config->element_type = ADP_ELEMENT_TYPE_BUTTON;
739 	config->font_size = 10;
740 }
741 
742 bool adp_add_button_to_dashboard(struct adp_msg_conf_dashboard_element_button *const config, const char* label);
743 
744 #define ADP_ELEMENT_TYPE_SLIDER_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
745 SHORTENUM struct adp_msg_conf_dashboard_element_slider {
746 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
747 	uint32_t minimum_value;
748 	uint32_t maximum_value;
749 	uint32_t initial_value;
750 };
751 
adp_conf_dashboard_slider_get_defaults(struct adp_msg_conf_dashboard_element_slider * const config)752 static inline void adp_conf_dashboard_slider_get_defaults(struct adp_msg_conf_dashboard_element_slider *const config)
753 {
754 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
755 	config->element_type = ADP_ELEMENT_TYPE_SLIDER;
756 	config->minimum_value = 0;
757 	config->maximum_value = 100;
758 	config->initial_value = 0;
759 }
760 
761 bool adp_add_slider_to_dashboard(struct adp_msg_conf_dashboard_element_slider *const config);
762 
763 #define ADP_ELEMENT_TYPE_SIGNAL_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 8)
764 SHORTENUM struct adp_msg_conf_dashboard_element_signal {
765 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
766 	uint8_t on_transparency;
767 	uint8_t on_color[3];
768 	uint8_t off_transparency;
769 	uint8_t off_color[3];
770 };
771 
adp_conf_dashboard_signal_get_defaults(struct adp_msg_conf_dashboard_element_signal * const config)772 static inline void adp_conf_dashboard_signal_get_defaults(struct adp_msg_conf_dashboard_element_signal *const config)
773 {
774 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
775 	config->element_type = ADP_ELEMENT_TYPE_SIGNAL;
776 	config->on_transparency = 0;
777 	adp_set_color(config->on_color, ADP_COLOR_WHITE);
778 	config->off_transparency = 0;
779 	adp_set_color(config->off_color, ADP_COLOR_BLACK);
780 }
781 
782 bool adp_add_signal_to_dashboard(struct adp_msg_conf_dashboard_element_signal *const config);
783 
784 #define ADP_ELEMENT_TYPE_PROGRESS_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 15)
785 SHORTENUM struct adp_msg_conf_dashboard_element_progress {
786 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
787 	uint32_t minimum_value;
788 	uint32_t maximum_value;
789 	uint32_t initial_value;
790 	uint8_t color[3];
791 };
792 
adp_conf_dashboard_progress_get_defaults(struct adp_msg_conf_dashboard_element_progress * const config)793 static inline void adp_conf_dashboard_progress_get_defaults(struct adp_msg_conf_dashboard_element_progress *const config)
794 {
795 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
796 	config->element_type = ADP_ELEMENT_TYPE_PROGRESS;
797 	config->minimum_value = 0;
798 	config->maximum_value = 100;
799 	config->initial_value = 0;
800 	adp_set_color(config->color, ADP_COLOR_BLACK);
801 }
802 
803 bool adp_add_progress_to_dashboard(struct adp_msg_conf_dashboard_element_progress *const config);
804 
805 #define ADP_ELEMENT_TYPE_SEGMENT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 6)
806 SHORTENUM struct adp_msg_conf_dashboard_element_segment {
807 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
808 	/* Values: 1 ~ 20 */
809 	uint8_t segment_count;
810 	/* Values: 2 ~ 16*/
811 	uint8_t base;
812 	uint8_t transparency;
813 	uint8_t color[3];
814 };
815 
adp_conf_dashboard_segment_get_defaults(struct adp_msg_conf_dashboard_element_segment * const config)816 static inline void adp_conf_dashboard_segment_get_defaults(struct adp_msg_conf_dashboard_element_segment *const config)
817 {
818 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
819 	config->element_type = ADP_ELEMENT_TYPE_SEGMENT;
820 	config->segment_count = 1;
821 	config->base = 10;
822 	config->transparency = 0;
823 	adp_set_color(config->color, ADP_COLOR_BLACK);
824 }
825 
826 bool adp_add_segment_to_dashboard(struct adp_msg_conf_dashboard_element_segment *const config);
827 
828 /* MSG_CONF_ADD_GRAPH_TO_ELEMENT */
829 #define  ADP_ELEMENT_TYPE_GRAPH_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 27)
830 typedef union {
831 	struct {
832 		uint8_t mouse:1;
833 		uint8_t fit_graph:1;
834 		uint8_t :6;
835 	} bit;
836 	uint8_t reg;
837 } mode_type;
838 
839 SHORTENUM struct adp_msg_conf_dashboard_element_graph {
840 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
841 	uint8_t title_color[3];
842 	uint8_t background_color[3];
843 	uint8_t graph_background_color[3];
844 	uint8_t plot_count;
845 	float x_min;
846 	float x_max;
847 	float y_min;
848 	float y_max;
849 	mode_type mode;
850 };
851 
adp_conf_dashboard_graph_get_defaults(struct adp_msg_conf_dashboard_element_graph * const config)852 static inline void adp_conf_dashboard_graph_get_defaults(struct adp_msg_conf_dashboard_element_graph *const config)
853 {
854 	adp_conf_dashboard_element_get_defaults((struct adp_msg_conf_dashboard_element_common*)config);
855 	config->element_type = ADP_ELEMENT_TYPE_GRAPH;
856 	adp_set_color(config->title_color, ADP_COLOR_WHITE);
857 	adp_set_color(config->background_color, ADP_COLOR_BLACK);
858 	adp_set_color(config->graph_background_color, ADP_COLOR_BLACK);
859 	config->plot_count = 1;
860 	config->x_min = 0;
861 	config->x_max = 10;
862 	config->y_min = 0;
863 	config->y_max = 5;
864 	config->mode.bit.fit_graph = 1;
865 	config->mode.bit.mouse = 0;
866 }
867 
868 bool adp_add_graph_to_dashboard(struct adp_msg_conf_dashboard_element_graph *const config, const char* title);
869 
870 
871 /* MSG_CONF_ADD_TEXT_TO_ELEMENT */
872 #define  ADP_ELEMENT_TYPE_TEXT_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 12)
873 SHORTENUM struct adp_msg_conf_dashboard_element_text {
874 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
875 	uint8_t minimum[4];
876 	uint8_t maximum[4];
877 	uint8_t value[4];
878 };
879 
880 bool adp_add_text_to_dashboard(struct adp_msg_conf_dashboard_element_text *const config);
881 
882 /* MSG_CONF_ADD_RADIO_TO_ELEMENT */
883 #define  ADP_ELEMENT_TYPE_RADIO_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 3)
884 
885 enum adp_radio_orientation {
886 	HORIZONTAL,
887 	VERTICAL,
888 };
889 
890 SHORTENUM struct adp_msg_conf_dashboard_element_radio {
891 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
892 	uint8_t font_size;
893 	uint8_t number_items;
894 	enum adp_radio_orientation orientation;
895 };
896 bool adp_add_radio_to_dashboard(struct adp_msg_conf_dashboard_element_radio *const config, const char* text);
897 
898 /* MSG_CONF_ADD_PIE_TO_ELEMENT */
899 #define  ADP_ELEMENT_TYPE_PIE_LEN (MSG_CONF_DASHBOARD_COMMON_LEN + 7)
900 
901 SHORTENUM struct adp_msg_conf_dashboard_element_pie {
902 	ADP_DASHBOARD_ELEMENT_COMMON_MEMBERS;
903 	uint8_t background_color[3];
904 	uint8_t title_color[3];
905 	uint8_t number_slices;
906 };
907 bool adp_add_pie_to_dashboard(struct adp_msg_conf_dashboard_element_pie *const config, const char* title);
908 
909 /* MSG_CONF_ADD_STREAM_TO_ELEMENT */
910 #define MSG_CONF_ADD_STREAM_TO_ELEMENT       0x2C
911 #define MSG_CONF_ADD_STREAM_TO_ELEMENT_LEN   6
912 
913 SHORTENUM struct adp_conf_add_stream_to_element {
914 	uint16_t dashboard_id;
915 	uint16_t element_id;
916 	uint16_t stream_id;
917 };
918 
919 bool adp_add_stream_to_element(struct adp_conf_add_stream_to_element *const config);
920 
921 /* MSG_DATA_STREAM */
922 #define MSG_DATA_STREAM 0x40
923 SHORTENUM struct adp_msg_data_stream_data {
924 	uint16_t stream_id;
925 	uint8_t data_size;
926 	uint8_t *data;
927 };
928 
929 SHORTENUM struct adp_msg_data_stream {
930 	uint8_t number_of_streams;
931 	struct adp_msg_data_stream_data stream[ADP_MAX_OUTGOING_STREAMS];
932 };
933 
934 bool adp_send_stream(struct adp_msg_data_stream *const stream_data, uint8_t* receive_buf);
935 bool adp_send_single_stream(uint8_t stream_id, uint8_t* data, uint8_t data_size, uint8_t* receive_buf);
936 bool adp_transceive_stream(struct adp_msg_data_stream *const stream_data, uint8_t *receive_buf);
937 bool adp_transceive_single_stream(uint16_t stream_id, uint8_t* data, uint8_t data_size, uint8_t* receive_buf);
938 
939 /* Init SPI/TWI interface used. And some other misc init */
940 void adp_init(void);
941 uint16_t adp_add_send_byte(uint8_t* buffer, uint8_t index, uint8_t* data, uint16_t length);
942 
943 #endif
944