X-Git-Url: http://git.droids-corp.org/?p=protos%2Fxbee-avr.git;a=blobdiff_plain;f=xbee_user.c;h=ecca81686feb4675f1f4a2db1631e9c191ac6a0f;hp=81f2fb649a424bcc625dfd51661522e39d12144b;hb=a992a62a843658a6f6a38158c3e13ce3dae45568;hpb=c17da94fafe8e0fa1a467f0c8fb7922fec8386e5 diff --git a/xbee_user.c b/xbee_user.c index 81f2fb6..ecca816 100644 --- a/xbee_user.c +++ b/xbee_user.c @@ -36,14 +36,17 @@ #include #include +#include #include #include +#include #include "rc_proto.h" #include "xbee_user.h" #include "main.h" -#define XBEE_TIMEOUT_MS 1000 +#define XBEE_TIMEOUT_MS 1000 +#define XBEE_POLL_TIMER_MS 5 static struct xbee_ctx xbee_ctx[XBEE_MAX_CHANNEL]; @@ -54,14 +57,13 @@ int xbee_raw = 0; int xbee_hexdump = 0; int xbee_debug = 0; -static void hexdump(const char *title, const void *buf, unsigned int len) +static void __hexdump(const void *buf, unsigned int len) { unsigned int i, out, ofs; const unsigned char *data = buf; #define LINE_LEN 80 char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */ - printf_P(PSTR("%s at [%p], len=%d\r\n"), title, data, len); ofs = 0; while (ofs < len) { /* format 1 line in the buffer, then use printk to print them */ @@ -84,8 +86,26 @@ static void hexdump(const char *title, const void *buf, unsigned int len) } } +static void hexdump_msg(const char *title, const struct xbee_msg *msg) +{ + unsigned i; + + printf_P(PSTR("dump %s\r\n"), title); + for (i = 0; i < msg->iovlen; i++) { + printf_P(PSTR("iovec %d at %p, len=%d\r\n"), i, + msg->iov[i].buf, msg->iov[i].len); + __hexdump(msg->iov[i].buf, msg->iov[i].len); + } +} + +static void hexdump(const char *title, const void *buf, unsigned int len) +{ + printf_P(PSTR("dump %s at [%p], len=%d\r\n"), title, buf, len); + __hexdump(buf, len); +} + static int parse_xmit_status(struct xbee_ctx *ctx, - struct xbee_xmit_status_hdr *frame, unsigned len) + struct xbee_xmit_status_hdr *frame, unsigned len) { (void)len; @@ -116,7 +136,7 @@ static int parse_xmit_status(struct xbee_ctx *ctx, } static int dump_atcmd(struct xbee_ctx *ctx, struct xbee_atresp_hdr *frame, - unsigned len) + unsigned len) { char atcmd_str[3]; const struct xbee_atcmd *cmd_pgm; @@ -362,17 +382,12 @@ int8_t xbeeapp_rx(struct xbee_dev *dev, int channel, int type, return ret; } -static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, - int foreground) +static int xbeeapp_send(struct xbee_ctx *ctx, int type, struct xbee_msg *msg, + int foreground) { int ret; int channel; - if (len > XBEE_MAX_FRAME_LEN) { - printf_P(PSTR("frame too large\r\n")); - return -1; - } - /* register a channel */ channel = xbee_register_channel(xbee_dev, XBEE_CHANNEL_ANY, xbeeapp_rx, NULL); @@ -387,13 +402,13 @@ 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_P(PSTR("send frame channel=%d type=0x%x len=%d\r\n"), - channel, type, len); + printf_P(PSTR("send frame channel=%d type=0x%x\r\n"), + channel, type); if (xbee_hexdump) - hexdump("xmit frame", buf, len); + hexdump_msg("xmit frame", msg); /* transmit the frame on this channel */ - ret = xbee_tx(xbee_dev, channel, type, buf, len); + ret = xbee_tx_iovec(xbee_dev, channel, type, msg); if (ret < 0) { printf_P(PSTR("cannot send\r\n")); xbee_unregister_channel(xbee_dev, channel); @@ -415,15 +430,15 @@ static int xbeeapp_send(struct xbee_ctx *ctx, int type, void *buf, unsigned len, /* send an AT command with parameters filled by caller. Disable * command line until we get the answer or until a timeout occurs */ -int xbeeapp_send_atcmd(const char *atcmd_str, - void *param, unsigned param_len, int foreground, - int (*func)(void *frame, unsigned len, void *arg), void *arg) +int xbeeapp_send_atcmd(char *atcmd_str, void *param, + unsigned param_len, int foreground, + int (*func)(void *frame, unsigned len, void *arg), void *arg) { struct xbee_ctx ctx; - struct { - struct xbee_atcmd_hdr atcmd; - char buf[XBEE_MAX_FRAME_LEN]; - } __attribute__((packed)) frame; + /* struct xbee_atcmd_hdr atcmd_hdr; -> no needed same than atcmd_str */ + struct xbee_msg msg; + uint8_t prio; + int ret; memset(&ctx, 0, sizeof(ctx)); ctx.atcmd_query[0] = atcmd_str[0]; @@ -431,43 +446,53 @@ int xbeeapp_send_atcmd(const char *atcmd_str, ctx.func = func; ctx.arg = arg; - memcpy(&frame.atcmd.cmd, atcmd_str, 2); - memcpy(&frame.buf, param, param_len); + msg.iovlen = 2; + msg.iov[0].buf = atcmd_str; + msg.iov[0].len = 2; + msg.iov[1].buf = param; + msg.iov[1].len = param_len; - if (xbeeapp_send(&ctx, XBEE_TYPE_ATCMD, &frame, - sizeof(struct xbee_atcmd_hdr) + - param_len, foreground) < 0) { - return -1; - } + prio = callout_mgr_set_prio(&xbeeboard.intr_cm, XBEE_PRIO); + ret = xbeeapp_send(&ctx, XBEE_TYPE_ATCMD, &msg, foreground); + callout_mgr_restore_prio(&xbeeboard.intr_cm, prio); - return 0; + return ret; } -int xbeeapp_send_msg(uint64_t addr, void *data, - unsigned data_len, int foreground) +int xbeeapp_send_msg(uint64_t addr, struct xbee_msg *msg, int foreground) { struct xbee_ctx ctx; - struct { - struct xbee_xmit_hdr xmit; - char buf[XBEE_MAX_FRAME_LEN]; - } __attribute__((packed)) frame; + struct xbee_xmit_hdr xmit_hdr; + struct xbee_msg msg2; + unsigned i; + uint8_t prio; + int ret; + + if (msg->iovlen + 2 > XBEE_MSG_MAXIOV) { + printf_P(PSTR("too many iovecs\r\n")); + return -1; + } + + + xmit_hdr.dstaddr = htonll(addr); + xmit_hdr.reserved = htons(0xFFFE); + xmit_hdr.bcast_radius = 0; + xmit_hdr.opts = 0; + + msg2.iovlen = msg->iovlen + 1; + msg2.iov[0].buf = &xmit_hdr; + msg2.iov[0].len = sizeof(xmit_hdr); + for (i = 0; i < msg->iovlen; i++) + msg2.iov[i+1] = msg->iov[i]; memset(&ctx, 0, sizeof(ctx)); ctx.atcmd_query[0] = '\0'; - frame.xmit.dstaddr = htonll(addr); - frame.xmit.reserved = htons(0xFFFE); - frame.xmit.bcast_radius = 0; - frame.xmit.opts = 0; - memcpy(&frame.buf, data, data_len); + prio = callout_mgr_set_prio(&xbeeboard.intr_cm, XBEE_PRIO); + ret = xbeeapp_send(&ctx, XBEE_TYPE_XMIT, &msg2, foreground); + callout_mgr_restore_prio(&xbeeboard.intr_cm, prio); - if (xbeeapp_send(&ctx, XBEE_TYPE_XMIT, &frame, - sizeof(struct xbee_xmit_hdr) + - data_len, foreground) < 0) { - return -1; - } - - return 0; + return ret; } static void evt_timeout(struct callout_mgr *cm, struct callout *clt, @@ -501,8 +526,18 @@ void xbee_unload_timeout(struct xbee_ctx *ctx) callout_stop(&xbeeboard.mainloop_cm, &ctx->timeout); } +static void xbee_rx_poll_timer_cb(struct callout_mgr *cm, struct callout *tim, + void *arg) +{ + (void) arg; + xbee_rx(xbee_dev); + callout_reschedule(cm, tim, XBEE_POLL_TIMER_MS); +} + void xbee_mainloop(void) { + uint8_t prio; + while (1) { callout_manage(&xbeeboard.mainloop_cm); @@ -517,11 +552,14 @@ void xbee_mainloop(void) /* from cmdline to xbee */ c = cmdline_dev_recv(NULL); if (c == 4) { /* CTRL-d */ + prio = callout_mgr_set_prio(&xbeeboard.intr_cm, + XBEE_PRIO); xbee_dev_send('A', NULL); xbee_dev_send('T', NULL); xbee_dev_send('C', NULL); xbee_dev_send('N', NULL); xbee_dev_send('\n', NULL); + callout_mgr_restore_prio(&xbeeboard.intr_cm, prio); xbee_raw = 0; rdline_newline(&xbeeboard.rdl, xbeeboard.prompt); @@ -537,7 +575,8 @@ void xbee_mainloop(void) else { if (xbee_cmdline_input_enabled) cmdline_poll(); - xbee_rx(xbee_dev); + /* xbee rx polling is done in a timer, so we can block + * the cmdline without loosing incoming packets */ } } } @@ -551,3 +590,11 @@ void xbee_stdin_disable(void) { xbee_cmdline_input_enabled = 0; } + +void xbeeapp_init(void) +{ + callout_init(&xbeeboard.xbee_rx_poll_timer, xbee_rx_poll_timer_cb, + NULL, XBEE_PRIO); + callout_schedule(&xbeeboard.intr_cm, + &xbeeboard.xbee_rx_poll_timer, XBEE_POLL_TIMER_MS); +}