diff --git a/html/cats/cross-eyed-cat.jpg b/html/cats/cross-eyed-cat.jpg
new file mode 100644
index 0000000..72deba6
Binary files /dev/null and b/html/cats/cross-eyed-cat.jpg differ
diff --git a/html/cats/junge-katze-iv.jpg b/html/cats/junge-katze-iv.jpg
new file mode 100644
index 0000000..803bbb0
Binary files /dev/null and b/html/cats/junge-katze-iv.jpg differ
diff --git a/html/cats/kitten-loves-toy.jpg b/html/cats/kitten-loves-toy.jpg
new file mode 100644
index 0000000..8965447
Binary files /dev/null and b/html/cats/kitten-loves-toy.jpg differ
diff --git a/html/index.html b/html/index.html
new file mode 100644
index 0000000..dbfb47a
--- /dev/null
+++ b/html/index.html
@@ -0,0 +1,19 @@
+
+
Esp8266 web server
+
+it Works
+
+If you see this, it means the tiny li'l website in your ESP8266 does actually work.
+
+- If you haven't connected this device to your WLAN network now, you can do so.
+- You can also control the LED.
+- And because I can, here's a link to my website
+
+
+
+And because we're on the Internets now, here are the required pictures of some cats:
+
+
+
+
+
diff --git a/html/led.tpl b/html/led.tpl
new file mode 100644
index 0000000..2290d60
--- /dev/null
+++ b/html/led.tpl
@@ -0,0 +1,12 @@
+Test
+
+
+
+If there's a LED connected to GPIO2, it's now %ledstate%. You can change that using the buttons below.
+
+
+
+
diff --git a/include/uart_hw.h b/include/uart_hw.h
new file mode 100644
index 0000000..183e694
--- /dev/null
+++ b/include/uart_hw.h
@@ -0,0 +1,195 @@
+//Generated at 2012-07-03 18:44:06
+/*
+ * Copyright (c) 2010 - 2011 Espressif System
+ *
+ */
+
+#ifndef UART_REGISTER_H_INCLUDED
+#define UART_REGISTER_H_INCLUDED
+#define REG_UART_BASE( i ) (0x60000000+(i)*0xf00)
+//version value:32'h062000
+
+#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0)
+#define UART_RXFIFO_RD_BYTE 0x000000FF
+#define UART_RXFIFO_RD_BYTE_S 0
+
+#define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4)
+#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
+#define UART_BRK_DET_INT_RAW (BIT(7))
+#define UART_CTS_CHG_INT_RAW (BIT(6))
+#define UART_DSR_CHG_INT_RAW (BIT(5))
+#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
+#define UART_FRM_ERR_INT_RAW (BIT(3))
+#define UART_PARITY_ERR_INT_RAW (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
+#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
+
+#define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8)
+#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
+#define UART_BRK_DET_INT_ST (BIT(7))
+#define UART_CTS_CHG_INT_ST (BIT(6))
+#define UART_DSR_CHG_INT_ST (BIT(5))
+#define UART_RXFIFO_OVF_INT_ST (BIT(4))
+#define UART_FRM_ERR_INT_ST (BIT(3))
+#define UART_PARITY_ERR_INT_ST (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
+#define UART_RXFIFO_FULL_INT_ST (BIT(0))
+
+#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC)
+#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
+#define UART_BRK_DET_INT_ENA (BIT(7))
+#define UART_CTS_CHG_INT_ENA (BIT(6))
+#define UART_DSR_CHG_INT_ENA (BIT(5))
+#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
+#define UART_FRM_ERR_INT_ENA (BIT(3))
+#define UART_PARITY_ERR_INT_ENA (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
+#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
+
+#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10)
+#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
+#define UART_BRK_DET_INT_CLR (BIT(7))
+#define UART_CTS_CHG_INT_CLR (BIT(6))
+#define UART_DSR_CHG_INT_CLR (BIT(5))
+#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
+#define UART_FRM_ERR_INT_CLR (BIT(3))
+#define UART_PARITY_ERR_INT_CLR (BIT(2))
+#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
+#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
+
+#define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14)
+#define UART_CLKDIV_CNT 0x000FFFFF
+#define UART_CLKDIV_S 0
+
+#define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18)
+#define UART_GLITCH_FILT 0x000000FF
+#define UART_GLITCH_FILT_S 8
+#define UART_AUTOBAUD_EN (BIT(0))
+
+#define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C)
+#define UART_TXD (BIT(31))
+#define UART_RTSN (BIT(30))
+#define UART_DTRN (BIT(29))
+#define UART_TXFIFO_CNT 0x000000FF
+#define UART_TXFIFO_CNT_S 16
+#define UART_RXD (BIT(15))
+#define UART_CTSN (BIT(14))
+#define UART_DSRN (BIT(13))
+#define UART_RXFIFO_CNT 0x000000FF
+#define UART_RXFIFO_CNT_S 0
+
+#define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20)
+#define UART_TXFIFO_RST (BIT(18))
+#define UART_RXFIFO_RST (BIT(17))
+#define UART_IRDA_EN (BIT(16))
+#define UART_TX_FLOW_EN (BIT(15))
+#define UART_LOOPBACK (BIT(14))
+#define UART_IRDA_RX_INV (BIT(13))
+#define UART_IRDA_TX_INV (BIT(12))
+#define UART_IRDA_WCTL (BIT(11))
+#define UART_IRDA_TX_EN (BIT(10))
+#define UART_IRDA_DPLX (BIT(9))
+#define UART_TXD_BRK (BIT(8))
+#define UART_SW_DTR (BIT(7))
+#define UART_SW_RTS (BIT(6))
+#define UART_STOP_BIT_NUM 0x00000003
+#define UART_STOP_BIT_NUM_S 4
+#define UART_BIT_NUM 0x00000003
+#define UART_BIT_NUM_S 2
+#define UART_PARITY_EN (BIT(1))
+#define UART_PARITY (BIT(0))
+
+#define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24)
+#define UART_RX_TOUT_EN (BIT(31))
+#define UART_RX_TOUT_THRHD 0x0000007F
+#define UART_RX_TOUT_THRHD_S 24
+#define UART_RX_FLOW_EN (BIT(23))
+#define UART_RX_FLOW_THRHD 0x0000007F
+#define UART_RX_FLOW_THRHD_S 16
+#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
+#define UART_TXFIFO_EMPTY_THRHD_S 8
+#define UART_RXFIFO_FULL_THRHD 0x0000007F
+#define UART_RXFIFO_FULL_THRHD_S 0
+
+#define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28)
+#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
+#define UART_LOWPULSE_MIN_CNT_S 0
+
+#define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C)
+#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
+#define UART_HIGHPULSE_MIN_CNT_S 0
+
+#define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30)
+#define UART_PULSE_NUM_CNT 0x0003FF
+#define UART_PULSE_NUM_CNT_S 0
+
+#define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78)
+#define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C)
+#endif // UART_REGISTER_H_INCLUDED
+
+#define RX_BUFF_SIZE 256
+#define TX_BUFF_SIZE 100
+#define UART0 0
+#define UART1 1
+
+typedef enum {
+ FIVE_BITS = 0x0,
+ SIX_BITS = 0x1,
+ SEVEN_BITS = 0x2,
+ EIGHT_BITS = 0x3
+} UartBitsNum4Char;
+
+typedef enum {
+ ONE_STOP_BIT = 0,
+ ONE_HALF_STOP_BIT = BIT2,
+ TWO_STOP_BIT = BIT2
+} UartStopBitsNum;
+
+typedef enum {
+ NONE_BITS = 0,
+ ODD_BITS = 0,
+ EVEN_BITS = BIT4
+} UartParityMode;
+
+typedef enum {
+ STICK_PARITY_DIS = 0,
+ STICK_PARITY_EN = BIT3 | BIT5
+} UartExistParity;
+
+typedef enum {
+ BIT_RATE_9600 = 9600,
+ BIT_RATE_19200 = 19200,
+ BIT_RATE_38400 = 38400,
+ BIT_RATE_57600 = 57600,
+ BIT_RATE_74880 = 74880,
+ BIT_RATE_115200 = 115200,
+ BIT_RATE_230400 = 230400,
+ BIT_RATE_460800 = 460800,
+ BIT_RATE_921600 = 921600
+} UartBautRate;
+
+typedef enum {
+ NONE_CTRL,
+ HARDWARE_CTRL,
+ XON_XOFF_CTRL
+} UartFlowCtrl;
+
+typedef enum {
+ EMPTY,
+ UNDER_WRITE,
+ WRITE_OVER
+} RcvMsgBuffState;
+
+typedef struct {
+ uint32 TrxBuffSize;
+ uint8 *pTrxBuff;
+} TrxMsgBuff;
+
+typedef enum {
+ BAUD_RATE_DET,
+ WAIT_SYNC_FRM,
+ SRCH_MSG_HEAD,
+ RCV_MSG_BODY,
+ RCV_ESC_CHAR,
+} RcvMsgState;
+
diff --git a/user/cgiwifi.c b/user/cgiwifi.c
new file mode 100644
index 0000000..36529b6
--- /dev/null
+++ b/user/cgiwifi.c
@@ -0,0 +1,216 @@
+/*
+Cgi/template routines for the /wifi url.
+*/
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Jeroen Domburg wrote this file. As long as you retain
+ * this notice you can do whatever you want with this stuff. If we meet some day,
+ * and you think this stuff is worth it, you can buy me a beer in return.
+ * ----------------------------------------------------------------------------
+ */
+
+
+#include
+#include
+#include "user_interface.h"
+#include "mem.h"
+#include "httpd.h"
+#include "cgi.h"
+#include "io.h"
+#include "espmissingincludes.h"
+
+//WiFi access point data
+typedef struct {
+ char ssid[32];
+ char rssi;
+ char enc;
+} ApData;
+
+//Scan resolt
+typedef struct {
+ char scanInProgress;
+ ApData **apData;
+ int noAps;
+} ScanResultData;
+
+//Static scan status storage.
+ScanResultData cgiWifiAps;
+
+//Callback the code calls when a wlan ap scan is done. Basically stores the result in
+//the cgiWifiAps struct.
+void ICACHE_FLASH_ATTR wifiScanDoneCb(void *arg, STATUS status) {
+ int n;
+ struct bss_info *bss_link = (struct bss_info *)arg;
+ os_printf("wifiScanDoneCb %d\n", status);
+ if (status!=OK) {
+ cgiWifiAps.scanInProgress=0;
+ wifi_station_disconnect(); //test HACK
+ return;
+ }
+
+ //Clear prev ap data if needed.
+ if (cgiWifiAps.apData!=NULL) {
+ for (n=0; nnext.stqe_next;
+ n++;
+ }
+ //Allocate memory for access point data
+ cgiWifiAps.apData=(ApData **)os_malloc(sizeof(ApData *)*n);
+ cgiWifiAps.noAps=n;
+
+ //Copy access point data to the static struct
+ n=0;
+ bss_link = (struct bss_info *)arg;
+ while (bss_link != NULL) {
+ cgiWifiAps.apData[n]=(ApData *)os_malloc(sizeof(ApData));
+ cgiWifiAps.apData[n]->rssi=bss_link->rssi;
+ cgiWifiAps.apData[n]->enc=bss_link->authmode;
+ strncpy(cgiWifiAps.apData[n]->ssid, (char*)bss_link->ssid, 32);
+
+ bss_link = bss_link->next.stqe_next;
+ n++;
+ }
+ os_printf("Scan done: found %d APs\n", n);
+ //We're done.
+ cgiWifiAps.scanInProgress=0;
+}
+
+
+//Routine to start a WiFi access point scan.
+static void ICACHE_FLASH_ATTR wifiStartScan() {
+ int x;
+ cgiWifiAps.scanInProgress=1;
+ x=wifi_station_get_connect_status();
+ if (x!=STATION_GOT_IP) {
+ //Unit probably is trying to connect to a bogus AP. This messes up scanning. Stop that.
+ os_printf("STA status = %d. Disconnecting STA...\n", x);
+ wifi_station_disconnect();
+ }
+ wifi_station_scan(NULL, wifiScanDoneCb);
+}
+
+//This CGI is called from the bit of AJAX-code in wifi.tpl. It will initiate a
+//scan for access points and if available will return the result of an earlier scan.
+//The result is embedded in a bit of JSON parsed by the javascript in wifi.tpl.
+int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) {
+ int len;
+ int i;
+ char buff[1024];
+ httpdStartResponse(connData, 200);
+ httpdHeader(connData, "Content-Type", "text/json");
+ httpdEndHeaders(connData);
+
+ if (cgiWifiAps.scanInProgress==1) {
+ len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n");
+ espconn_sent(connData->conn, (uint8 *)buff, len);
+ } else {
+ len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n");
+ espconn_sent(connData->conn, (uint8 *)buff, len);
+ if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0;
+ for (i=0; issid, cgiWifiAps.apData[i]->rssi,
+ cgiWifiAps.apData[i]->enc, (i==cgiWifiAps.noAps-1)?"":",");
+ espconn_sent(connData->conn, (uint8 *)buff, len);
+ }
+ len=os_sprintf(buff, "]\n}\n}\n");
+ espconn_sent(connData->conn, (uint8 *)buff, len);
+ wifiStartScan();
+ }
+ return HTTPD_CGI_DONE;
+}
+
+//Temp store for new ap info.
+static struct station_config stconf;
+
+//This routine is ran some time after a connection attempt to an access point. If
+//the connect succeeds, this gets the module in STA-only mode.
+static void ICACHE_FLASH_ATTR resetTimerCb(void *arg) {
+ int x=wifi_station_get_connect_status();
+ if (x==STATION_GOT_IP) {
+ //Go to STA mode. This needs a reset, so do that.
+ wifi_set_opmode(1);
+ system_restart();
+ } else {
+ os_printf("Connect fail. Not going into STA-only mode.\n");
+ }
+}
+
+//Actually connect to a station. This routine is timed because I had problems
+//with immediate connections earlier. It probably was something else that caused it,
+//but I can't be arsed to put the code back :P
+static void ICACHE_FLASH_ATTR reassTimerCb(void *arg) {
+ int x;
+ static ETSTimer resetTimer;
+ wifi_station_disconnect();
+ wifi_station_set_config(&stconf);
+ wifi_station_connect();
+ x=wifi_get_opmode();
+ if (x!=1) {
+ //Schedule disconnect/connect
+ os_timer_disarm(&resetTimer);
+ os_timer_setfn(&resetTimer, resetTimerCb, NULL);
+ os_timer_arm(&resetTimer, 4000, 0);
+ }
+}
+
+
+//This cgi uses the routines above to connect to a specific access point with the
+//given ESSID using the given password.
+int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
+ char essid[128];
+ char passwd[128];
+ static ETSTimer reassTimer;
+
+ if (connData->conn==NULL) {
+ //Connection aborted. Clean up.
+ return HTTPD_CGI_DONE;
+ }
+
+ httpdFindArg(connData->postBuff, "essid", essid, sizeof(essid));
+ httpdFindArg(connData->postBuff, "passwd", passwd, sizeof(passwd));
+
+ os_strncpy((char*)stconf.ssid, essid, 32);
+ os_strncpy((char*)stconf.password, passwd, 64);
+
+ //Schedule disconnect/connect
+ os_timer_disarm(&reassTimer);
+ os_timer_setfn(&reassTimer, reassTimerCb, NULL);
+ os_timer_arm(&reassTimer, 1000, 0);
+
+ httpdRedirect(connData, "connecting.html");
+
+ return HTTPD_CGI_DONE;
+}
+
+//Template code for the WLAN page.
+void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) {
+ char buff[1024];
+ int x;
+ static struct station_config stconf;
+ if (token==NULL) return;
+ wifi_station_get_config(&stconf);
+
+ os_strcpy(buff, "Unknown");
+ if (os_strcmp(token, "WiFiMode")==0) {
+ x=wifi_get_opmode();
+ if (x==1) os_strcpy(buff, "Client");
+ if (x==2) os_strcpy(buff, "SoftAP");
+ if (x==3) os_strcpy(buff, "STA+AP");
+ } else if (os_strcmp(token, "currSsid")==0) {
+ os_strcpy(buff, (char*)stconf.ssid);
+ } else if (os_strcmp(token, "WiFiPasswd")==0) {
+ os_strcpy(buff, (char*)stconf.password);
+ }
+ espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff));
+}
+
+
diff --git a/user/cgiwifi.h b/user/cgiwifi.h
new file mode 100644
index 0000000..91c1992
--- /dev/null
+++ b/user/cgiwifi.h
@@ -0,0 +1,11 @@
+#ifndef CGIWIFI_H
+#define CGIWIFI_H
+
+#include "httpd.h"
+
+int cgiWiFiScan(HttpdConnData *connData);
+void tplWlan(HttpdConnData *connData, char *token, void **arg);
+int cgiWiFi(HttpdConnData *connData);
+int cgiWiFiConnect(HttpdConnData *connData);
+
+#endif
\ No newline at end of file
diff --git a/user/stdout.c b/user/stdout.c
new file mode 100644
index 0000000..68efd54
--- /dev/null
+++ b/user/stdout.c
@@ -0,0 +1,50 @@
+//Stupid bit of code that does the bare minimum to make os_printf work.
+
+/*
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * Jeroen Domburg wrote this file. As long as you retain
+ * this notice you can do whatever you want with this stuff. If we meet some day,
+ * and you think this stuff is worth it, you can buy me a beer in return.
+ * ----------------------------------------------------------------------------
+ */
+
+
+#include "espmissingincludes.h"
+#include "ets_sys.h"
+#include "osapi.h"
+#include "uart_hw.h"
+
+static void ICACHE_FLASH_ATTR stdoutUartTxd(char c) {
+ //Wait until there is room in the FIFO
+ while (((READ_PERI_REG(UART_STATUS(0))>>UART_TXFIFO_CNT_S)&UART_TXFIFO_CNT)>=126) ;
+ //Send the character
+ WRITE_PERI_REG(UART_FIFO(0), c);
+}
+
+static void ICACHE_FLASH_ATTR stdoutPutchar(char c) {
+ //convert \n -> \r\n
+ if (c=='\n') stdoutUartTxd('\r');
+ stdoutUartTxd(c);
+}
+
+
+void stdoutInit() {
+ //Enable TxD pin
+ PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
+
+ //Set baud rate and other serial parameters to 115200,n,8,1
+ uart_div_modify(0, UART_CLK_FREQ/BIT_RATE_115200);
+ WRITE_PERI_REG(UART_CONF0(0), (STICK_PARITY_DIS)|(ONE_STOP_BIT << UART_STOP_BIT_NUM_S)| \
+ (EIGHT_BITS << UART_BIT_NUM_S));
+
+ //Reset tx & rx fifo
+ SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST);
+ CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST|UART_TXFIFO_RST);
+ //Clear pending interrupts
+ WRITE_PERI_REG(UART_INT_CLR(0), 0xffff);
+
+ //Install our own putchar handler
+ os_install_putc1((void *)stdoutPutchar);
+}
\ No newline at end of file
diff --git a/user/stdout.h b/user/stdout.h
new file mode 100644
index 0000000..589da44
--- /dev/null
+++ b/user/stdout.h
@@ -0,0 +1 @@
+void stdoutInit();