aboutsummaryrefslogtreecommitdiff
path: root/firmwares/wifishield/wifiHD/src/main.c
diff options
context:
space:
mode:
authorDavid A. Mellis <d.mellis@arduino.cc>2012-09-13 10:42:25 -0400
committerDavid A. Mellis <d.mellis@arduino.cc>2012-09-13 10:42:25 -0400
commitbd45bf50c7c68ec35c3aad8c5e7bf4d3db9cafc1 (patch)
treec02065cc7b15ce5f0a8eaa9f0030a268b37c89bb /firmwares/wifishield/wifiHD/src/main.c
parent6225a8596005bfb0be68fa641f5b47d01a95c12d (diff)
parent0d9a111face4f3629bcae8e52af843792af3b453 (diff)
Merge branch 'master' of ../wifishield
Diffstat (limited to 'firmwares/wifishield/wifiHD/src/main.c')
-rw-r--r--firmwares/wifishield/wifiHD/src/main.c455
1 files changed, 455 insertions, 0 deletions
diff --git a/firmwares/wifishield/wifiHD/src/main.c b/firmwares/wifishield/wifiHD/src/main.c
new file mode 100644
index 0000000..8961e35
--- /dev/null
+++ b/firmwares/wifishield/wifiHD/src/main.c
@@ -0,0 +1,455 @@
+/*
+ * main.c
+ *
+ * Created on: May 27, 2010
+ * Author: mlf by Metodo2 srl
+ */
+
+//#define _TEST_SPI_
+
+#include <compiler.h>
+#include "board.h"
+#include "gpio.h"
+
+#include <stdint.h>
+#include "wl_api.h"
+#include "wl_cm.h"
+
+#include "lwip/init.h"
+#include "lwip/dhcp.h"
+#include "lwip/dns.h"
+#include "lwip/tcp.h"
+#include "netif/etharp.h"
+#include "netif/wlif.h"
+
+#include "board_init.h"
+#include "trace.h"
+
+#include "timer.h"
+#include "util.h"
+#include "cmd_wl.h"
+#include "ping.h"
+#include "ard_tcp.h"
+#include "spi.h"
+#include "ard_spi.h"
+#include "delay.h"
+#include "tc.h"
+#include "debug.h"
+#include "ard_utils.h"
+#include <lwip_setup.h>
+
+/* FIRMWARE version */
+const char* fwVersion = "1.0.0";
+
+#if BOARD == ARDUINO
+#if !defined(DATAFLASH)
+#include "wl_fw.h"
+
+int fw_download_init(void) { return 0;}
+void fw_download_cb(void* ctx, uint8_t** buf, uint32_t* len)
+{
+ //printk("Fw download not available!\n");
+ /* remember accross different calls */
+ static uint8_t* _fw_buf = (uint8_t*)&fw_buf[0];
+ static uint32_t offset = 0;
+
+ /* when firmware download is completed, this function will be invoked
+ * on additional time with the input value of len set to 0. we can free
+ * the firmware buffer at this time since it's no longer needed.
+ */
+ if (*len == 0) {
+ return;
+ }
+
+ /* decide how much to read. we know *len bytes remains, but we only have
+ * room for SECTOR_SIEZ bytes in our buffer (fw_buf)
+ */
+ uint32_t fw_len = *len;
+
+ *buf = (_fw_buf+offset);
+ *len = fw_len;
+
+ /* we need to know where to start reading upon next call */
+ offset += fw_len;
+
+}
+#else
+#include "fw_download.h"
+#endif
+#endif
+
+struct ctx_server {
+ struct net_cfg net_cfg;
+ uint8_t wl_init_complete;
+};
+
+bool ifStatus = false;
+bool scanNetCompleted = false;
+
+static bool initSpiComplete = false;
+
+// variable used as enable flag for debug prints
+#ifdef _DEBUG_
+uint16_t enableDebug = DEFAULT_INFO_FLAG | INFO_WARN_FLAG;// | INFO_SPI_FLAG;
+uint16_t verboseDebug = 0;
+#else
+uint16_t enableDebug = DEFAULT_INFO_FLAG;
+uint16_t verboseDebug = 0;
+#endif
+
+
+/**
+ *
+ */
+static void
+wl_cm_scan_cb(void* ctx)
+{
+ INFO_INIT("Scan Completed!\n");
+ scanNetCompleted=true;
+}
+
+/**
+ *
+ */
+static void
+wl_cm_conn_cb(struct wl_network_t* net, void* ctx)
+{
+ struct ctx_server* hs = ctx;
+
+ LINK_LED_ON();
+
+ INFO_INIT("Connection cb...\n");
+
+ printk("link up, connected to \"%s\"\n", ssid2str(&net->ssid));
+ if ( hs->net_cfg.dhcp_enabled ) {
+ INFO_INIT("Start DHCP...\n");
+ printk("requesting dhcp ... ");
+ int8_t result = dhcp_start(hs->net_cfg.netif);
+ printk((result==ERR_OK)?"OK\n":"FAILED\n");
+ hs->net_cfg.dhcp_running = 1;
+ }
+ else {
+ netif_set_up(hs->net_cfg.netif);
+ }
+
+ INFO_INIT("Start DNS...\n");
+ dns_init();
+}
+
+
+/**
+ *
+ */
+static void
+wl_cm_disconn_cb(void* ctx)
+{
+ struct ctx_server* hs = ctx;
+
+ LINK_LED_OFF();
+ INFO_INIT("Disconnection cb...\n");
+
+ if (hs->net_cfg.dhcp_running) {
+ printk("link down, release dhcp\n");
+ dhcp_release(hs->net_cfg.netif);
+ dhcp_stop(hs->net_cfg.netif);
+ hs->net_cfg.dhcp_running = 0;
+ } else {
+ printk("link down\n");
+ netif_set_down(hs->net_cfg.netif);
+ }
+
+ set_result_cmd(WL_FAILURE);
+}
+
+#if 0
+static void wl_cm_err_cb(void* ctx)
+{
+ int err = *(int*)ctx;
+ WARN("Error: %d\n", err);
+ set_result_cmd(err);
+}
+#endif
+
+/**
+ *
+ */
+static void
+ip_status_cb(struct netif* netif)
+{
+ INFO_INIT("IP status cb...\n");
+ if (netif_is_up(netif)) {
+ set_result_cmd(WL_SUCCESS);
+ printk("bound to %s\n", ip2str(netif->ip_addr));
+ ifStatus = true;
+ }else{
+ ifStatus = false;
+ closeConnections();
+ WARN("Interface not up!\n");
+ }
+}
+
+
+/**
+ *
+ */
+void
+led_init(void)
+{
+ gpio_enable_gpio_pin(LED0_GPIO);
+ gpio_enable_gpio_pin(LED1_GPIO);
+ gpio_enable_gpio_pin(LED2_GPIO);
+ LINK_LED_OFF();
+ ERROR_LED_OFF();
+ DATA_LED_OFF();
+}
+
+
+void tc_init(void)
+{
+ // The timer/counter instance and channel number are used in several functions.
+ // It's defined as local variable for ease-of-use causes and readability.
+ volatile avr32_tc_t *tc = WIFI_TC;
+
+ // Options for waveform genration.
+ tc_waveform_opt_t waveform_opt =
+ {
+ .channel = WIFI_TC_CHANNEL_ID, // Channel selection.
+
+ .bswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOB.
+ .beevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOB.
+ .bcpc = TC_EVT_EFFECT_NOOP, // RC compare effect on TIOB.
+ .bcpb = TC_EVT_EFFECT_NOOP, // RB compare effect on TIOB.
+
+ .aswtrg = TC_EVT_EFFECT_NOOP, // Software trigger effect on TIOA.
+ .aeevt = TC_EVT_EFFECT_NOOP, // External event effect on TIOA.
+ .acpc = TC_EVT_EFFECT_TOGGLE, // RC compare effect on TIOA: toggle.
+ .acpa = TC_EVT_EFFECT_TOGGLE, // RA compare effect on TIOA: toggle (other possibilities are none, set and clear).
+
+ .wavsel = TC_WAVEFORM_SEL_UP_MODE_RC_TRIGGER,// Waveform selection: Up mode with automatic trigger(reset) on RC compare.
+ .enetrg = FALSE, // External event trigger enable.
+ .eevt = TC_EXT_EVENT_SEL_TIOB_INPUT, // External event selection.
+ .eevtedg = TC_SEL_NO_EDGE, // External event edge selection.
+ .cpcdis = FALSE, // Counter disable when RC compare.
+ .cpcstop = FALSE, // Counter clock stopped with RC compare.
+
+ .burst = TC_BURST_NOT_GATED, // Burst signal selection.
+ .clki = TC_CLOCK_RISING_EDGE, // Clock inversion.
+ .tcclks = TC_CLOCK_SOURCE_TC2 // Internal source clock 3, connected to fPBA / 2.
+ };
+
+ // Assign I/O to timer/counter channel pin & function.
+ gpio_enable_module_pin(WIFI_TC_CHANNEL_PIN, WIFI_TC_CHANNEL_FUNCTION);
+
+ // Initialize the timer/counter.
+ tc_init_waveform(tc, &waveform_opt); // Initialize the timer/counter waveform.
+
+ // Set the compare triggers.
+ tc_write_ra(tc, WIFI_TC_CHANNEL_ID, 0x01A4); // Set RA value.
+ tc_write_rc(tc, WIFI_TC_CHANNEL_ID, 0x0348); // Set RC value.
+
+ // Start the timer/counter.
+ tc_start(tc, WIFI_TC_CHANNEL_ID);
+
+}
+
+/**
+ *
+ */
+void
+poll(struct ctx_server* hs)
+{
+ /* this will trigger any scheduled timer callbacks */
+ timer_poll();
+
+ /* handle console input */
+ console_poll();
+
+ /* wl api 'tick' */
+ wl_tick(timer_get_ms());
+
+ /* lwip driver poll */
+ wlif_poll(hs->net_cfg.netif);
+
+ if (initSpiComplete) spi_poll(hs->net_cfg.netif);
+
+#ifdef WITH_GUI
+ gui_exec(timer_get_ms());
+#endif
+}
+
+void initShell()
+{
+ /* initialize shell */
+ INFO_INIT("Shell init...\n");
+ console_init();
+ console_add_cmd("scan", cmd_scan, NULL);
+ console_add_cmd("connect", cmd_connect, NULL);
+ console_add_cmd("setkey", cmd_setkey, NULL);
+ console_add_cmd("status", cmd_status, NULL);
+ console_add_cmd("debug", cmd_debug, NULL);
+
+#ifdef ADD_CMDS
+ console_add_cmd("powersave", cmd_power, NULL);
+ console_add_cmd("psconf", cmd_psconf, NULL);
+#endif
+#ifdef PING_CMD
+ console_add_cmd("ping", cmd_ping, NULL);
+#endif
+ console_add_cmd("ttcp", cmd_ttcp, NULL);
+#ifdef WITH_WPA
+ console_add_cmd("wpass", cmd_setpass, NULL);
+ console_add_cmd("dpass", cmd_delpass, NULL);
+#endif
+#ifdef _SPI_STATS_
+ console_add_cmd("spiStat", cmd_statSpi, NULL);
+ console_add_cmd("resetSpiStat", cmd_resetStatSpi, NULL);
+#endif
+#ifdef _DNS_CMD_
+ console_add_cmd("getHost", cmd_gethostbyname, NULL);
+ console_add_cmd("setDNS", cmd_setDnsServer, NULL);
+ console_add_cmd("startTcpSrv", cmd_startTcpSrv, NULL);
+#endif
+}
+
+/**
+ *
+ */
+void
+wl_init_complete_cb(void* ctx)
+{
+ struct ctx_server *hs = ctx;
+ struct ip_addr ipaddr, netmask, gw;
+ wl_err_t wl_status;
+
+ IP4_ADDR(&gw, 0,0,0,0);
+ IP4_ADDR(&ipaddr, 0,0,0,0);
+ IP4_ADDR(&netmask, 0,0,0,0);
+
+ /* default is dhcp enabled */
+ hs->net_cfg.dhcp_enabled = 1;
+ start_ip_stack(&hs->net_cfg,
+ ipaddr,
+ netmask,
+ gw);
+ netif_set_status_callback(hs->net_cfg.netif, ip_status_cb);
+
+ INFO_INIT("Starting CM...\n");
+ /* start connection manager */
+ wl_status = wl_cm_init(wl_cm_scan_cb, wl_cm_conn_cb, wl_cm_disconn_cb, hs);
+ ASSERT(wl_status == WL_SUCCESS, "failed to init wl conn mgr");
+ wl_cm_start();
+
+ wl_scan();
+
+ if (initSpi()){
+ WARN("Spi not initialized\n");
+ }else
+ {
+ initSpiComplete = true;
+ AVAIL_FOR_SPI();
+ }
+
+ hs->wl_init_complete = 1;
+}
+
+void startup_init(void)
+{
+ INIT_SIGNAL_FOR_SPI();
+ BUSY_FOR_SPI();
+
+ // if DEBUG enabled use DEB_PIN_GPIO for debug purposes
+ DEB_PIN_ENA();
+ DEB_PIN_UP();
+}
+
+/**
+ *
+ */
+int
+main(void)
+{
+ wl_err_t wl_status;
+ int status;
+ struct ctx_server *hs;
+ enum wl_host_attention_mode mode;
+
+ startup_init();
+
+ board_init();
+
+ led_init();
+
+ tc_init();
+
+ initShell();
+
+ delay_init(FOSC0);
+
+#ifdef _TEST_SPI_
+ for (;;)
+ {
+ /* handle console input */
+
+ console_poll();
+
+ spi_poll(NULL);
+
+ }
+#else
+ printk("Arduino Wifi Startup... [%s]\n", __TIMESTAMP__);
+
+ size_t size_ctx_server = sizeof(struct ctx_server);
+ hs = calloc(1, size_ctx_server);
+ ASSERT(hs, "out of memory");
+
+ size_t size_netif = sizeof(struct netif);
+ hs->net_cfg.netif = calloc(1, size_netif);
+ ASSERT(hs->net_cfg.netif, "out of memory");
+
+ INFO_INIT("hs:%p size:0x%x netif:%p size:0x%x\n", hs, size_ctx_server,
+ hs->net_cfg.netif, size_netif);
+
+ timer_init(NULL, NULL);
+ lwip_init();
+
+ status = fw_download_init();
+ ASSERT(status == 0, "failed to prepare for firmware download\n");
+
+ wl_status = wl_transport_init(fw_read_cb, hs, &mode);
+ if (wl_status != WL_SUCCESS)
+ goto err;
+ INFO_INIT("Mode: 0x%x\n", mode);
+ wl_status = wl_init(hs, wl_init_complete_cb, mode);
+ if (wl_status != WL_SUCCESS)
+ goto err;
+
+ /* start main loop */
+ for (;;)
+ poll(hs);
+
+
+err:
+ /* show error message on console and display if wlan initialization fails */
+
+#define WL_CARD_FAILURE_STR "Could not detect wl device, aborting\n"
+#define WL_FIRMWARE_INVALID_STR "Invalid firmware data, aborting\n"
+#define WL_OTHER_FAILURE_STR "Failed to start wl initialization\n"
+
+ switch (wl_status) {
+ case WL_CARD_FAILURE:
+ printk(WL_CARD_FAILURE_STR);
+ break;
+
+ case WL_FIRMWARE_INVALID:
+ printk(WL_FIRMWARE_INVALID_STR);
+ break;
+
+ default:
+ printk(WL_OTHER_FAILURE_STR);
+ break;
+ }
+ for (;;) {
+ timer_poll();
+ }
+#endif
+}