From e412390d84e4412c9cdc2a97d7a24eaa8f2ea5f6 Mon Sep 17 00:00:00 2001 From: Thorsten von Eicken Date: Wed, 17 Jun 2015 23:23:24 -0700 Subject: [PATCH] support for dynamically changing gpio pin assignments --- Makefile | 2 +- html/140medley.min.js | 2 +- html/home.tpl | 13 ++++--- html/style.css | 2 +- html/ui.js | 21 +++++++++++ html/wifi/wifi.tpl | 15 -------- serial/serbridge.c | 84 ++++++++++++++++++++++++++----------------- serial/serbridge.h | 3 +- serial/serled.c | 21 ++++++----- serial/serled.h | 2 +- user/cgipins.c | 18 +++++++--- user/status.c | 20 ++++++----- user/status.h | 2 +- user/user_main.c | 6 ++-- 14 files changed, 130 insertions(+), 81 deletions(-) diff --git a/Makefile b/Makefile index f1e2060..27fd4cd 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ XTENSA_TOOLS_ROOT ?= $(abspath ../esp-open-sdk/xtensa-lx106-elf/bin)/ # Base directory of the ESP8266 SDK package, absolute # Typically you'll download from Espressif's BBS, http://bbs.espressif.com/viewforum.php?f=5 -SDK_BASE ?= $(abspath ../esp_iot_sdk_v1.1.0) +SDK_BASE ?= $(abspath ../esp_iot_sdk_v1.1.2p) # Esptool.py path and port, only used for 1-time serial flashing # Typically you'll use https://github.com/themadinventor/esptool diff --git a/html/140medley.min.js b/html/140medley.min.js index 78e620a..675ed59 100644 --- a/html/140medley.min.js +++ b/html/140medley.min.js @@ -1,4 +1,4 @@ -var b=function(a,b,c,d){c=c||document;d=c[b="on"+b];a=c[b]=function(e){d=d&&d(e=e||c.event);return(a=a&&b(e))?b:d};c=this}, +var p=function(a,b,c,d){c=c||document;d=c[b="on"+b];a=c[b]=function(e){d=d&&d(e=e||c.event);return(a=a&&b(e))?b:d};c=this}, m=function(a,b,c){b=document;c=b.createElement("p");c.innerHTML=a;for(a=b.createDocumentFragment();b= c.firstChild;)a.appendChild(b);return a}, $=function(a,b){a=a.match(/^(\W)?(.*)/);return(b||document)["getElement"+(a[1]?a[1]=="#"?"ById":"sByClassName":"sByTagName")](a[2])}, diff --git a/html/home.tpl b/html/home.tpl index 32f02e1..73bb10a 100644 --- a/html/home.tpl +++ b/html/home.tpl @@ -44,10 +44,11 @@ function createInputForPin(pin) { var input = document.createElement("input"); input.type = "radio"; input.name = "pins"; + input.data = pin.name; + input.className = "pin-input"; input.value= pin.value; input.id = "opt-" + pin.value; - input.onclick = "setPins("+pin.value+", '"+pin.name+"')"; - if (currPin == pin.value) input.checked = "1"; + if (currPin == pin.name) input.checked = "1"; var descr = m('"); descr.for = "opt-" + pin.value; @@ -64,6 +65,10 @@ function displayPins(resp) { resp.map.forEach(function(v) { po.appendChild(createInputForPin(v)); }); + var i, inputs = $(".pin-input"); + for (i=0; i diff --git a/html/style.css b/html/style.css index 0765241..78efb8c 100644 --- a/html/style.css +++ b/html/style.css @@ -37,7 +37,7 @@ fieldset fields { } #pin-mux label { display: block; - margin: 0em 0.2em 0em 2em; + margin: 0em 0.2em 0em 1em; width: 90%; } diff --git a/html/ui.js b/html/ui.js index 9054512..aced049 100644 --- a/html/ui.js +++ b/html/ui.js @@ -46,6 +46,25 @@ }(this, this.document)); +//===== Wifi info + +function showWifiInfo(data) { + Object.keys(data).forEach(function(v) { + el = $("#wifi-" + v); + if (el != null) el.innerHTML = data[v]; + }); + $("#wifi-spinner").setAttribute("hidden", ""); + $("#wifi-table").removeAttribute("hidden"); + currAp = data.ssid; +} + +function getWifiInfo() { + ajaxJson('GET', "/wifi/info", showWifiInfo, + function(s, st) { window.setTimeout(getWifiInfo, 1000); }); +} + +//===== Notifications + function showWarning(text) { var el = $("#warning"); el.innerHTML = text; @@ -66,6 +85,8 @@ function showNotification(text) { }, 4000); } +//===== AJAX + function ajaxReq(method, url, ok_cb, err_cb) { var xhr = j(); xhr.open(method, url, true); diff --git a/html/wifi/wifi.tpl b/html/wifi/wifi.tpl index 2173999..946c59d 100644 --- a/html/wifi/wifi.tpl +++ b/html/wifi/wifi.tpl @@ -135,21 +135,6 @@ function scanAPs() { }); } -function showWifiInfo(data) { - Object.keys(data).forEach(function(v) { - el = $("#wifi-" + v); - if (el != null) el.innerHTML = data[v]; - }); - $("#wifi-spinner").setAttribute("hidden", ""); - $("#wifi-table").removeAttribute("hidden"); - currAp = data.ssid; -} - -function getWifiInfo() { - ajaxJson('GET', "info", showWifiInfo, - function(s, st) { window.setTimeout(getWifiInfo, 1000); }); -} - function getStatus() { ajaxJsonSpin("GET", "connstatus", function(data) { if (data.status == "idle" || data.status == "connecting") { diff --git a/serial/serbridge.c b/serial/serbridge.c index 8d8f46e..20a0912 100644 --- a/serial/serbridge.c +++ b/serial/serbridge.c @@ -9,12 +9,12 @@ #include "uart.h" #include "serbridge.h" #include "serled.h" +#include "config.h" #include "console.h" -static uint8_t mcu_reset_pin, mcu_isp_pin; - static struct espconn serbridgeConn; static esp_tcp serbridgeTcp; +static int8_t mcu_reset_pin, mcu_isp_pin; sint8 ICACHE_FLASH_ATTR espbuffsend(serbridgeConnData *conn, const char *data, uint16 len); @@ -147,22 +147,30 @@ telnetUnwrap(uint8_t *inBuf, int len, uint8_t state) case TN_setControl: // switch control line and delay a tad switch (c) { case DTR_ON: - os_printf("MCU reset gpio%d\n", mcu_reset_pin); - GPIO_OUTPUT_SET(mcu_reset_pin, 0); - os_delay_us(100L); + if (mcu_reset_pin >= 0) { + os_printf("MCU reset gpio%d\n", mcu_reset_pin); + GPIO_OUTPUT_SET(mcu_reset_pin, 0); + os_delay_us(100L); + } else os_printf("MCU reset: no pin\n"); break; case DTR_OFF: - GPIO_OUTPUT_SET(mcu_reset_pin, 1); - os_delay_us(100L); + if (mcu_reset_pin >= 0) { + GPIO_OUTPUT_SET(mcu_reset_pin, 1); + os_delay_us(100L); + } break; case RTS_ON: - os_printf("MCU ISP gpio%d\n", mcu_isp_pin); - GPIO_OUTPUT_SET(mcu_isp_pin, 0); - os_delay_us(100L); + if (mcu_isp_pin >= 0) { + os_printf("MCU ISP gpio%d\n", mcu_isp_pin); + GPIO_OUTPUT_SET(mcu_isp_pin, 0); + os_delay_us(100L); + } else os_printf("MCU isp: no pin\n"); break; case RTS_OFF: - GPIO_OUTPUT_SET(mcu_isp_pin, 1); - os_delay_us(100L); + if (mcu_isp_pin >= 0) { + GPIO_OUTPUT_SET(mcu_isp_pin, 1); + os_delay_us(100L); + } break; } state = TN_end; @@ -173,10 +181,12 @@ telnetUnwrap(uint8_t *inBuf, int len, uint8_t state) } void ICACHE_FLASH_ATTR serbridgeReset() { - os_printf("MCU reset gpio%d\n", mcu_reset_pin); - GPIO_OUTPUT_SET(mcu_reset_pin, 0); - os_delay_us(100L); - GPIO_OUTPUT_SET(mcu_reset_pin, 1); + if (mcu_reset_pin >= 0) { + os_printf("MCU reset gpio%d\n", mcu_reset_pin); + GPIO_OUTPUT_SET(mcu_reset_pin, 0); + os_delay_us(100L); + GPIO_OUTPUT_SET(mcu_reset_pin, 1); + } else os_printf("MCU reset: no pin\n"); } @@ -201,13 +211,13 @@ static void ICACHE_FLASH_ATTR serbridgeRecvCb(void *arg, char *data, unsigned sh os_printf("MCU Reset=%d ISP=%d\n", mcu_reset_pin, mcu_isp_pin); os_delay_us(2*1000L); // time for os_printf to happen // send reset to arduino/ARM - GPIO_OUTPUT_SET(mcu_reset_pin, 0); + if (mcu_reset_pin >= 0) GPIO_OUTPUT_SET(mcu_reset_pin, 0); os_delay_us(100L); - GPIO_OUTPUT_SET(mcu_isp_pin, 0); + if (mcu_isp_pin >= 0) GPIO_OUTPUT_SET(mcu_isp_pin, 0); os_delay_us(100L); - GPIO_OUTPUT_SET(mcu_reset_pin, 1); + if (mcu_reset_pin >= 0) GPIO_OUTPUT_SET(mcu_reset_pin, 1); os_delay_us(100L); - GPIO_OUTPUT_SET(mcu_isp_pin, 1); + if (mcu_isp_pin >= 0) GPIO_OUTPUT_SET(mcu_isp_pin, 1); os_delay_us(1000L); conn->conn_mode = cmAVR; @@ -255,9 +265,11 @@ static void ICACHE_FLASH_ATTR serbridgeDisconCb(void *arg) { { if (connData[i].conn_mode == cmAVR) { // send reset to arduino/ARM - GPIO_OUTPUT_SET(mcu_reset_pin, 0); - os_delay_us(100L); - GPIO_OUTPUT_SET(mcu_reset_pin, 1); + if (mcu_reset_pin >= 0) { + GPIO_OUTPUT_SET(mcu_reset_pin, 0); + os_delay_us(100L); + GPIO_OUTPUT_SET(mcu_reset_pin, 1); + } } connData[i].conn = NULL; } @@ -306,8 +318,23 @@ serbridgeUartCb(char *buf, int length) { } } +void ICACHE_FLASH_ATTR serbridgeInitPins() { + mcu_reset_pin = flashConfig.reset_pin; + mcu_isp_pin = flashConfig.isp_pin; + os_printf("Serbridge pins: reset=%d isp=%d\n", mcu_reset_pin, mcu_isp_pin); + + // set both pins to 1 before turning them on so we don't cause a reset + if (mcu_isp_pin >= 0) GPIO_OUTPUT_SET(mcu_isp_pin, 1); + if (mcu_reset_pin >= 0) GPIO_OUTPUT_SET(mcu_reset_pin, 1); + // switch pin mux to make these pins GPIO pins + if (mcu_reset_pin >= 0) makeGpio(mcu_reset_pin); + if (mcu_isp_pin >= 0) makeGpio(mcu_isp_pin); +} + // Start transparent serial bridge TCP server on specified port (typ. 23) -void ICACHE_FLASH_ATTR serbridgeInit(int port, uint8_t reset_pin, uint8_t isp_pin) { +void ICACHE_FLASH_ATTR serbridgeInit(int port) { + serbridgeInitPins(); + int i; for (i = 0; i < MAX_CONN; i++) { connData[i].conn = NULL; @@ -318,15 +345,6 @@ void ICACHE_FLASH_ATTR serbridgeInit(int port, uint8_t reset_pin, uint8_t isp_pi serbridgeTcp.local_port = port; serbridgeConn.proto.tcp = &serbridgeTcp; - mcu_reset_pin = reset_pin; - mcu_isp_pin = isp_pin; - // set both pins to 1 so we don't cause a reset - GPIO_OUTPUT_SET(mcu_isp_pin, 1); - GPIO_OUTPUT_SET(mcu_reset_pin, 1); - // switch pin mux to make these pins GPIO pins - makeGpio(mcu_reset_pin); - makeGpio(mcu_isp_pin); - espconn_regist_connectcb(&serbridgeConn, serbridgeConnectCb); espconn_accept(&serbridgeConn); espconn_tcp_set_max_con_allow(&serbridgeConn, MAX_CONN); diff --git a/serial/serbridge.h b/serial/serbridge.h index bcb3d7a..364f833 100644 --- a/serial/serbridge.h +++ b/serial/serbridge.h @@ -32,7 +32,8 @@ struct serbridgeConnData { uint8_t telnet_state; }; -void ICACHE_FLASH_ATTR serbridgeInit(int port, uint8_t reset_pin, uint8_t isp_pin); +void ICACHE_FLASH_ATTR serbridgeInit(int port); +void ICACHE_FLASH_ATTR serbridgeInitPins(void); void ICACHE_FLASH_ATTR serbridgeUartCb(char *buf, int len); void ICACHE_FLASH_ATTR serbridgeReset(); diff --git a/serial/serled.c b/serial/serled.c index 82390f8..413fa1a 100644 --- a/serial/serled.c +++ b/serial/serled.c @@ -1,15 +1,17 @@ #include +#include #include static ETSTimer serledTimer; -static uint8_t serledPin; static void ICACHE_FLASH_ATTR setSerled(int on) { + int8_t pin = flashConfig.ser_led_pin; + if (pin < 0) return; // disabled // LED is active-low if (on) { - gpio_output_set(0, (1<= 0) { + makeGpio(pin); + gpio_output_set(0, 0, (1<= 0) len += os_sprintf(buff+len, " %s:gpio%d", map_func[f], p); + else len += os_sprintf(buff+len, " %s:n/a", map_func[f]); } len += os_sprintf(buff+len, "\" }"); } @@ -64,7 +70,7 @@ int ICACHE_FLASH_ATTR cgiPinsSet(HttpdConnData *connData) { char buff[128]; int len = httpdFindArg(connData->getArgs, "map", buff, sizeof(buff)); - if (len == 0) { + if (len <= 0) { jsonHeader(connData, 400); return HTTPD_CGI_DONE; } @@ -82,6 +88,10 @@ int ICACHE_FLASH_ATTR cgiPinsSet(HttpdConnData *connData) { flashConfig.conn_led_pin = map[2]; flashConfig.ser_led_pin = map[3]; + serbridgeInitPins(); + serledInit(); + statusInit(); + jsonHeader(connData, 200); return HTTPD_CGI_DONE; } diff --git a/user/status.c b/user/status.c index d469242..4abaf63 100644 --- a/user/status.c +++ b/user/status.c @@ -1,16 +1,18 @@ #include +#include "config.h" +#include "serled.h" #include "cgiwifi.h" -#define LEDGPIO 0 - static ETSTimer ledTimer; static void ICACHE_FLASH_ATTR setLed(int on) { + int8_t pin = flashConfig.conn_led_pin; + if (pin < 0) return; // disabled // LED is active-low if (on) { - gpio_output_set(0, (1<= 0) { + makeGpio(flashConfig.conn_led_pin); + setLed(1); + } + os_printf("CONN led=%d\n", flashConfig.conn_led_pin); os_timer_disarm(&ledTimer); os_timer_setfn(&ledTimer, ledTimerCb, NULL); diff --git a/user/status.h b/user/status.h index 4ce8b02..0f89edf 100644 --- a/user/status.h +++ b/user/status.h @@ -2,7 +2,7 @@ #define STATUS_H void statusWifiUpdate(uint8_t state); -void statusInit(uint8_t pin); +void statusInit(void); #endif diff --git a/user/user_main.c b/user/user_main.c index 98aa550..e6b40ec 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -122,8 +122,8 @@ void user_init(void) { # define VERS_STR(V) VERS_STR_STR(V) os_printf("\n\nInitializing esp-link\n" VERS_STR(VERSION) "\n"); // Status LEDs - statusInit(LED_CONN_PIN); - serledInit(LED_SERIAL_PIN); + statusInit(); + serledInit(); logInit(); // Wifi wifiInit(); @@ -133,7 +133,7 @@ void user_init(void) { // mount the http handlers httpdInit(builtInUrls, 80); // init the wifi-serial transparent bridge (port 23) - serbridgeInit(23, MCU_RESET_PIN, MCU_ISP_PIN); + serbridgeInit(23); uart_add_recv_cb(&serbridgeUartCb); #ifdef SHOW_HEAP_USE os_timer_disarm(&prHeapTimer);