Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / diagnostic_station / station / comm_server.c @ 1198

History | View | Annotate | Download (6.1 KB)

1
#include "comm_server.h"
2

    
3
#include <avr/pgmspace.h>
4
#include <string.h>
5

    
6
#include "global.h"
7
#include "tests.h"
8

    
9
// ##############
10
// ## Settings ##
11
// ##############
12

    
13
//#define comm_server_debug
14

    
15
// ###############
16
// ## Constants ##
17
// ###############
18

    
19
#define buffer_size 120
20

    
21
// Put all symbolic string constants into the program memory because else all of them would be copied into the RAM (see
22
// the avr-libc documentation, chapter "Data in Program Space").
23

    
24
// Commands 
25
const char command_ping          [] PROGMEM = "ping"       ;
26
const char command_start_test    [] PROGMEM = "start_test" ;
27
const char command_all           [] PROGMEM = "all"        ;
28
const char command_comm          [] PROGMEM = "comm"       ;
29
const char command_bom           [] PROGMEM = "bom"        ;
30
const char command_rangefinder   [] PROGMEM = "rangefinder";
31
const char command_motor         [] PROGMEM = "motor"      ;
32
const char command_encoder       [] PROGMEM = "encoder"    ;
33
const char command_help          [] PROGMEM = "help"       ;
34

    
35
// Help
36
const char help_text          [] PROGMEM =
37
        "# Available commands:" NL
38
        "#   - help" NL
39
        "#   - ping" NL
40
        "#   - start_test all" NL
41
        "#   - start_test comm" NL
42
        "#   - start_test bom all|<num> (0..15)" NL
43
        "#   - start_test rangefinder all|<num> (?..?)" NL
44
        "#   - start_test motor all|<num> (1..2)" NL
45
        "#   - start_test encoder all|<num> (1..2)" NL
46
        ;
47

    
48

    
49
// ####################
50
// ## Initialization ##
51
// ####################
52

    
53
void comm_server_init ()
54
{
55
        usb_init ();
56
}
57

    
58

    
59
// ########################
60
// ## Message processing ##
61
// ########################
62

    
63
// TODO move this to the library
64
static void serial_send_string_P (PGM_P s)
65
{
66
    char buf;
67
    while (memcpy_P (&buf, s, sizeof (char)), buf!=0)
68
    {
69
        usb_putc (buf);
70
        s++;
71
    }
72
}
73

    
74
static char *find_next_parameter (char *p)
75
{
76
        // Advance p until a blank or the terminating zero is found.
77
        while ((*p)!=' ' && (*p)!=0) p++;
78
        
79
        // Advance p until a non-blank (including the terminating zero) is found.
80
        while (*p==' ') p++;
81
        
82
        // We have found the next parameter unless p points to the terminating zero.
83
        if (*p==0)
84
                return NULL;
85
        else
86
                return p;
87
}
88

    
89
/** Check if the buffer starts with the given text, followed by a space */
90
static bool serial_match (PGM_P text, const char *buffer)
91
{
92
        uint8_t text_len=strlen_P (text);
93
        uint8_t buffer_len=strlen (buffer);
94

    
95
        // If the buffer is shorter than the text, there is no match
96
        if (buffer_len<text_len) return false;
97

    
98
        // If the buffer is longer than the text, it must have a space at position after the text
99
        if (buffer_len>text_len && buffer[text_len]!=' ') return false;
100

    
101
        // Test for match
102
        if (strncmp_P ((char *)buffer, text, text_len)==0) return true;
103
        
104
        return false;
105
}
106

    
107

    
108

    
109

    
110

    
111

    
112
// ########################
113
// ## Messages (sending) ##
114
// ########################
115

    
116
void server_send_finished ()
117
{
118
        usb_puts ("finished");
119
}
120

    
121

    
122
// ######################
123
// ## Message handlers ##
124
// ######################
125

    
126
static void handle_message_ping (char *buffer)
127
{
128
        usb_puts ("pong" NL);
129
        orbs_set (255, 127, 0, 0, 255, 0);
130
        delay_ms (400);
131
        orbs_set (0, 255, 0, 255, 127, 0);
132
}
133

    
134
static void handle_message_start_test (char *buffer)
135
{
136
        // FIXME parameter handling
137
        // Parameters: all/rangefinder/motor/encoder all/<num>
138
        
139
        buffer=find_next_parameter (buffer);
140

    
141
        if (!buffer)
142
                usb_puts ("# Parameter missing" NL);
143
        else if (serial_match (command_all, buffer))
144
        {
145
                usb_puts ("# Doing all tests" NL);
146
                test_all ();
147
        }
148
        else
149
        {
150
                usb_puts ("# Warning: unhandled parameters: [");
151
                usb_puts (buffer);
152
                usb_puts ("]" NL);
153
        }
154
}
155

    
156
static void handle_message_help (char *buffer)
157
{
158
        serial_send_string_P (help_text);
159
}
160

    
161

    
162
// ##########################
163
// ## Messages (receiving) ##
164
// ##########################
165

    
166
/** message is 0 terminated */
167
static void handle_message (char *message)
168
{
169
#ifdef comm_server_debug
170
        // Output: "# Received a message, size <size>: [<message>]"
171
        usb_puts ("# Received a message, size ");
172
        usb_puti(size);
173
        usb_puts (": [");
174
        usb_puts ((char *)message);
175
        usb_puts ("]" NL);
176
#endif
177
        
178
        bool handled=false;
179
        if (serial_match (command_ping      , message)) { handle_message_ping       (message); handled=true; }
180
        if (serial_match (command_start_test, message)) { handle_message_start_test (message); handled=true; }
181
        if (serial_match (command_help      , message)) { handle_message_help       (message); handled=true; }
182
        // More messages go here
183
        
184
        if (!handled)
185
        {
186
                usb_puts ("# Warning: unhandled message: [");
187
                usb_puts ((char *)message);
188
                usb_puts ("]" NL);
189
        }
190
}
191

    
192

    
193
// ###############
194
// ## Debugging ##
195
// ###############
196

    
197
void byte_transmission_test (void)
198
{
199
        uint8_t c;
200
        
201
        while (1)
202
        {
203
                c=usb_getc ();
204
                usb_puts ("[");
205
                usb_puti (c);
206
                usb_puts ("] ");
207
        }
208
}
209

    
210

    
211
// ###############
212
// ## Main loop ##
213
// ###############
214

    
215
void server_main (void)
216
{
217
        char buffer[buffer_size];
218
        uint8_t c;
219
        uint8_t buffer_fill=0;
220

    
221
        //byte_transmission_test (); // Does not return
222

    
223
        usb_puts (NL);
224
        usb_puts ("# Diagnostic station server mode" NL);
225
        
226
        while (1)
227
        {
228
                // Do nothing until we receive a byte (this function will return 0 when a character has been read)
229
                // (Yes, we could use the blocking function for now, but we may need the non-blocking later)
230
                while (usb_getc_nb ((char *)&c));
231
                
232
                if (c=='\r' || c=='\n')
233
                {
234
                        // A newline character was received. This terminates the message.
235
                        
236
                        // Empty lines are ignored.
237
                        if (buffer_fill>0)
238
                        {
239
                                // Add a terminating 0 to the buffer so the string functions won't try to read outside the buffer.
240
                                buffer[buffer_fill]=0;
241
                                
242
                                // Handle the message.
243
                                handle_message (buffer);
244
                        
245
                                // Reset the buffer
246
                                buffer_fill=0;
247
                        }
248
                }
249
                else
250
                {
251
                        // If there is enough space left in the buffer, add the character we just received. Leave one byte for a
252
                        // terminating 0. If there is not enough space in the buffer, the rest of the message is ignored.
253
                        if (buffer_fill<buffer_size-1)
254
                        {
255
                                buffer[buffer_fill]=c;
256
                                ++buffer_fill;
257
                        }
258
                }
259
        
260
        }
261
}