xbee_neighbor: replace printf printf_P
[protos/xbee-avr.git] / DualVirtualSerial.c
1 /*\r
2              LUFA Library\r
3      Copyright (C) Dean Camera, 2011.\r
4 \r
5   dean [at] fourwalledcubicle [dot] com\r
6            www.lufa-lib.org\r
7 */\r
8 \r
9 /*\r
10   Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
11 \r
12   Permission to use, copy, modify, distribute, and sell this\r
13   software and its documentation for any purpose is hereby granted\r
14   without fee, provided that the above copyright notice appear in\r
15   all copies and that both that the copyright notice and this\r
16   permission notice and warranty disclaimer appear in supporting\r
17   documentation, and that the name of the author not be used in\r
18   advertising or publicity pertaining to distribution of the\r
19   software without specific, written prior permission.\r
20 \r
21   The author disclaim all warranties with regard to this\r
22   software, including all implied warranties of merchantability\r
23   and fitness.  In no event shall the author be liable for any\r
24   special, indirect or consequential damages or any damages\r
25   whatsoever resulting from loss of use, data or profits, whether\r
26   in an action of contract, negligence or other tortious action,\r
27   arising out of or in connection with the use or performance of\r
28   this software.\r
29 */\r
30 \r
31 /** \file\r
32  *\r
33  *  Main source file for the DualVirtualSerial demo. This file contains the main tasks of\r
34  *  the demo and is responsible for the initial application hardware configuration.\r
35  */\r
36 \r
37 #include "DualVirtualSerial.h"\r
38 \r
39 \r
40 #include <aversive.h>\r
41 #include <aversive/error.h>\r
42 #include <aversive/queue.h>\r
43 \r
44 #include <scheduler.h>\r
45 #include <clock_time.h>\r
46 #include <parse.h>\r
47 #include <rdline.h>\r
48 #include <timer.h>\r
49 \r
50 #include "xbee_neighbor.h"\r
51 #include "xbee_atcmd.h"\r
52 #include "xbee_stats.h"\r
53 #include "xbee_buf.h"\r
54 #include "xbee_proto.h"\r
55 #include "xbee.h"\r
56 \r
57 #include "callout.h"\r
58 #include "main.h"\r
59 #include "cmdline.h"\r
60 \r
61 volatile uint16_t global_ms;\r
62 struct callout_manager cm;\r
63 \r
64 \r
65 /** LUFA CDC Class driver interface configuration and state information. This structure is\r
66  *  passed to all CDC Class driver functions, so that multiple instances of the same class\r
67  *  within a device can be differentiated from one another. This is for the first CDC interface,\r
68  *  which sends strings to the host for each joystick movement.\r
69  */\r
70 USB_ClassInfo_CDC_Device_t VirtualSerial1_CDC_Interface =\r
71         {\r
72                 .Config =\r
73                         {\r
74                                 .ControlInterfaceNumber           = 0,\r
75 \r
76                                 .DataINEndpointNumber             = CDC1_TX_EPNUM,\r
77                                 .DataINEndpointSize               = CDC_TXRX_EPSIZE,\r
78                                 .DataINEndpointDoubleBank         = false,\r
79 \r
80                                 .DataOUTEndpointNumber            = CDC1_RX_EPNUM,\r
81                                 .DataOUTEndpointSize              = CDC_TXRX_EPSIZE,\r
82                                 .DataOUTEndpointDoubleBank        = false,\r
83 \r
84                                 .NotificationEndpointNumber       = CDC1_NOTIFICATION_EPNUM,\r
85                                 .NotificationEndpointSize         = CDC_NOTIFICATION_EPSIZE,\r
86                                 .NotificationEndpointDoubleBank   = false,\r
87                         },\r
88         };\r
89 \r
90 /** LUFA CDC Class driver interface configuration and state information. This structure is\r
91  *  passed to all CDC Class driver functions, so that multiple instances of the same class\r
92  *  within a device can be differentiated from one another. This is for the second CDC interface,\r
93  *  which echos back all received data from the host.\r
94  */\r
95 USB_ClassInfo_CDC_Device_t VirtualSerial2_CDC_Interface =\r
96         {\r
97                 .Config =\r
98                         {\r
99                                 .ControlInterfaceNumber           = 2,\r
100 \r
101                                 .DataINEndpointNumber             = CDC2_TX_EPNUM,\r
102                                 .DataINEndpointSize               = CDC_TXRX_EPSIZE,\r
103                                 .DataINEndpointDoubleBank         = false,\r
104 \r
105                                 .DataOUTEndpointNumber            = CDC2_RX_EPNUM,\r
106                                 .DataOUTEndpointSize              = CDC_TXRX_EPSIZE,\r
107                                 .DataOUTEndpointDoubleBank        = false,\r
108 \r
109                                 .NotificationEndpointNumber       = CDC2_NOTIFICATION_EPNUM,\r
110                                 .NotificationEndpointSize         = CDC_NOTIFICATION_EPSIZE,\r
111                                 .NotificationEndpointDoubleBank   = false,\r
112                         },\r
113         };\r
114 \r
115 \r
116 /* return time in milliseconds on unsigned 16 bits */\r
117 static uint16_t get_time_ms(void)\r
118 {\r
119         return global_ms;\r
120 }\r
121 \r
122 static void do_led_blink(struct callout_manager *cm,\r
123                          struct callout *clt, void *dummy)\r
124 {\r
125         static uint8_t a = 0;\r
126 \r
127         if (a & 1)\r
128                 LEDs_SetAllLEDs(0);\r
129         else\r
130                 LEDs_SetAllLEDs(0xff);\r
131         a++;\r
132 }\r
133 \r
134 static void increment_ms(void *dummy)\r
135 {\r
136         global_ms++;\r
137 }\r
138 \r
139 static void main_timer_interrupt(void)\r
140 {\r
141         static uint8_t cpt = 0;\r
142         cpt++;\r
143         sei();\r
144         if ((cpt & 0x3) == 0)\r
145                 scheduler_interrupt();\r
146 }\r
147 \r
148 \r
149 /** Main program entry point. This routine contains the overall program flow, including initial\r
150  *  setup of all components and the main program loop.\r
151  */\r
152 int main(void)\r
153 {\r
154         struct callout t1;\r
155         FILE *xbee_file;\r
156         int8_t err;\r
157         struct xbee_dev dev;\r
158 \r
159         SetupHardware();\r
160 \r
161         LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
162 \r
163         fdevopen(usbserial1_dev_send, usbserial1_dev_recv);\r
164         xbee_file = fdevopen(usbserial2_dev_send, usbserial2_dev_recv);\r
165         scheduler_init();\r
166         timer_init();\r
167         timer0_register_OV_intr(main_timer_interrupt);\r
168         sei();\r
169 \r
170         scheduler_add_periodical_event_priority(increment_ms, NULL,\r
171                                                 1000L / SCHEDULER_UNIT,\r
172                                                 LED_PRIO);\r
173         cmdline_init();\r
174         callout_manager_init(&cm, get_time_ms);\r
175         callout_reset(&cm, &t1, 500, PERIODICAL, do_led_blink, NULL);\r
176 \r
177         /* initialize libxbee */\r
178         err = xbee_init();\r
179         if (err < 0)\r
180                 return -1;\r
181 \r
182         xbee_dev = &dev;\r
183 \r
184         /* open xbee device */\r
185         if (xbee_open(xbee_dev, xbee_file) < 0)\r
186                 return -1;\r
187 \r
188         /* register default channel with a callback */\r
189         if (xbee_register_channel(xbee_dev, XBEE_DEFAULT_CHANNEL,\r
190                                   xbee_rx, NULL) < 0) {\r
191                 fprintf(stderr, "cannot register default channel\n");\r
192                 return -1;\r
193         }\r
194 \r
195         sei();\r
196         xbee_mainloop();\r
197         return 0;\r
198 }\r
199 \r
200 /** Configures the board hardware and chip peripherals for the demo's functionality. */\r
201 void SetupHardware(void)\r
202 {\r
203         /* Disable watchdog if enabled by bootloader/fuses */\r
204         MCUSR &= ~(1 << WDRF);\r
205         wdt_disable();\r
206 \r
207         /* Disable clock division */\r
208         clock_prescale_set(clock_div_1);\r
209 \r
210         /* Hardware Initialization */\r
211         Joystick_Init();\r
212         LEDs_Init();\r
213         USB_Init();\r
214 }\r
215 \r
216 /** Checks for changes in the position of the board joystick, sending strings to the host upon each change\r
217  *  through the first of the CDC interfaces.\r
218  */\r
219 void CheckJoystickMovement(void)\r
220 {\r
221         uint8_t     JoyStatus_LCL = Joystick_GetStatus();\r
222         char*       ReportString  = NULL;\r
223         static bool ActionSent = false;\r
224 \r
225         if (JoyStatus_LCL & JOY_UP)\r
226           ReportString = "Joystick Up\r\n";\r
227         else if (JoyStatus_LCL & JOY_DOWN)\r
228           ReportString = "Joystick Down\r\n";\r
229         else if (JoyStatus_LCL & JOY_LEFT)\r
230           ReportString = "Joystick Left\r\n";\r
231         else if (JoyStatus_LCL & JOY_RIGHT)\r
232           ReportString = "Joystick Right\r\n";\r
233         else if (JoyStatus_LCL & JOY_PRESS)\r
234           ReportString = "Joystick Pressed\r\n";\r
235         else\r
236           ActionSent = false;\r
237 \r
238         if ((ReportString != NULL) && (ActionSent == false))\r
239         {\r
240                 ActionSent = true;\r
241 \r
242                 CDC_Device_SendString(&VirtualSerial1_CDC_Interface, ReportString);\r
243         }\r
244 }\r
245 \r
246 /** Event handler for the library USB Connection event. */\r
247 void EVENT_USB_Device_Connect(void)\r
248 {\r
249         LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);\r
250 }\r
251 \r
252 /** Event handler for the library USB Disconnection event. */\r
253 void EVENT_USB_Device_Disconnect(void)\r
254 {\r
255         LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);\r
256 }\r
257 \r
258 /** Event handler for the library USB Configuration Changed event. */\r
259 void EVENT_USB_Device_ConfigurationChanged(void)\r
260 {\r
261         bool ConfigSuccess = true;\r
262 \r
263         ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial1_CDC_Interface);\r
264         ConfigSuccess &= CDC_Device_ConfigureEndpoints(&VirtualSerial2_CDC_Interface);\r
265 \r
266         LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);\r
267 \r
268         rdline_newline(&xbeeboard.rdl, xbeeboard.prompt);\r
269 }\r
270 \r
271 /** Event handler for the library USB Control Request reception event. */\r
272 void EVENT_USB_Device_ControlRequest(void)\r
273 {\r
274         CDC_Device_ProcessControlRequest(&VirtualSerial1_CDC_Interface);\r
275         CDC_Device_ProcessControlRequest(&VirtualSerial2_CDC_Interface);\r
276 }\r
277 \r