1 #include <stepper-process.h>
2 #include <stepper-steps.h>
4 #include <stepper-move.h>
6 #include <interrupt-utils.h>
17 parse_uint_hex(
const char **pp,
const char *end)
22 if ((ch = **pp) >=
'0' && ch <=
'9') {
23 v = v* 16 + (ch -
'0');
24 }
else if (ch >=
'A' && ch <=
'F') {
25 v = v* 16 + (ch -
'A') + 10;
33 parse_int_hex(
const char **pp,
const char *end)
35 if (*pp == end)
return 0;
38 return -parse_uint_hex(pp, end);
40 return parse_uint_hex(pp, end);
45 skip_white(
const char **pp,
const char *end)
48 while(*pp < end && ((ch = **pp) ==
' ' || ch ==
'\t')) (*pp)++;
51 static const char hex_chars[] =
52 {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'};
55 format_uint_hex(
char **str,
char *end,
unsigned int v)
59 if (*str == end)
return;
65 *--p = hex_chars[v&0xf];
68 while((p < buffer+10) && (*str < end)) {
74 format_int_hex(
char **str,
char *end,
int v)
77 if (*str == end)
return;
81 format_uint_hex(str, end, v);
85 format_ull_hex(
char **str,
char *end,
unsigned long long int v)
89 if (*str == end)
return;
95 *--p = hex_chars[v&0xf];
98 while((p < buffer+10) && (*str < end)) {
103 format_ll_hex(
char **str,
char *end,
long long v)
106 if (*str == end)
return;
110 format_ull_hex(str, end, v);
113 typedef struct _ReplyBuffer ReplyBuffer;
121 static ReplyBuffer tcp_reply;
122 static ReplyBuffer udp_reply;
124 #define REPLY_BUFFER_END(reply) ((reply)->buffer+sizeof((reply)->buffer))
125 #define REPLY_BUFFER_LEFT(reply) \
126 ((reply)->buffer+sizeof((reply)->buffer) - (reply)->write)
129 reply_char(ReplyBuffer *reply,
char c)
131 if (REPLY_BUFFER_LEFT(reply) > 0) {
137 reply_str(ReplyBuffer *reply,
char *str)
139 while(reply->write < REPLY_BUFFER_END(reply) && *str !=
'\0')
140 *reply->write++ = *str++;
144 stepper_reply(ReplyBuffer *reply, StepperResult res)
148 reply_str(reply,
"OK");
150 case STEPPER_ERR_MEM:
151 reply_str(reply,
"ERR MEM");
153 case STEPPER_ERR_TOO_LATE:
154 reply_str(reply,
"ERR LATE");
156 case STEPPER_ERR_INDEX:
157 reply_str(reply,
"ERR INDEX");
160 reply_str(reply,
"ERR");
162 reply_char(reply,
'\n');
165 #define CHECK_INPUT_LEFT(x) \
167 if ((x) > inend - input_line) {reply_str(reply, "ERR\n");return 0;}\
171 handle_line(
const char *input_line,
const char *inend, ReplyBuffer *reply)
176 const char *p = input_line;
177 printf(
"Got line: '");
185 skip_white(&input_line, inend);
187 if (*input_line ==
'#') {
189 reply_char(reply,
'#');
190 while (input_line < inend &&*input_line !=
' ') {
191 reply_char(reply, *input_line++);
193 reply_char(reply,
' ');
195 skip_white(&input_line, inend);
197 if (*input_line ==
'@') {
199 when = parse_uint_hex(&input_line, inend);
201 when = stepper_current_period() + 3;
203 skip_white(&input_line, inend);
205 if (input_line[0] ==
'L' || input_line[0] ==
'R') {
206 unsigned int stepper_index = (input_line[0] ==
'R' ? 1 : 0);
209 if (input_line[0] ==
'S') {
212 if (input_line == inend) {
215 reply_char(reply, input_line[-2]);
216 reply_char(reply,
'S');
217 format_int_hex(&reply->write, REPLY_BUFFER_END(reply),
218 stepper_current_velocity(stepper_index)/VEL_SCALE);
219 reply_char(reply,
'\n');
221 speed = parse_int_hex(&input_line, inend);
222 if (*input_line ==
',') {
226 acc = parse_uint_hex(&input_line, inend);
228 res = stepper_set_velocity(stepper_index, &when,
229 acc, speed*VEL_SCALE);
231 stepper_reply(reply, res);
233 reply_str(reply,
"ERR\n");
236 }
else if (input_line[0] ==
'C') {
237 reply_char(reply, input_line[-1]);
238 reply_char(reply,
'C');
239 format_ll_hex(&reply->write, REPLY_BUFFER_END(reply),
240 stepper_current_step(stepper_index));
241 reply_char(reply,
'\n');
242 }
else if (input_line[0] ==
'M') {
247 speed = parse_uint_hex(&input_line, inend);
249 if (*input_line ==
',') {
251 acc = parse_uint_hex(&input_line, inend);
252 if (*input_line ==
',') {
255 move = parse_int_hex(&input_line, inend);
257 res = stepper_move(stepper_index, &when,
258 acc,speed*VEL_SCALE,move*DIST_SCALE);
259 stepper_reply(reply, res);
261 reply_str(reply,
"ERR\n");
264 reply_str(reply,
"ERR\n");
267 reply_str(reply,
"ERR\n");
269 }
else if (input_line[0] ==
'E') {
271 printf(
"Stepper enabled\n");
272 reply_str(reply,
"OK\n");
273 }
else if (input_line[0] ==
'D') {
275 printf(
"Stepper disabled\n");
276 reply_str(reply,
"OK\n");
277 }
else if (input_line[0] ==
'p') {
278 reply_char(reply,
'p');
279 format_int_hex(&reply->write, REPLY_BUFFER_END(reply),
281 reply_char(reply,
',');
282 format_uint_hex(&reply->write, REPLY_BUFFER_END(reply),
283 cc2420_last_correlation);
284 reply_char(reply,
'\n');
285 }
else if (input_line[0] ==
'T') {
286 reply_char(reply,
'T');
287 format_int_hex(&reply->write, REPLY_BUFFER_END(reply),
288 stepper_current_period());
289 reply_char(reply,
'\n');
290 }
else if (input_line[0] ==
'q') {
293 reply_str(reply,
"ERR\n");
297 static unsigned int transmit_len = 0;
302 if (transmit_len == 0) {
303 transmit_len = tcp_reply.write - tcp_reply.buffer;
304 if (transmit_len > 0) {
306 uip_send(tcp_reply.buffer, transmit_len);
315 static char exiting = 0;
316 static char line_buffer[100];
317 static char *line_end;
321 line_end = line_buffer;
322 tcp_reply.write = tcp_reply.buffer;
323 reply_str(&tcp_reply,
"Ready\n");
327 if (tcp_reply.write - tcp_reply.buffer > transmit_len) {
328 memmove(tcp_reply.buffer, tcp_reply.buffer + transmit_len,
329 tcp_reply.write - tcp_reply.buffer - transmit_len);
331 tcp_reply.write -= transmit_len;
334 if (exiting && tcp_reply.write == tcp_reply.buffer) {
341 const char *read_end = read_pos +
uip_len;
343 while(read_pos < read_end) {
344 if (line_end == line_buffer+
sizeof(line_buffer)) {
346 line_end = line_buffer;
348 *line_end++ = *read_pos++;
349 if (line_end[-1] ==
'\n' || line_end[-1] ==
'\r' || line_end[-1] ==
';'){
350 if (line_end - 1 != line_buffer) {
351 if (handle_line(line_buffer, line_end - 1, &tcp_reply)) {
354 if (transmit_len == 0)
361 line_end = line_buffer;
371 printf(
"Retransmit\n");
372 if (transmit_len > 0)
373 uip_send(tcp_reply.buffer, transmit_len);
378 PROCESS(udp_stepper_process,
"UDP stepper process");
384 static char listening = 1;
389 printf(
"udp_stepper_process starting\n");
393 if (!conn)
goto exit;
401 struct uip_udpip_hdr *header = (
struct uip_udpip_hdr *)uip_buf;
403 const char *line_end = line_start;
404 const char *packet_end = line_start +
uip_len;
405 udp_reply.write = udp_reply.buffer;
406 while(line_end < packet_end) {
407 if (*line_end ==
'\n' || *line_end ==
'\r' || *line_end ==
';' ) {
408 if (line_end != line_start) {
409 handle_line(line_start, line_end, &udp_reply);
411 line_start = line_end+1;
418 conn =
udp_new(&header->srcipaddr, header->srcport, &conn);
419 if (!conn)
goto exit;
427 uip_send(udp_reply.buffer, udp_reply.write - udp_reply.buffer);
431 }
else if (ev == PROCESS_EVENT_TIMER) {
434 if (!conn)
goto exit;
443 printf(
"udprecv_process exiting\n");
447 static const uint32_t stepper0_steps_acc[] = MICRO_STEP(0,3);
448 static const uint32_t stepper0_steps_run[] = MICRO_STEP(0,2);
449 static const uint32_t stepper0_steps_hold[] = MICRO_STEP(0,1);
451 static const uint32_t stepper1_steps_acc[] = MICRO_STEP(1,3);
452 static const uint32_t stepper1_steps_run[] = MICRO_STEP(1,2);
453 static const uint32_t stepper1_steps_hold[] = MICRO_STEP(1,1);
455 static StepperAccSeq seq_heap[40];
461 for(i = 0; i <
sizeof(seq_heap)/
sizeof(seq_heap[0]); i++) {
462 seq_heap[i].next =
NULL;
463 stepper_free_seq(&seq_heap[i]);
472 stepper_init(AT91C_BASE_TC0, AT91C_ID_TC0);
473 *AT91C_PIOA_OER = STEPPER_INHIBIT;
474 *AT91C_PIOA_MDER = STEPPER_INHIBIT;
475 *AT91C_PIOA_CODR = STEPPER_INHIBIT;
476 stepper_init_io(1, STEPPER_IOMASK(0), stepper0_steps_acc,
477 stepper0_steps_run, stepper0_steps_hold,
478 (
sizeof(stepper0_steps_run) /
sizeof(stepper0_steps_run[0])));
479 stepper_init_io(0, STEPPER_IOMASK(1), stepper1_steps_acc,
480 stepper1_steps_run, stepper1_steps_hold,
481 (
sizeof(stepper1_steps_run) /
sizeof(stepper1_steps_run[0])));
486 PROCESS(stepper_process,
"Stepper control process");
492 robot_stepper_init();
496 printf(
"Stepper starting\n");
508 printf(
"disconnected\n");
514 printf(
"Stepper exiting\n");