#include "project.h" static struct gpio { int id; uint32_t pin; uint32_t func; uint32_t bit; int pull; } gpios[] = { { 0, PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0, BIT0, 1}, { 2, PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2, BIT2, 1}, { 12, PERIPHS_IO_MUX_MTDI_U, FUNC_GPIO12, BIT12, 0}, { 13, PERIPHS_IO_MUX_MTCK_U, FUNC_GPIO13, BIT13, 1}, { 14, PERIPHS_IO_MUX_MTMS_U, FUNC_GPIO14, BIT14, 1}, { 15, PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15, BIT15, 0} }; #define N_GPIOS (sizeof(gpios)/sizeof(gpios[0])) static uint32_t mask; static os_timer_t gpio_timer; static os_timer_t gpio_intr_timer; uint32_t ICACHE_FLASH_ATTR gpio_read (void) { return gpio_input_get () & mask; } void ICACHE_FLASH_ATTR gpio_dispatch (void) { uint32_t v = gpio_read (); int red, green; red = ! !(v & BIT12); green = ! !(v & BIT14); msg_send (red,green,v); } static void ICACHE_FLASH_ATTR gpio_intr_timer_cb (void *arg) { gpio_dispatch (); } static void ICACHE_FLASH_ATTR gpio_timer_cb (void *arg) { gpio_dispatch (); } /* Docs say you can't call os_timer_arm in an interrupt, yet the examples do */ static void gpio_intr_handler (void *arg) { int i; uint32 status = GPIO_REG_READ (GPIO_STATUS_ADDRESS); /* Clear any interrupts */ for (i = 0; i < N_GPIOS; ++i) if (status & gpios[i].bit) GPIO_REG_WRITE (GPIO_STATUS_W1TC_ADDRESS, status & gpios[i].bit); /*Arm the timer*/ os_timer_disarm (&gpio_intr_timer); os_timer_setfn (&gpio_intr_timer, gpio_intr_timer_cb, NULL); os_timer_arm (&gpio_intr_timer, 5, 0); } void ICACHE_FLASH_ATTR gpio_page (struct espconn *conn) { char *page = os_zalloc (1024); char *ptr = page; int i; uint32_t j, v; if (!page) { webserver_send_reply (conn, 400, "text/html", "Out of memory", 0); return; } ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); v = gpio_read (); ptr += os_sprintf (ptr, "

GPIO: 0x%04x


", v); ptr += os_sprintf (ptr, ""); for (i = 0; i < N_GPIOS; ++i) { ptr += os_sprintf (ptr, "", gpios[i].id, gpios[i].bit, (gpios[i].bit & v) ? "High" : "Low"); } ptr += os_sprintf (ptr, "
%d0x%04x%s
"); webserver_send_reply (conn, 200, "text/html", page, ptr - page); os_free (page); } void ICACHE_FLASH_ATTR gpio_colour_page (struct espconn *conn) { char *page = os_zalloc (1024); char *ptr = page; int i; uint32_t j, v; int red, green; if (!page) { webserver_send_reply (conn, 400, "text/html", "Out of memory", 0); return; } ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); v = gpio_read (); red = ! !(v & BIT12); green = ! !(v & BIT14); if ((!red) && (!green)) ptr += os_sprintf (ptr, ""); else if ((!red) && (green)) ptr += os_sprintf (ptr, ""); else if ((red) && (!green)) ptr += os_sprintf (ptr, ""); else if ((red) && (green)) ptr += os_sprintf (ptr, ""); ptr += os_sprintf (ptr, ""); webserver_send_reply (conn, 200, "text/html", page, ptr - page); os_free (page); } void ICACHE_FLASH_ATTR gpio_init (void) { int i; ETS_GPIO_INTR_DISABLE (); ETS_GPIO_INTR_ATTACH (gpio_intr_handler, NULL); for (i = 0; i < N_GPIOS; ++i) { PIN_FUNC_SELECT (gpios[i].pin, gpios[i].func); if (gpios[i].pull) PIN_PULLUP_EN (gpios[i].pin); else PIN_PULLUP_DIS (gpios[i].pin); /* disable drivers */ gpio_output_set (0, 0, 0, gpios[i].bit); gpio_register_set (GPIO_PIN_ADDR (gpios[i].id), GPIO_PIN_INT_TYPE_SET (GPIO_PIN_INTR_DISABLE) | GPIO_PIN_PAD_DRIVER_SET (GPIO_PAD_DRIVER_DISABLE) | GPIO_PIN_SOURCE_SET (GPIO_AS_PIN_SOURCE)); GPIO_REG_WRITE (GPIO_STATUS_W1TC_ADDRESS, gpios[i].bit); gpio_pin_intr_state_set (GPIO_ID_PIN (gpios[i].id), GPIO_PIN_INTR_ANYEDGE); mask |= gpios[i].bit; } ETS_GPIO_INTR_ENABLE (); os_timer_disarm (&gpio_timer); os_timer_setfn (&gpio_timer, (os_timer_func_t *) gpio_timer_cb, NULL); os_timer_arm (&gpio_timer, 10000, 1); }