X-Git-Url: http://git.droids-corp.org/?p=protos%2Fxbee-avr.git;a=blobdiff_plain;f=main.c;h=2bcb3ec974bf6c2ad45334c4b03cd506e24b4279;hp=24fba694e914b892f6b5540729dd86965364c07d;hb=0f9366b7328777d91aa72f4b92cfcb232969e1ce;hpb=8c3e14e4eb2604046ff2b10ebdcc8a7b8381490e diff --git a/main.c b/main.c index 24fba69..2bcb3ec 100644 --- a/main.c +++ b/main.c @@ -60,6 +60,8 @@ #include "main.h" struct xbeeboard xbeeboard; +volatile uint16_t global_ms; +struct callout_manager cm; #define TIMEOUT_MS 1000 @@ -85,23 +87,26 @@ static void hexdump(const char *title, const void *buf, unsigned int len) #define LINE_LEN 80 char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */ - printf("%s at [%p], len=%d\n", title, data, len); + printf_P(PSTR("%s at [%p], len=%d\n"), title, data, len); ofs = 0; while (ofs < len) { /* format 1 line in the buffer, then use printk to print them */ - out = snprintf(line, LINE_LEN, "%08X", ofs); + out = snprintf_P(line, LINE_LEN, PSTR("%08X"), ofs); for (i=0; ofs+i < len && i<16; i++) - out += snprintf(line+out, LINE_LEN - out, " %02X", - data[ofs+i]&0xff); + out += snprintf_P(line+out, LINE_LEN - out, + PSTR(" %02X"), + data[ofs+i]&0xff); for (;i<=16;i++) out += snprintf(line+out, LINE_LEN - out, " "); for (i=0; ofs < len && i<16; i++, ofs++) { unsigned char c = data[ofs]; if (!isascii(c) || !isprint(c)) c = '.'; - out += snprintf(line+out, LINE_LEN - out, "%c", c); + out += snprintf_P(line+out, + LINE_LEN - out, + PSTR("%c"), c); } - printf("%s\n", line); + printf_P(PSTR("%s\r\n"), line); } } @@ -109,27 +114,27 @@ static int parse_xmit_status(struct xbee_ctx *ctx, struct xbee_xmit_status_hdr *frame, unsigned len) { if (ctx == NULL) { - printf("no context\n"); + printf_P(PSTR("no context\r\n")); return -1; } /* see if it matches a xmit query (atcmd_query must be NULL) */ - if (ctx->atcmd_query[0] == '\0') { - printf("invalid response 2\n"); + if (ctx->atcmd_query[0] != '\0') { + printf_P(PSTR("invalid response 2\r\n")); return -1; } /* XXX use defines for these values */ if (frame->delivery_status == 0x00) - printf("Success\n"); + printf_P(PSTR("Success\r\n")); else if (frame->delivery_status == 0x01) - printf("MAC ACK Failure\n"); + printf_P(PSTR("MAC ACK Failure\r\n")); else if (frame->delivery_status == 0x15) - printf("Invalid destination endpoint\n"); + printf_P(PSTR("Invalid destination endpoint\r\n")); else if (frame->delivery_status == 0x21) - printf("Network ACK Failure\n"); + printf_P(PSTR("Network ACK Failure\r\n")); else if (frame->delivery_status == 0x25) - printf("Route Not Found\n"); + printf_P(PSTR("Route Not Found\r\n")); return 0; } @@ -148,7 +153,7 @@ static int dump_atcmd(struct xbee_ctx *ctx, struct xbee_atresp_hdr *frame, } __attribute__((packed)) *result; if (ctx == NULL) { - printf("no context\n"); + printf_P(PSTR("no context\r\n")); return -1; } @@ -158,36 +163,36 @@ static int dump_atcmd(struct xbee_ctx *ctx, struct xbee_atresp_hdr *frame, /* see if it matches query */ if (memcmp(atcmd_str, ctx->atcmd_query, 2)) { - printf("invalid response <%c%c><%s><%s>\n", - frame->cmd & 0xFF, - (frame->cmd >> 8) & 0xFF, - atcmd_str, ctx->atcmd_query); + printf_P(PSTR("invalid response <%c%c><%s><%s>\r\n"), + frame->cmd & 0xFF, + (frame->cmd >> 8) & 0xFF, + atcmd_str, ctx->atcmd_query); return -1; } /* see if it exists */ cmd_pgm = xbee_atcmd_lookup_name(atcmd_str); if (cmd_pgm == NULL) { - printf("unknown response\n"); + printf_P(PSTR("unknown response\r\n")); return -1; } memcpy_P(&cmd, cmd_pgm, sizeof(cmd)); /* bad status */ if (frame->status == 1) { - printf("Status is error\n"); + printf_P(PSTR("Status is error\r\n")); return -1; } else if (frame->status == 2) { - printf("Invalid command\n"); + printf_P(PSTR("Invalid command\r\n")); return -1; } else if (frame->status == 3) { - printf("Invalid parameter\n"); + printf_P(PSTR("Invalid parameter\r\n")); return -1; } else if (frame->status != 0) { - printf("Unknown status error %d\n", frame->status); + printf_P(PSTR("Unknown status error %d\r\n"), frame->status); return -1; } @@ -199,15 +204,19 @@ static int dump_atcmd(struct xbee_ctx *ctx, struct xbee_atresp_hdr *frame, result = (void *)frame->data; len -= offsetof(struct xbee_atresp_hdr, data); if (cmd.flags & XBEE_ATCMD_F_PARAM_U8 && len == sizeof(uint8_t)) - printf("<%s> is 0x%x\n", atcmd_str, result->u8); + printf_P(PSTR("<%s> is 0x%x\r\n"), atcmd_str, result->u8); else if (cmd.flags & XBEE_ATCMD_F_PARAM_U16 && len == sizeof(uint16_t)) - printf("<%s> is 0x%x\n", atcmd_str, ntohs(result->u16)); + printf_P(PSTR("<%s> is 0x%x\r\n"), + atcmd_str, + ntohs(result->u16)); else if (cmd.flags & XBEE_ATCMD_F_PARAM_U32 && len == sizeof(uint32_t)) - printf("<%s> is 0x%"PRIx32"\n", atcmd_str, ntohl(result->u32)); + printf_P(PSTR("<%s> is 0x%"PRIx32"\r\n"), + atcmd_str, + ntohl(result->u32)); else if (cmd.flags & XBEE_ATCMD_F_PARAM_S16 && len == sizeof(int16_t)) - printf("<%s> is %d\n", atcmd_str, ntohs(result->s16)); + printf_P(PSTR("<%s> is %d\r\n"), atcmd_str, ntohs(result->s16)); else if (len == 0) - printf("no data, status ok\n"); + printf_P(PSTR("no data, status ok\r\n")); else hexdump("atcmd answer", frame->data, len); @@ -231,7 +240,7 @@ int xbee_recv_data(struct xbee_recv_hdr *recvframe, unsigned len) break; case RC_PROTO_TYPE_RANGE: { struct rc_proto_range *rcr = - (struct rc_proto_range *) recvframe; + (struct rc_proto_range *) recvframe->data; if (datalen != sizeof(struct rc_proto_range)) return -1; @@ -258,21 +267,22 @@ void xbee_rx(struct xbee_dev *dev, int channel, int type, int do_hexdump = xbee_hexdump; if (xbee_debug) - printf("type=0x%x, channel=%d, ctx=%p\n", type, channel, ctx); + printf_P(PSTR("type=0x%x, channel=%d, ctx=%p\r\n"), + type, channel, ctx); /* if ctx is !NULL, it is an answer to a query */ if (ctx != NULL) { /* XXX only delete timeout if answer matched */ xbee_unload_timeout(ctx); if (xbee_debug && ctx->atcmd_query) - printf("Received answer to query <%c%c>\n", - ctx->atcmd_query[0], ctx->atcmd_query[1]); + printf_P(PSTR("Received answer to query <%c%c>\r\n"), + ctx->atcmd_query[0], ctx->atcmd_query[1]); } /* some additional checks before sending */ switch (type) { case XBEE_TYPE_MODEM_STATUS: { - printf("Received Modem Status frame\n"); + printf_P(PSTR("Received Modem Status frame\r\n")); break; } @@ -291,8 +301,8 @@ void xbee_rx(struct xbee_dev *dev, int channel, int type, } addr; memcpy(&addr, frame, sizeof(addr)); addr.u64 = ntohll(addr.u64); - printf("from remote address %"PRIx32"%"PRIx32"\n", - addr.u32.high, addr.u32.low); + printf_P(PSTR("from remote address %"PRIx32"%"PRIx32"\r\n"), + addr.u32.high, addr.u32.low); /* this answer contains an atcmd answer at offset 10 */ if (dump_atcmd(ctx, frame + 10, len - 10) < 0) @@ -325,7 +335,7 @@ void xbee_rx(struct xbee_dev *dev, int channel, int type, case XBEE_TYPE_EXPL_RECV: case XBEE_TYPE_NODE_ID: default: - printf("Invalid frame\n"); + printf_P(PSTR("Invalid frame\r\n")); do_hexdump = 1; break; } @@ -350,7 +360,7 @@ static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, int channel; if (len > XBEE_MAX_FRAME_LEN) { - printf("frame too large\n"); + printf_P(PSTR("frame too large\r\n")); return -1; } @@ -358,7 +368,7 @@ static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, channel = xbee_register_channel(xbee_dev, XBEE_CHANNEL_ANY, xbee_rx, NULL); if (channel < 0) { - printf("cannot send: no free channel\n"); + printf_P(PSTR("cannot send: no free channel\r\n")); return -1; } @@ -368,8 +378,8 @@ static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, xbee_set_opaque(xbee_dev, channel, ctx); if (xbee_debug) - printf("send frame channel=%d type=0x%x len=%d\n", - channel, type, len); + printf_P(PSTR("send frame channel=%d type=0x%x len=%d\r\n"), + channel, type, len); if (xbee_hexdump) hexdump("xmit frame", buf, len); @@ -377,7 +387,7 @@ static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, ret = xbee_proto_xmit(xbee_dev, channel, type, buf, len); if (ret < 0) { - printf("cannot send\n"); + printf_P(PSTR("cannot send\r\n")); xbee_unregister_channel(xbee_dev, channel); return -1; } @@ -467,7 +477,7 @@ static void evt_timeout(struct callout_manager *cm, struct callout *clt, { struct xbee_ctx *ctx = arg; - printf("Timeout\n"); + printf_P(PSTR("Timeout\r\n")); /* restart command line */ xbee_stdin_enable(); @@ -489,7 +499,7 @@ void xbee_unload_timeout(struct xbee_ctx *ctx) void bootloader(void) { -#define BOOTLOADER_ADDR 0x1e000 +#define BOOTLOADER_ADDR 0x1f800 if (pgm_read_byte_far(BOOTLOADER_ADDR) == 0xff) { printf_P(PSTR("Bootloader is not present\r\n")); return; @@ -518,13 +528,12 @@ void xbee_mainloop(void) int16_t c; /* from xbee to cmdline */ - c = CDC_Device_ReceiveByte(&VirtualSerial2_CDC_Interface); + c = xbee_dev_recv(NULL); if (c >= 0) - CDC_Device_SendByte(&VirtualSerial1_CDC_Interface, - (uint8_t)c); + cmdline_dev_send((uint8_t)c, NULL); /* from cmdline to xbee */ - c = CDC_Device_ReceiveByte(&VirtualSerial1_CDC_Interface); + c = cmdline_dev_recv(NULL); if (c == 4) { /* CTRL-d */ xbee_raw = 0; rdline_newline(&xbeeboard.rdl, @@ -532,11 +541,10 @@ void xbee_mainloop(void) } else if (c >= 0) { /* send to xbee */ - CDC_Device_SendByte(&VirtualSerial2_CDC_Interface, - (uint8_t)c); + xbee_dev_send((uint8_t)c, NULL); + /* echo on cmdline */ - CDC_Device_SendByte(&VirtualSerial1_CDC_Interface, - (uint8_t)c); + cmdline_dev_send((uint8_t)c, NULL); } } else { @@ -545,8 +553,104 @@ void xbee_mainloop(void) xbee_proto_rx(xbee_dev); } +#ifdef USE_USB CDC_Device_USBTask(&VirtualSerial1_CDC_Interface); CDC_Device_USBTask(&VirtualSerial2_CDC_Interface); USB_USBTask(); +#endif } } + +/* return time in milliseconds on unsigned 16 bits */ +static uint16_t get_time_ms(void) +{ + return global_ms; +} + +static void do_led_blink(struct callout_manager *cm, + struct callout *clt, void *dummy) +{ + static uint8_t a = 0; + +#ifdef USE_USB + if (a & 1) + LEDs_SetAllLEDs(0); + else + LEDs_SetAllLEDs(0xff); +#else + /* XXX */ +#endif + a++; +} + +static void increment_ms(void *dummy) +{ + global_ms++; +} + +static void main_timer_interrupt(void) +{ + static uint8_t cpt = 0; + cpt++; + sei(); + if ((cpt & 0x3) == 0) + scheduler_interrupt(); +} + +/** Main program entry point. This routine contains the overall program flow, including initial + * setup of all components and the main program loop. + */ +int main(void) +{ + struct callout t1; + FILE *xbee_file; + int8_t err; + struct xbee_dev dev; + +#ifdef USE_USB + SetupHardware(); + + LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); +#else + uart_init(); +#endif + + fdevopen(cmdline_dev_send, cmdline_dev_recv); + xbee_file = fdevopen(xbee_dev_send, xbee_dev_recv); + scheduler_init(); + timer_init(); + timer0_register_OV_intr(main_timer_interrupt); + + scheduler_add_periodical_event_priority(increment_ms, NULL, + 1000L / SCHEDULER_UNIT, + LED_PRIO); + cmdline_init(); +#ifndef USE_USB + /* in usb mode, it's done in usb callback */ + rdline_newline(&xbeeboard.rdl, xbeeboard.prompt); +#endif + callout_manager_init(&cm, get_time_ms); + callout_reset(&cm, &t1, 500, PERIODICAL, do_led_blink, NULL); + + /* initialize libxbee */ + err = xbee_init(); + if (err < 0) + return -1; + + xbee_dev = &dev; + + /* open xbee device */ + if (xbee_open(xbee_dev, xbee_file) < 0) + return -1; + + /* register default channel with a callback */ + if (xbee_register_channel(xbee_dev, XBEE_DEFAULT_CHANNEL, + xbee_rx, NULL) < 0) { + fprintf(stderr, "cannot register default channel\n"); + return -1; + } + + sei(); + xbee_mainloop(); + return 0; +}