implement async handlers for pulsing pw_sw
This commit is contained in:
parent
c0e774c08c
commit
426c04116f
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
**/build/*
|
||||
**/secret.h
|
||||
**/htmldata.c
|
||||
**/wwwdata.c
|
17
Makefile
17
Makefile
@ -1,16 +1,13 @@
|
||||
#TOPTARGETS := all clean
|
||||
.PHONY: all clean build makefsdata
|
||||
|
||||
SUBDIRS := build
|
||||
all: clean makefsdata build
|
||||
|
||||
all: makefsdata $(SUBDIRS)
|
||||
clean:
|
||||
$(MAKE) -C build/ clean
|
||||
rm -rf wwwdata.c
|
||||
|
||||
makefsdata:
|
||||
python3 makefsdata.py
|
||||
|
||||
clean: $(SUBDIRS)
|
||||
rm -rf htmldata.c
|
||||
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
.PHONY: all makefsdata clean $(SUBDIRS)
|
||||
build:
|
||||
$(MAKE) -C build/
|
54
cgi.h
54
cgi.h
@ -1,32 +1,40 @@
|
||||
#ifndef CGI_H
|
||||
#define CGI_H
|
||||
|
||||
#include "lwip/apps/httpd.h"
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "handlers.h"
|
||||
|
||||
// CGI handler which is run when a request for /led.cgi is detected
|
||||
const char * cgi_led_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||
{
|
||||
// Check if an request for LED has been made (/led.cgi?led=x)
|
||||
if (strcmp(pcParam[0] , "led") == 0){
|
||||
// Look at the argument to check if LED is to be turned on (x=1) or off (x=0)
|
||||
if(strcmp(pcValue[0], "0") == 0)
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||
else if(strcmp(pcValue[0], "1") == 0)
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
||||
}
|
||||
|
||||
// Send the index page back to the user
|
||||
return "/index.shtml";
|
||||
const char * cgi_power_handler (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
|
||||
// Check if an request for power has been made (/power?requested_state=x)
|
||||
if (strcmp(pcParam[0] , "requested_state") == 0){
|
||||
// Look at the argument to check if LED is to be turned on (x=1) or off (x=0)
|
||||
if(strcmp(pcValue[0], "0") == 0) {
|
||||
bmc_power_handler(false);
|
||||
}
|
||||
else if(strcmp(pcValue[0], "1") == 0) {
|
||||
bmc_power_handler(true);
|
||||
}
|
||||
}
|
||||
// Send the index page back to the user
|
||||
return "/power.ssi";
|
||||
}
|
||||
|
||||
const char * cgi_status_handler (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
|
||||
return "/status.ssi";
|
||||
}
|
||||
|
||||
// tCGI Struct
|
||||
// Fill this with all of the CGI requests and their respective handlers
|
||||
static const tCGI cgi_handlers[] = {
|
||||
{
|
||||
// Html request for "/led.cgi" triggers cgi_handler
|
||||
"/led.cgi", cgi_led_handler
|
||||
},
|
||||
{
|
||||
"/power", cgi_power_handler
|
||||
},
|
||||
{
|
||||
"/status", cgi_status_handler
|
||||
}
|
||||
};
|
||||
|
||||
void cgi_init(void)
|
||||
{
|
||||
http_set_cgi_handlers(cgi_handlers, 1);
|
||||
void cgi_init(void) {
|
||||
http_set_cgi_handlers(cgi_handlers, 2);
|
||||
}
|
||||
|
||||
#endif
|
38
handlers.h
Normal file
38
handlers.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef HANDLERS_H
|
||||
#define HANDLERS_H
|
||||
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#define PW_SW_DELAY_MS 100
|
||||
#define STATE_UPDATE_REPEAT_DELAY_MS 100
|
||||
|
||||
bool current_state = false;
|
||||
|
||||
int64_t pw_sw_on_async (alarm_id_t id, void * user_data) {
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
||||
return 0; // do not reschedule alarm
|
||||
}
|
||||
|
||||
int64_t pw_sw_off_async (alarm_id_t id, void * user_data) {
|
||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||
return 0; // do not reschedule alarm
|
||||
}
|
||||
|
||||
bool update_current_state_async (repeating_timer_t * rt) {
|
||||
return true; // continue repeating alarm
|
||||
}
|
||||
|
||||
bool bmc_power_handler (bool requested_state) {
|
||||
if (requested_state != current_state) {
|
||||
add_alarm_in_ms(0, pw_sw_on_async, NULL, true);
|
||||
add_alarm_in_ms(PW_SW_DELAY_MS, pw_sw_off_async, NULL, true);
|
||||
}
|
||||
}
|
||||
|
||||
struct repeating_timer * bmc_handler_init () {
|
||||
struct repeating_timer * timer = malloc(sizeof(struct repeating_timer));
|
||||
add_repeating_timer_ms(STATE_UPDATE_REPEAT_DELAY_MS, update_current_state_async, NULL, timer);
|
||||
return timer;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>PicoW Webserver</title>
|
||||
</head>
|
||||
<body> <h1>PicoW Webserver Tutorial</h1>
|
||||
<br>
|
||||
<h2>This bit is SSI:</h2>
|
||||
<p>Voltage: <!--#volt--></p>
|
||||
<p>Temp: <!--#temp--> C</p>
|
||||
<p>LED is: <!--#led--></p>
|
||||
<br>
|
||||
<h2>This bit is CGI:</h2>
|
||||
<a href="/led.cgi?led=1"><button>LED ON</button></a>
|
||||
<a href="/led.cgi?led=0"><button>LED OFF</button></a>
|
||||
<br>
|
||||
<br>
|
||||
<a href="/index.shtml">Refresh</a>
|
||||
</body>
|
||||
</html>
|
@ -90,4 +90,4 @@
|
||||
#define LWIP_HTTPD_CGI 1
|
||||
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0
|
||||
#define HTTPD_SERVER_PORT 80
|
||||
#define HTTPD_FSDATA_FILE "htmldata.c"
|
||||
#define HTTPD_FSDATA_FILE "wwwdata.c"
|
142
makefsdata.py
142
makefsdata.py
@ -8,13 +8,13 @@ import os
|
||||
import binascii
|
||||
|
||||
#Create file to write output into
|
||||
output = open('htmldata.c', 'w')
|
||||
output = open('wwwdata.c', 'w')
|
||||
|
||||
#Traverse directory, generate list of files
|
||||
files = list()
|
||||
os.chdir('./html_files')
|
||||
os.chdir('./www')
|
||||
for(dirpath, dirnames, filenames) in os.walk('.'):
|
||||
files += [os.path.join(dirpath, file) for file in filenames]
|
||||
files += [os.path.join(dirpath, file) for file in filenames]
|
||||
|
||||
filenames = list()
|
||||
varnames = list()
|
||||
@ -22,85 +22,87 @@ varnames = list()
|
||||
#Generate appropriate HTTP headers
|
||||
for file in files:
|
||||
|
||||
if '404' in file:
|
||||
header = "HTTP/1.0 404 File not found\r\n"
|
||||
else:
|
||||
header = "HTTP/1.0 200 OK\r\n"
|
||||
if '404' in file:
|
||||
header = "HTTP/1.0 404 File not found\r\n"
|
||||
else:
|
||||
header = "HTTP/1.0 200 OK\r\n"
|
||||
|
||||
header += "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"
|
||||
header += "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"
|
||||
|
||||
if '.html' in file:
|
||||
header += "Content-type: text/html\r\n"
|
||||
elif '.shtml' in file:
|
||||
header += "Content-type: text/html\r\n"
|
||||
elif '.jpg' in file:
|
||||
header += "Content-type: image/jpeg\r\n"
|
||||
elif '.gif' in file:
|
||||
header += "Content-type: image/gif\r\n"
|
||||
elif '.png' in file:
|
||||
header += "Content-type: image/png\r\n"
|
||||
elif '.class' in file:
|
||||
header += "Content-type: application/octet-stream\r\n"
|
||||
elif '.js' in file:
|
||||
header += "Content-type: text/javascript\r\n"
|
||||
elif '.css' in file:
|
||||
header += "Content-type: text/css\r\n"
|
||||
elif '.svg' in file:
|
||||
header += "Content-type: image/svg+xml\r\n"
|
||||
else:
|
||||
header += "Content-type: text/plain\r\n"
|
||||
if '.html' in file:
|
||||
header += "Content-type: text/html\r\n"
|
||||
elif '.shtml' in file:
|
||||
header += "Content-type: text/html\r\n"
|
||||
elif '.jpg' in file:
|
||||
header += "Content-type: image/jpeg\r\n"
|
||||
elif '.gif' in file:
|
||||
header += "Content-type: image/gif\r\n"
|
||||
elif '.png' in file:
|
||||
header += "Content-type: image/png\r\n"
|
||||
elif '.class' in file:
|
||||
header += "Content-type: application/octet-stream\r\n"
|
||||
elif '.js' in file:
|
||||
header += "Content-type: text/javascript\r\n"
|
||||
elif '.css' in file:
|
||||
header += "Content-type: text/css\r\n"
|
||||
elif '.svg' in file:
|
||||
header += "Content-type: image/svg+xml\r\n"
|
||||
elif ".ssi" in file:
|
||||
header += "Content-type: application/json\r\n"
|
||||
else:
|
||||
header += "Content-type: text/plain\r\n"
|
||||
|
||||
header += "\r\n"
|
||||
header += "\r\n"
|
||||
|
||||
fvar = file[1:] #remove leading dot in filename
|
||||
fvar = fvar.replace('/', '_') #replace *nix path separator with underscore
|
||||
fvar = fvar.replace('\\', '_') #replace DOS path separator with underscore
|
||||
fvar = fvar.replace('.', '_') #replace file extension dot with underscore
|
||||
fvar = file[1:] #remove leading dot in filename
|
||||
fvar = fvar.replace('/', '_') #replace *nix path separator with underscore
|
||||
fvar = fvar.replace('\\', '_') #replace DOS path separator with underscore
|
||||
fvar = fvar.replace('.', '_') #replace file extension dot with underscore
|
||||
|
||||
output.write("static const unsigned char data{}[] = {{\n".format(fvar))
|
||||
output.write("\t/* {} */\n\t".format(file))
|
||||
output.write("static const unsigned char data{}[] = {{\n".format(fvar))
|
||||
output.write("\t/* {} */\n\t".format(file))
|
||||
|
||||
#first set of hex data encodes the filename
|
||||
b = bytes(file[1:].replace('\\', '/'), 'utf-8') #change DOS path separator to forward slash
|
||||
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
output.write("0,\n\t")
|
||||
#first set of hex data encodes the filename
|
||||
b = bytes(file[1:].replace('\\', '/'), 'utf-8') #change DOS path separator to forward slash
|
||||
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
output.write("0,\n\t")
|
||||
|
||||
#second set of hex data is the HTTP header/mime type we generated above
|
||||
b = bytes(header, 'utf-8')
|
||||
count = 0
|
||||
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
count = count + 1
|
||||
if(count == 10):
|
||||
output.write("\n\t")
|
||||
count = 0
|
||||
output.write("\n\t")
|
||||
#second set of hex data is the HTTP header/mime type we generated above
|
||||
b = bytes(header, 'utf-8')
|
||||
count = 0
|
||||
for byte in binascii.hexlify(b, b' ', 1).split():
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
count = count + 1
|
||||
if(count == 10):
|
||||
output.write("\n\t")
|
||||
count = 0
|
||||
output.write("\n\t")
|
||||
|
||||
#finally, dump raw hex data from files
|
||||
with open(file, 'rb') as f:
|
||||
count = 0
|
||||
while(byte := f.read(1)):
|
||||
byte = binascii.hexlify(byte)
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
count = count + 1
|
||||
if(count == 10):
|
||||
output.write("\n\t")
|
||||
count = 0
|
||||
output.write("};\n\n")
|
||||
#finally, dump raw hex data from files
|
||||
with open(file, 'rb') as f:
|
||||
count = 0
|
||||
while(byte := f.read(1)):
|
||||
byte = binascii.hexlify(byte)
|
||||
output.write("0x{}, ".format(byte.decode()))
|
||||
count = count + 1
|
||||
if(count == 10):
|
||||
output.write("\n\t")
|
||||
count = 0
|
||||
output.write("};\n\n")
|
||||
|
||||
filenames.append(file[1:])
|
||||
varnames.append(fvar)
|
||||
filenames.append(file[1:])
|
||||
varnames.append(fvar)
|
||||
|
||||
for i in range(len(filenames)):
|
||||
prevfile = "NULL"
|
||||
if(i > 0):
|
||||
prevfile = "file" + varnames[i-1]
|
||||
prevfile = "NULL"
|
||||
if(i > 0):
|
||||
prevfile = "file" + varnames[i-1]
|
||||
|
||||
output.write("const struct fsdata_file file{0}[] = {{{{ {1}, data{2}, ".format(varnames[i], prevfile, varnames[i]))
|
||||
output.write("data{} + {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||
output.write("sizeof(data{}) - {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||
output.write("FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT}};\n")
|
||||
output.write("const struct fsdata_file file{0}[] = {{{{ {1}, data{2}, ".format(varnames[i], prevfile, varnames[i]))
|
||||
output.write("data{} + {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||
output.write("sizeof(data{}) - {}, ".format(varnames[i], len(filenames[i]) + 1))
|
||||
output.write("FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT}};\n")
|
||||
|
||||
output.write("\n#define FS_ROOT file{}\n".format(varnames[-1]))
|
||||
output.write("#define FS_NUMFILES {}\n".format(len(filenames)))
|
38
ssi.h
38
ssi.h
@ -1,51 +1,49 @@
|
||||
#ifndef SSI_H
|
||||
#define SSI_H
|
||||
|
||||
#include "lwip/apps/httpd.h"
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "hardware/adc.h"
|
||||
#include "handlers.h"
|
||||
|
||||
// SSI tags - tag length limited to 8 bytes by default
|
||||
const char * ssi_tags[] = {"volt","temp","led"};
|
||||
const char * ssi_tags[] = {"volt", "temp", "power"};
|
||||
|
||||
u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
|
||||
size_t printed;
|
||||
switch (iIndex) {
|
||||
case 0: // volt
|
||||
{
|
||||
const float voltage = adc_read() * 3.3f / (1 << 12);
|
||||
printed = snprintf(pcInsert, iInsertLen, "%f", voltage);
|
||||
const float voltage = adc_read() * 3.3f / (1 << 12);
|
||||
printed = snprintf(pcInsert, iInsertLen, "%f", voltage);
|
||||
}
|
||||
break;
|
||||
case 1: // temp
|
||||
{
|
||||
const float voltage = adc_read() * 3.3f / (1 << 12);
|
||||
const float tempC = 27.0f - (voltage - 0.706f) / 0.001721f;
|
||||
printed = snprintf(pcInsert, iInsertLen, "%f", tempC);
|
||||
const float voltage = adc_read() * 3.3f / (1 << 12);
|
||||
const float tempC = 27.0f - (voltage - 0.706f) / 0.001721f;
|
||||
printed = snprintf(pcInsert, iInsertLen, "%f", tempC);
|
||||
}
|
||||
break;
|
||||
case 2: // led
|
||||
case 2: // power
|
||||
{
|
||||
bool led_status = cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN);
|
||||
if(led_status == true){
|
||||
printed = snprintf(pcInsert, iInsertLen, "ON");
|
||||
}
|
||||
else{
|
||||
printed = snprintf(pcInsert, iInsertLen, "OFF");
|
||||
}
|
||||
printed = snprintf(pcInsert, iInsertLen, "%d", current_state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printed = 0;
|
||||
{
|
||||
printed = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (u16_t)printed;
|
||||
return (u16_t) printed;
|
||||
}
|
||||
|
||||
// Initialise the SSI handler
|
||||
void ssi_init() {
|
||||
// Initialise ADC (internal pin)
|
||||
adc_init();
|
||||
adc_set_temp_sensor_enabled(true);
|
||||
adc_select_input(4);
|
||||
|
||||
http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags));
|
||||
}
|
||||
|
||||
#endif
|
1
www/power.ssi
Normal file
1
www/power.ssi
Normal file
@ -0,0 +1 @@
|
||||
{}
|
5
www/status.ssi
Normal file
5
www/status.ssi
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"volt": <!--#volt-->,
|
||||
"temp": <!--#temp-->,
|
||||
"power": <!--#power-->
|
||||
}
|
Loading…
Reference in New Issue
Block a user