version 0.1 written by Akiba, taken from here:
[chibi.git] / demo / chb_demo.c
blob06f8e22c742de6b78895562f9a7c0cb12c7b4bfe
1 /*******************************************************************
2 Copyright (C) 2009 FreakLabs
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 1. Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 2. Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 3. Neither the name of the the copyright holder nor the names of its contributors
15 may be used to endorse or promote products derived from this software
16 without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
22 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 SUCH DAMAGE.
30 Originally written by Christopher Wang aka Akiba.
31 Please post support questions to the FreakLabs forum.
33 *******************************************************************/
34 /*!
35 \file
36 \ingroup
40 /**************************************************************************/
41 #include <avr/pgmspace.h>
42 #include "chb_demo.h"
43 #include "freakusb.h"
44 #include "chb.h"
45 #include "chb_drvr.h"
47 FILE file_str = FDEV_SETUP_STREAM(chb_demo_putchar, NULL, _FDEV_SETUP_WRITE);
49 // static globals
50 static U8 msg[CHB_MAX_MSG_SIZE];
51 static U8 *msg_ptr;
53 // command prototypes
54 void cmd_parse(char *cmd);
55 static void cmd_hello(U8 argc, char **argv);
56 static void cmd_set_short_addr(U8 argc, char **argv);
57 static void cmd_get_short_addr(U8 argc, char **argv);
58 static void cmd_set_ieee_addr(U8 argc, char **argv);
59 static void cmd_get_ieee_addr(U8 argc, char **argv);
60 static void cmd_tx(U8 argc, char **argv);
61 static void cmd_reg_read(U8 argc, char **argv);
62 static void cmd_reg_write(U8 argc, char **argv);
63 static void cmd_reg_dump(U8 argc, char **argv);
65 // command table
66 static chb_cmd_t cmd_tbl[] =
68 {"hello", cmd_hello},
69 {"setsaddr", cmd_set_short_addr},
70 {"getsaddr", cmd_get_short_addr},
71 {"setiaddr", cmd_set_ieee_addr},
72 {"getiaddr", cmd_get_ieee_addr},
73 {"rd", cmd_reg_read},
74 {"wr", cmd_reg_write},
75 {"dump", cmd_reg_dump},
76 {"send", cmd_tx},
77 {NULL, NULL}
80 /**************************************************************************/
81 /*!
82 This is the putchar function that is used by avr-libc's printf. We need
83 to hook this function into the stdout file stream using the FDEV_SETUP_STREAM
84 macro in avr-libc. Once the stream is set up, we hook the stream to stdout
85 and we can do printfs via USB.
87 /**************************************************************************/
88 int chb_demo_putchar(char c, FILE *unused)
90 usb_pcb_t *pcb = usb_pcb_get();
92 if (!(pcb->flags & (1<<ENUMERATED)))
94 return 0;
97 if (c == '\n')
99 usb_buf_write(EP_1, '\n');
100 usb_buf_write(EP_1, '\r');
102 else
104 usb_buf_write(EP_1, (U8)c);
106 ep_write(EP_1);
107 return 0;
110 /**************************************************************************/
112 This is the rx handling function. It will handle any incoming data from
113 the USB. This function needs to be registered with the CDC class since
114 the CDC doesn't know what to do with received data.
116 /**************************************************************************/
117 void rx()
119 U8 i, c, ep_num, len;
120 usb_pcb_t *pcb = usb_pcb_get();
122 // get the ep number of any endpoint with pending rx data
123 if ((ep_num = usb_buf_data_pending(DIR_OUT)) != 0xFF)
125 // get the length of data in the OUT buffer
126 len = pcb->fifo[ep_num].len;
128 // read out the data in the buffer and echo it back to the host.
129 for (i=0; i<len; i++)
131 c = usb_buf_read(ep_num);
133 switch (c)
135 case '\r':
136 // terminate the msg and reset the msg ptr. then send
137 // it to the handler for processing.
138 *msg_ptr = '\0';
139 printf_P(PSTR("\n\r"));
140 cmd_parse((char *)msg);
141 msg_ptr = msg;
142 break;
144 case '\b':
145 usb_buf_write(EP_1, c);
146 if (msg_ptr > msg)
148 msg_ptr--;
150 break;
152 default:
153 usb_buf_write(EP_1, c);
154 *msg_ptr++ = c;
155 break;
158 pcb->flags |= (1 << TX_DATA_AVAIL);
162 /**************************************************************************/
166 /**************************************************************************/
167 static void cmd_menu()
169 printf_P(PSTR("\n"));
170 printf_P(PSTR("********** CHIBI **************\n"));
171 printf_P(PSTR("CHIBI >> "));
174 /**************************************************************************/
178 /**************************************************************************/
179 void cmd_parse(char *cmd)
181 U8 argc, i = 0;
182 char *argv[30];
184 fflush(stdout);
186 argv[i] = strtok(cmd, " ");
189 argv[++i] = strtok(NULL, " ");
190 } while ((i < CHB_MAX_MSG_SIZE) && (argv[i] != NULL));
192 argc = i;
193 for (i=0; cmd_tbl[i].cmd != NULL; i++)
195 if (!strcmp(argv[0], cmd_tbl[i].cmd))
197 cmd_tbl[i].func(argc, argv);
198 cmd_menu();
199 return;
202 printf_P(PSTR("CMD: Command not recognized.\n"));
204 cmd_menu();
207 /**************************************************************************/
211 /**************************************************************************/
212 int main()
214 pcb_t *pcb = chb_get_pcb();
215 chb_rx_data_t rx_data;
217 usb_init();
218 hw_init();
220 // init the class driver here
221 cdc_init();
223 // register the rx handler function with the cdc
224 cdc_reg_rx_handler(rx);
226 // hook the putchar function into the printf stdout filestream. This is needed
227 // for printf to work.
228 stdout = &file_str;
230 // init the msg ptr
231 msg_ptr = msg;
233 // init chibi stack
234 chb_init();
236 // and off we go...
237 while (1)
239 usb_poll();
241 if (pcb->data_rcv)
243 rx_data.len = chb_read(&rx_data);
244 printf_P(PSTR("Message received from node %02X: %s.\n"), rx_data.src_addr, rx_data.data);
245 pcb->data_rcv = false;
249 return 0;
252 /**************************************************************************/
256 /**************************************************************************/
257 static void cmd_hello(U8 argc, char **argv)
259 printf_P(PSTR("Hello World!\n"));
262 /**************************************************************************/
266 /**************************************************************************/
267 static void cmd_set_short_addr(U8 argc, char **argv)
269 U16 addr = strtol(argv[1], NULL, 16);
270 chb_set_short_addr(addr);
273 /**************************************************************************/
277 /**************************************************************************/
278 static void cmd_get_short_addr(U8 argc, char **argv)
280 U16 addr = chb_get_short_addr();
281 printf_P(PSTR("Short Addr = %04X.\n"), addr);
284 /**************************************************************************/
288 /**************************************************************************/
289 static void cmd_set_ieee_addr(U8 argc, char **argv)
291 U8 i, addr[8];
293 memset(addr, 0, 8);
294 for (i=0; i<argc-1; i++)
296 addr[i] = strtol(argv[i+1], NULL, 16);
298 chb_set_ieee_addr(addr);
301 /**************************************************************************/
305 /**************************************************************************/
306 static void cmd_get_ieee_addr(U8 argc, char **argv)
308 U8 i, addr[8];
310 chb_get_ieee_addr(addr);
312 printf_P(PSTR("IEEE Addr = "));
313 for (i=8; i>0; i--)
315 printf("%02X", addr[i-1]);
319 /**************************************************************************/
323 /**************************************************************************/
324 static void cmd_reg_read(U8 argc, char **argv)
326 U8 addr, val;
328 addr = strtol(argv[1], NULL, 16);
329 val = chb_reg_read(addr);
330 printf_P(PSTR("Reg Read: %04X, %02X.\n"), addr, val);
333 /**************************************************************************/
337 /**************************************************************************/
338 static void cmd_reg_write(U8 argc, char **argv)
340 U8 addr, val;
342 addr = strtol(argv[1], NULL, 16);
343 val = strtol(argv[2], NULL, 16);
345 chb_reg_write(addr, val);
346 printf_P(PSTR("Write: %04X, %02X.\n"), addr, val);
348 val = chb_reg_read(addr);
349 printf_P(PSTR("Readback: %04X, %02X.\n"), addr, val);
352 /**************************************************************************/
356 /**************************************************************************/
357 static void cmd_reg_dump(U8 argc, char **argv)
359 U8 i, val;
361 for (i=0; i<0x2e; i++)
363 val = chb_reg_read(i);
364 printf_P(PSTR("Reg Read: %04X, %02X.\n"), i, val);
368 /**************************************************************************/
372 /**************************************************************************/
373 static void cmd_tx(U8 argc, char **argv)
375 U8 i, len, *data_ptr, data[50];
376 U16 addr;
378 addr = strtol(argv[1], NULL, 16);
380 data_ptr = data;
381 for (i=0; i<argc-2; i++)
383 len = strlen(argv[i+2]);
384 strcpy((char *)data_ptr, (char *)argv[i+2]);
385 data_ptr += len;
386 *data_ptr++ = ' ';
388 *data_ptr++ = '\0';
390 chb_write(addr, data, data_ptr - data);