#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,
"%d | 0x%04x | %s |
",
gpios[i].id, gpios[i].bit,
(gpios[i].bit & v) ? "High" : "Low");
}
ptr += os_sprintf (ptr, "
");
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);
}