diff options
Diffstat (limited to 'firmwares/wifishield/wifiHD/src/console.c')
-rw-r--r-- | firmwares/wifishield/wifiHD/src/console.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/firmwares/wifishield/wifiHD/src/console.c b/firmwares/wifishield/wifiHD/src/console.c new file mode 100644 index 0000000..5ead91e --- /dev/null +++ b/firmwares/wifishield/wifiHD/src/console.c @@ -0,0 +1,212 @@ +/*! \page License + * Copyright (C) 2009, H&D Wireless AB All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of H&D Wireless AB may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY H&D WIRELESS AB ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND + * SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <top_defs.h> +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include <printf-stdarg.h> +#include <console.h> +#include <board_init.h> +#include <usart.h> + +#define MAX_CMD_CONSOLE_NUM 12 +struct { + cmd_cb_t cb; + const char* str; + void* ctx; +} cmd_list[MAX_CMD_CONSOLE_NUM] = { { 0 } }; + +#ifndef CMD_MAX_LEN +#define CMD_MAX_LEN 80 +#endif +extern int board_putchar(char c); +int io_getc(char *c) +{ + int ci; + int status; + status = usart_read_char(&CONFIG_CONSOLE_PORT, &ci); + if (status == USART_RX_EMPTY) + return 1; + + if (status == USART_RX_ERROR) { + CONFIG_CONSOLE_PORT.cr = AVR32_USART_CR_RSTSTA_MASK; + return 1; + } + + if (ci == '\r') { + board_putchar('\n'); + /* Echo char. */ + } else if (ci == '\b') { + board_putchar(ci); + board_putchar(' '); + board_putchar(ci); + } else + board_putchar(ci); + + + *c = ci; + return 0; +} + +static uint8_t is_initialized = 0; + +char* console_gets() +{ + static char buf[CMD_MAX_LEN]; + static int pos = 0; + char c; + + for (;;) { + if (io_getc(&c)) + return NULL; + + if (c == '\r' || c == '\n') { + buf[pos] = 0; + pos = 0; + return buf; + } + if (c == '\b') { + pos -= 1; + if (pos < 0) pos = 0; + buf[pos] = 0; + } + else + buf[pos++] = c; + if (pos == sizeof(buf)) + pos = 0; + } + return NULL; +} + +int console_add_cmd(const char* str, cmd_cb_t cb, void* ctx) +{ + uint32_t i; + for (i = 0; i < ARRAY_SIZE(cmd_list); i++) + if (!cmd_list[i].cb) + break; + + if (i == ARRAY_SIZE(cmd_list)) + return -1; + + cmd_list[i].str = str; + cmd_list[i].cb = cb; + cmd_list[i].ctx = ctx; + return 0; +} + +void console_init(void) +{ + printk("\n$ "); + is_initialized = 1; +} + +void console_init_silent(void) { + is_initialized = 1; +} + +int console_schedule_cmd(char *cmd, int interactive) { +#define MAX_ARGS 16 + static int argc, i; + static char* argv[MAX_ARGS]; + static char *buf; + static enum { INPUT, RUN } state = INPUT; + + switch (state) { + case INPUT: { + char* token; + if (NULL == cmd) { + return 0; + } + buf = strdup(cmd); + if (!buf) + return 0; + if (!strlen(buf)) { + interactive ? printk("$ ") : 0; + free(buf); + return 0; + } +#ifdef WIFI_DEBUG_ON + printk("%s : Scheduling command \"%s\"\n", + __func__, + buf); +#endif + for (i = 0; i < ARRAY_SIZE(cmd_list); i++) + if(cmd_list[i].str && !strncmp(cmd_list[i].str, buf, min(strlen(cmd_list[i].str), strlen(buf)))) + break; + + if (ARRAY_SIZE(cmd_list) == 0) { + printk("No commands available. Is the WiFi card responding?\n"); + } + if (i == ARRAY_SIZE(cmd_list)) { + if (interactive) { + printk("available commands:\n"); + for (i = 0; i < ARRAY_SIZE(cmd_list); i++) + if (cmd_list[i].cb) + printk(" %s\n", cmd_list[i].str); + printk("$ "); + } + free(buf); + return 0; + } + + for (token = strtok(buf, " "); token != NULL; + token = strtok(NULL, " ")) { + argv[argc] = token; + argc++; + if (argc == MAX_ARGS) + break; + } + + state = RUN; + } /* fall through */ + + case RUN: { + cmd_state_t s = cmd_list[i].cb(argc, argv, cmd_list[i].ctx); + if (s == CMD_INPROGRESS) + return 1; + + interactive ? printk("$ ") : 0; + + argc = 0; + memset(argv, 0, sizeof argv); + free(buf); + state = INPUT; + } + } + + return 1; +} + + +void console_poll(void) +{ + char *buf; + buf = console_gets(); + console_schedule_cmd(buf, 1); +} |