This commit is contained in:
parent
82146efb03
commit
4abab8f1b0
2 changed files with 173 additions and 1 deletions
166
firmware/lux.cpp
166
firmware/lux.cpp
|
@ -3,10 +3,18 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "lux.h"
|
#include "lux.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <FreeRTOS.h>
|
#include <FreeRTOS.h>
|
||||||
#include <task.h>
|
#include <task.h>
|
||||||
|
#include <sockets.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sysparam.h>
|
||||||
|
#include <lwipopts.h>
|
||||||
|
#include <espressif/user_interface.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include <esp/spi.h>
|
#include <esp/spi.h>
|
||||||
|
|
||||||
|
@ -20,13 +28,169 @@ extern "C" void signal_led(bool state) {
|
||||||
gpio_write(signal_led_pin, !state);
|
gpio_write(signal_led_pin, !state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class parse_status {
|
||||||
|
ERROR,
|
||||||
|
SET_PIXEL_RGB,
|
||||||
|
SET_PIXEL_RGBW,
|
||||||
|
GET_PIXEL,
|
||||||
|
GET_DIMENSIONS,
|
||||||
|
GET_HELP
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
parse_status parse_pixelflut_message(const char *msg, size_t len,
|
||||||
|
uint16_t &x, uint16_t &y, uint8_t &r, uint8_t &g, uint8_t &b, uint8_t &w) {
|
||||||
|
if(len < 4)
|
||||||
|
return parse_status::ERROR;
|
||||||
|
|
||||||
|
if(msg[0] == 'P' && msg[1] == 'X' && msg[2] == ' ') {
|
||||||
|
size_t i = 3;
|
||||||
|
size_t j = 0;
|
||||||
|
char buf[5];
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
x = atoi(buf);
|
||||||
|
while(i < len && msg[i] == ' ')
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
y = atoi(buf);
|
||||||
|
while(i < len && msg[i] == ' ')
|
||||||
|
i++;
|
||||||
|
if(i >= len)
|
||||||
|
return parse_status::GET_PIXEL;
|
||||||
|
j = 0;
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
r = atoi(buf);
|
||||||
|
while(i < len && msg[i] == ' ')
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
g = atoi(buf);
|
||||||
|
while(i < len && msg[i] == ' ')
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
b = atoi(buf);
|
||||||
|
while(i < len && msg[i] == ' ')
|
||||||
|
i++;
|
||||||
|
if(i >= len)
|
||||||
|
return parse_status::SET_PIXEL_RGB;
|
||||||
|
j = 0;
|
||||||
|
while (i < len && msg[i] != ' ' && j < 4) {
|
||||||
|
buf[j++] = msg[i++];
|
||||||
|
}
|
||||||
|
buf[j] = 0;
|
||||||
|
w = atoi(buf);
|
||||||
|
return parse_status::SET_PIXEL_RGBW;
|
||||||
|
} else if(msg[0] == 'S' && msg[1] == 'I' && msg[2] == 'Z' && msg[3] == 'E') {
|
||||||
|
return parse_status::GET_DIMENSIONS;
|
||||||
|
} else if(msg[0] == 'H' && msg[1] == 'E' && msg[2] == 'L' && msg[3] == 'P') {
|
||||||
|
return parse_status::GET_HELP;
|
||||||
|
} else {
|
||||||
|
return parse_status::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[[noreturn]] static void pixelflut_task(void *pvParameters) {
|
||||||
|
//char *wifi_ap_ip_addr = nullptr;
|
||||||
|
//sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr);
|
||||||
|
//if(!wifi_ap_ip_addr) {
|
||||||
|
// syslog("dns: no ip address\n");
|
||||||
|
// vTaskDelete(nullptr);
|
||||||
|
//}
|
||||||
|
//ip4_addr_t server_addr;
|
||||||
|
//server_addr.addr = ipaddr_addr(wifi_ap_ip_addr);
|
||||||
|
|
||||||
|
#if LWIP_IPV6
|
||||||
|
int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
sockaddr_in6 serv_addr;
|
||||||
|
memset(&serv_addr, '0', sizeof(serv_addr));
|
||||||
|
serv_addr.sin6_family = AF_INET6;
|
||||||
|
serv_addr.sin6_port = htons(53);
|
||||||
|
serv_addr.sin6_flowinfo = 0;
|
||||||
|
serv_addr.sin6_addr = in6addr_any;
|
||||||
|
serv_addr.sin6_scope_id = IP6_NO_ZONE;
|
||||||
|
#else
|
||||||
|
int fd = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
sockaddr_in serv_addr{};
|
||||||
|
serv_addr.sin_family = AF_INET;
|
||||||
|
serv_addr.sin_addr.s_addr = lwip_htonl(INADDR_ANY);
|
||||||
|
serv_addr.sin_port = lwip_htons(2342);
|
||||||
|
#endif
|
||||||
|
lwip_bind(fd, (sockaddr *) &serv_addr, sizeof(serv_addr));
|
||||||
|
|
||||||
|
printf("pixelflut: listening on port 2342\n");
|
||||||
|
|
||||||
|
const ifreq ifreq0 = {"en0"};
|
||||||
|
const ifreq ifreq1 = {"en1"};
|
||||||
|
lwip_setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
|
||||||
|
sdk_wifi_get_opmode() == STATIONAP_MODE ? &ifreq1 : &ifreq0,
|
||||||
|
sizeof(ifreq0));
|
||||||
|
|
||||||
|
int width = 23;
|
||||||
|
int height = 42;
|
||||||
|
|
||||||
|
char buffer[96] = {0};
|
||||||
|
sockaddr_storage src_addr{};
|
||||||
|
for (;;) {
|
||||||
|
socklen_t src_addr_len = sizeof(src_addr);
|
||||||
|
ssize_t count = lwip_recvfrom(fd, buffer, sizeof(buffer), 0, (sockaddr *) &src_addr, &src_addr_len);
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t x, y;
|
||||||
|
uint8_t r, g, b, w;
|
||||||
|
parse_status status = parse_pixelflut_message((char *) buffer, count, x, y, r, g, b, w);
|
||||||
|
if(status == parse_status::SET_PIXEL_RGB) {
|
||||||
|
printf("set pixel %d %d to %d %d %d\n", x, y, r, g, b);
|
||||||
|
} else if(status == parse_status::SET_PIXEL_RGBW) {
|
||||||
|
printf("set pixel %d %d to %d %d %d %d\n", x, y, r, g, b, w);
|
||||||
|
} else if(status == parse_status::GET_PIXEL) {
|
||||||
|
uint32_t reply_len = snprintf((char *) buffer, 96, "PX %d %d %d %d %d %d", x, y, r, g, b, w);
|
||||||
|
lwip_sendto(fd, buffer, reply_len, 0, (sockaddr *) &src_addr, src_addr_len);
|
||||||
|
} else if(status == parse_status::GET_DIMENSIONS) {
|
||||||
|
uint32_t reply_len = snprintf((char *) buffer, 96, "SIZE %d %d", width, height);
|
||||||
|
lwip_sendto(fd, buffer, reply_len, 0, (sockaddr *) &src_addr, src_addr_len);
|
||||||
|
} else if(status == parse_status::GET_HELP) {
|
||||||
|
uint32_t reply_len = snprintf((char *) buffer, 96, "HELP");
|
||||||
|
lwip_sendto(fd, buffer, reply_len, 0, (sockaddr *) &src_addr, src_addr_len);
|
||||||
|
} else {
|
||||||
|
uint32_t reply_len = snprintf((char *) buffer, 96, "ERR");
|
||||||
|
lwip_sendto(fd, buffer, reply_len, 0, (sockaddr *) &src_addr, src_addr_len);
|
||||||
|
printf("error parsing message [%d bytes]: \n", count);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
printf("%c", buffer[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void lux_task(void *pvParameters) {
|
extern "C" void lux_task(void *pvParameters) {
|
||||||
|
|
||||||
gpio_enable(signal_led_pin, GPIO_OUTPUT);
|
gpio_enable(signal_led_pin, GPIO_OUTPUT);
|
||||||
gpio_enable(cs0, GPIO_OUTPUT);
|
gpio_enable(cs0, GPIO_OUTPUT);
|
||||||
gpio_enable(gpio4, GPIO_OUTPUT);
|
gpio_enable(gpio4, GPIO_OUTPUT);
|
||||||
gpio_enable(gpio5, GPIO_OUTPUT);
|
gpio_enable(gpio5, GPIO_OUTPUT);
|
||||||
spi_init(1, SPI_MODE0, SPI_FREQ_DIV_1M, 1, SPI_BIG_ENDIAN, 1);
|
spi_init(1, SPI_MODE0, SPI_FREQ_DIV_1M, true, SPI_BIG_ENDIAN, true);
|
||||||
|
|
||||||
|
xTaskCreate(&pixelflut_task, "pixelflut_task", 512, nullptr, 2, nullptr);
|
||||||
|
|
||||||
vTaskDelete(nullptr);
|
vTaskDelete(nullptr);
|
||||||
}
|
}
|
|
@ -65,6 +65,14 @@ void websocket_task(void *pvParameter) {
|
||||||
|
|
||||||
//Global Info
|
//Global Info
|
||||||
if(has_changed.global) {
|
if(has_changed.global) {
|
||||||
|
|
||||||
|
//while (1) {
|
||||||
|
// vTaskDelay(10000 / portTICK_PERIOD_MS);
|
||||||
|
// time_t ts = time(NULL);
|
||||||
|
// long long t = ts;
|
||||||
|
// printf("TIME: %ld %s", (long int) t, ctime(&ts));
|
||||||
|
//}
|
||||||
|
|
||||||
timeval tv{};
|
timeval tv{};
|
||||||
gettimeofday(&tv, nullptr);
|
gettimeofday(&tv, nullptr);
|
||||||
size_t uptime = xTaskGetTickCount() * portTICK_PERIOD_MS / 1000;
|
size_t uptime = xTaskGetTickCount() * portTICK_PERIOD_MS / 1000;
|
||||||
|
|
Loading…
Reference in a new issue