+
+/* 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;
+}