This commit is contained in:
parent
2b07102b69
commit
1cd16f0aad
9 changed files with 326 additions and 162 deletions
7
.idea/.gitignore
vendored
Normal file
7
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
||||||
|
|
8
Makefile
8
Makefile
|
@ -1,12 +1,16 @@
|
||||||
.PHONY: firmware flash firmware_docker case pcb
|
.PHONY: firmware flash firmware_docker case pcb
|
||||||
|
|
||||||
all: firmware case pcb
|
all: peripherals firmware case pcb
|
||||||
|
|
||||||
|
peripherals:
|
||||||
|
+@make all -C peripherals/cc48x6
|
||||||
|
|
||||||
firmware:
|
firmware:
|
||||||
+@make -C firmware html all
|
+@make -C firmware html all
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
+@make -C firmware flash
|
+@make flash -C firmware
|
||||||
|
+@make flash -C peripherals/cc48x6
|
||||||
|
|
||||||
case:
|
case:
|
||||||
+@make -C case all
|
+@make -C case all
|
||||||
|
|
208
firmware/bus.cpp
208
firmware/bus.cpp
|
@ -2,6 +2,7 @@
|
||||||
#include "esp/gpio.h"
|
#include "esp/gpio.h"
|
||||||
|
|
||||||
#include <esp/spi.h>
|
#include <esp/spi.h>
|
||||||
|
#include <cstdio>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
uint32_t spi_transfer_32_duplex(uint8_t bus, uint32_t val) {
|
uint32_t spi_transfer_32_duplex(uint8_t bus, uint32_t val) {
|
||||||
|
@ -18,13 +19,124 @@ uint16_t spi_transfer_16_duplex(uint8_t bus, uint32_t val) {
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CMD_NONE = 0,
|
||||||
|
CMD_READ = 1,
|
||||||
|
CMD_WRITE = 2,
|
||||||
|
CMD_INIT = 3,
|
||||||
|
CMD_RESET = 4,
|
||||||
|
CMD_VERSION = 5,
|
||||||
|
CMD_CONFIG = 6,
|
||||||
|
CMD_PING = 7
|
||||||
|
} bus_cmd;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 16;
|
||||||
|
unsigned addr: 8;
|
||||||
|
unsigned cmd: 8;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint32_t _;
|
||||||
|
} request_frame;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 16;
|
||||||
|
unsigned addr: 8;
|
||||||
|
unsigned flags: 7;
|
||||||
|
unsigned: 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint32_t _;
|
||||||
|
} reply_frame;
|
||||||
|
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
|
reply_frame bus_transfer_msg(bus_cmd cmd, uint8_t addr, uint16_t dat) {
|
||||||
|
request_frame frame_out = {._=0};
|
||||||
|
reply_frame frame_in = {._=0};
|
||||||
|
|
||||||
|
frame_out.cmd = cmd;
|
||||||
|
frame_out.addr = addr;
|
||||||
|
frame_out.dat = dat;
|
||||||
|
spi_transfer_32_duplex(1, frame_out._);
|
||||||
|
for (volatile int k = 0; k < 512 * 2; ++k);
|
||||||
|
frame_in._ = spi_transfer_32_duplex(1, 0x0000);
|
||||||
|
for (volatile int k = 0; k < 512 * 2; ++k);
|
||||||
|
flags |= frame_in.flags;
|
||||||
|
return frame_in;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t bus_transfer_msg(uint8_t addr, uint16_t dat) {
|
||||||
|
return bus_transfer_msg(CMD_WRITE, addr, dat)._;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bus_transfer_msg_arr(uint8_t addr, uint16_t *dat, uint8_t len) {
|
||||||
|
request_frame frame_out = {._=0};
|
||||||
|
reply_frame frame_in = {._=0};
|
||||||
|
|
||||||
|
request_frame last_frame = {._=0};
|
||||||
|
uint8_t error_count = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
|
|
||||||
|
frame_out.cmd = CMD_WRITE;
|
||||||
|
frame_out.addr = addr;
|
||||||
|
frame_out.dat = dat[i];
|
||||||
|
|
||||||
|
frame_in._ = spi_transfer_32_duplex(1, frame_out._);
|
||||||
|
|
||||||
|
if(frame_in.dat != last_frame.dat && i != 0) {
|
||||||
|
error_count++;
|
||||||
|
|
||||||
|
if(0) {
|
||||||
|
syslog(" > ");
|
||||||
|
syslog_i32(frame_out._);
|
||||||
|
syslog(" < ");
|
||||||
|
syslog_i32(frame_in._);
|
||||||
|
syslog(" =? ");
|
||||||
|
syslog_i32(last_frame._);
|
||||||
|
syslog("\n");
|
||||||
|
}
|
||||||
|
printf(" > %08x < %08x =? %08x\n", frame_out._, frame_in._, last_frame._);
|
||||||
|
}
|
||||||
|
|
||||||
|
last_frame._ = frame_out._;
|
||||||
|
|
||||||
|
for (volatile int k = 0; k < 512 * 2; ++k);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_in._ = spi_transfer_32_duplex(1, 0x0000);
|
||||||
|
if(frame_in.dat != last_frame.dat) {
|
||||||
|
error_count++;
|
||||||
|
|
||||||
|
if(0) {
|
||||||
|
syslog(" > ");
|
||||||
|
syslog_i32(frame_out._);
|
||||||
|
syslog(" < ");
|
||||||
|
syslog_i32(frame_in._);
|
||||||
|
syslog(" =? ");
|
||||||
|
syslog_i32(last_frame._);
|
||||||
|
syslog("\n");
|
||||||
|
}
|
||||||
|
printf(" > %08x < %08x =? %08x\n", 0, frame_in._, last_frame._);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error_count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t bus_get_version() {
|
||||||
|
return bus_transfer_msg(15, 0) >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
void reset_bus() {
|
void reset_bus() {
|
||||||
gpio_write(4, false);
|
gpio_write(4, false);
|
||||||
for (volatile int k = 0; k < 128; ++k);
|
for (volatile int k = 0; k < 128; ++k);
|
||||||
gpio_write(4, true);
|
gpio_write(4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bus_init() {
|
bool bus_init() {
|
||||||
|
gpio_enable(12, GPIO_INPUT);
|
||||||
|
gpio_set_pullup(12, true, true);
|
||||||
gpio_write(4, false);
|
gpio_write(4, false);
|
||||||
for (volatile int k = 0; k < 512 * 2; ++k);
|
for (volatile int k = 0; k < 512 * 2; ++k);
|
||||||
gpio_write(4, true);
|
gpio_write(4, true);
|
||||||
|
@ -32,86 +144,32 @@ void bus_init() {
|
||||||
gpio_write(4, true);
|
gpio_write(4, true);
|
||||||
for (volatile int k = 0; k < 512 * 4; ++k);
|
for (volatile int k = 0; k < 512 * 4; ++k);
|
||||||
|
|
||||||
spi_init(1, SPI_MODE0, SPI_FREQ_DIV_2M, true, SPI_BIG_ENDIAN, false);
|
bool miso_state = gpio_read(12);
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t bus_transfer_msg(uint8_t addr, uint16_t dat) {
|
if(miso_state) {
|
||||||
union {
|
printf("MISO is high, bus is not reset\n");
|
||||||
struct {
|
return false;
|
||||||
unsigned dat: 12;
|
|
||||||
unsigned addr: 4;
|
|
||||||
} __attribute__((packed));
|
|
||||||
uint16_t _;
|
|
||||||
} frame = {._=0};
|
|
||||||
|
|
||||||
frame.addr = addr;
|
|
||||||
frame.dat = dat;
|
|
||||||
spi_transfer_16_duplex(1, frame._);
|
|
||||||
for (volatile int k = 0; k < 512 * 2; ++k);
|
|
||||||
uint16_t reply = spi_transfer_16_duplex(1, 0x0000);
|
|
||||||
for (volatile int k = 0; k < 512 * 2; ++k);
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bus_transfer_msg_arr(uint8_t addr, uint16_t* dat, uint8_t len) {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned dat: 12;
|
|
||||||
unsigned addr: 4;
|
|
||||||
} __attribute__((packed));
|
|
||||||
uint16_t _;
|
|
||||||
} frame = {._=0};
|
|
||||||
|
|
||||||
uint16_t last_frame = 0x0000;
|
|
||||||
uint16_t reply = 0x0000;
|
|
||||||
uint8_t error_count = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < len; ++i) {
|
|
||||||
|
|
||||||
frame.addr = addr + i;
|
|
||||||
frame.dat = dat[i];
|
|
||||||
|
|
||||||
reply = spi_transfer_16_duplex(1, frame._);
|
|
||||||
|
|
||||||
if(reply != last_frame && i != 0)
|
|
||||||
error_count++;
|
|
||||||
|
|
||||||
if(0){
|
|
||||||
syslog(" > ");
|
|
||||||
syslog_i32(frame._);
|
|
||||||
syslog(" < ");
|
|
||||||
syslog_i32(reply);
|
|
||||||
syslog(" =? ");
|
|
||||||
syslog_i32(last_frame);
|
|
||||||
syslog("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
last_frame = frame._;
|
|
||||||
|
|
||||||
for (volatile int k = 0; k < 512 * 2; ++k);
|
|
||||||
}
|
}
|
||||||
|
spi_init(1, SPI_MODE0, SPI_FREQ_DIV_8M, true, SPI_BIG_ENDIAN, false);
|
||||||
|
|
||||||
reply = spi_transfer_16_duplex(1, 0x0000);
|
return true;
|
||||||
if(reply != last_frame)
|
|
||||||
error_count++;
|
|
||||||
|
|
||||||
if(0){
|
|
||||||
syslog(" > ");
|
|
||||||
syslog_i32(frame._);
|
|
||||||
syslog(" < ");
|
|
||||||
syslog_i32(reply);
|
|
||||||
syslog(" =? ");
|
|
||||||
syslog_i32(last_frame);
|
|
||||||
syslog("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return error_count == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t bus_get_version() {
|
bool bus_init_next() {
|
||||||
return bus_transfer_msg(15, 0);
|
flags &= ~0x04;
|
||||||
|
auto reply = bus_transfer_msg(CMD_INIT, 1, 0);
|
||||||
|
//printf(" init: %08x \n", reply.flags);
|
||||||
|
printf(" init: %02x %02x %04x %08x \n", reply.flags, reply.addr, reply.dat, reply._);
|
||||||
|
return reply.flags & 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t ping_count = 0;
|
||||||
|
|
||||||
bool bus_ping() {
|
bool bus_ping() {
|
||||||
return bus_get_version() == 0x002a;
|
auto reply = bus_transfer_msg(CMD_PING, 1, ++ping_count);
|
||||||
|
if(reply.dat == ping_count)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
printf("ping %02x %04x =? %08x\n", 1, ping_count, reply._);
|
||||||
|
return false;
|
||||||
}
|
}
|
|
@ -11,11 +11,7 @@ uint32_t spi_transfer_32_duplex(uint8_t bus, uint32_t val);
|
||||||
|
|
||||||
uint16_t spi_transfer_16_duplex(uint8_t bus, uint32_t val);
|
uint16_t spi_transfer_16_duplex(uint8_t bus, uint32_t val);
|
||||||
|
|
||||||
void reset_bus();
|
uint32_t bus_transfer_msg(uint8_t addr, uint16_t dat);
|
||||||
|
|
||||||
void bus_init();
|
|
||||||
|
|
||||||
uint16_t bus_transfer_msg(uint8_t addr, uint16_t dat);
|
|
||||||
|
|
||||||
bool bus_transfer_msg_arr(uint8_t addr, uint16_t dat[], uint8_t len);
|
bool bus_transfer_msg_arr(uint8_t addr, uint16_t dat[], uint8_t len);
|
||||||
|
|
||||||
|
@ -23,6 +19,12 @@ uint16_t bus_get_version();
|
||||||
|
|
||||||
bool bus_ping();
|
bool bus_ping();
|
||||||
|
|
||||||
|
void reset_bus();
|
||||||
|
|
||||||
|
bool bus_init();
|
||||||
|
|
||||||
|
bool bus_init_next();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace fiatlux {
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
gpio_enable(2, GPIO_OUTPUT);
|
gpio_enable(2, GPIO_OUTPUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace relais {
|
namespace relais {
|
||||||
|
@ -231,9 +231,24 @@ extern "C" void signal_led(bool state) {
|
||||||
fiatlux::signal::write_data(state);
|
fiatlux::signal::write_data(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 12;
|
||||||
|
unsigned addr: 4;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint16_t _;
|
||||||
|
} cc48x6_frame;
|
||||||
|
|
||||||
extern "C" bool set_cc48x6(uint16_t a[6]) {
|
extern "C" bool set_cc48x6(uint16_t a[6]) {
|
||||||
return bus_transfer_msg_arr(1, a, 6);
|
cc48x6_frame f[6] = {
|
||||||
|
{{a[0], 1}},
|
||||||
|
{{a[1], 2}},
|
||||||
|
{{a[2], 3}},
|
||||||
|
{{a[3], 4}},
|
||||||
|
{{a[4], 5}},
|
||||||
|
{{a[5], 6}},
|
||||||
|
};
|
||||||
|
return bus_transfer_msg_arr(1, (uint16_t *) f, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" bool set_cc48(uint16_t a) {
|
extern "C" bool set_cc48(uint16_t a) {
|
||||||
|
@ -241,7 +256,7 @@ extern "C" bool set_cc48(uint16_t a) {
|
||||||
return set_cc48x6(d);
|
return set_cc48x6(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t bus_timeout = 200;
|
||||||
/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
|
/* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -250,7 +265,7 @@ extern "C" [[noreturn]] void lux_task(void *pvParameters) {
|
||||||
fiatlux::signal::setup();
|
fiatlux::signal::setup();
|
||||||
fiatlux::relais::setup();
|
fiatlux::relais::setup();
|
||||||
|
|
||||||
bus_init();
|
bool bus_active = bus_init();
|
||||||
|
|
||||||
int32_t lux_ws2812_number = 240;
|
int32_t lux_ws2812_number = 240;
|
||||||
auto ret = sysparam_get_int32("lux_ws2812_number", &lux_ws2812_number);
|
auto ret = sysparam_get_int32("lux_ws2812_number", &lux_ws2812_number);
|
||||||
|
@ -266,6 +281,11 @@ extern "C" [[noreturn]] void lux_task(void *pvParameters) {
|
||||||
ws2812_i2s_init(lux_ws2812_number, PIXEL_RGBW);
|
ws2812_i2s_init(lux_ws2812_number, PIXEL_RGBW);
|
||||||
memset(pixels, 0, sizeof(ws2812_pixel_t) * lux_ws2812_number);
|
memset(pixels, 0, sizeof(ws2812_pixel_t) * lux_ws2812_number);
|
||||||
|
|
||||||
|
if(bus_active) {
|
||||||
|
reset_bus();
|
||||||
|
while (bus_init_next())vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
//apa10xx_pixel_t leds[lux_apa10xx_number]; // TODO
|
//apa10xx_pixel_t leds[lux_apa10xx_number]; // TODO
|
||||||
|
|
||||||
//lux_apa102c_number
|
//lux_apa102c_number
|
||||||
|
@ -285,7 +305,7 @@ extern "C" [[noreturn]] void lux_task(void *pvParameters) {
|
||||||
- [2*n+1] = 8bit PWM value
|
- [2*n+1] = 8bit PWM value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
{
|
if(bus_active) {
|
||||||
peripheral_version = bus_get_version();
|
peripheral_version = bus_get_version();
|
||||||
syslog("peripheral_version: ");
|
syslog("peripheral_version: ");
|
||||||
syslog_i32(peripheral_version);
|
syslog_i32(peripheral_version);
|
||||||
|
@ -295,34 +315,47 @@ extern "C" [[noreturn]] void lux_task(void *pvParameters) {
|
||||||
light_value = 0xFFF;
|
light_value = 0xFFF;
|
||||||
uint16_t last_light_value = 0xFFFF;
|
uint16_t last_light_value = 0xFFFF;
|
||||||
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
fiatlux::signal::write_data(false);
|
if(bus_active) {
|
||||||
|
|
||||||
if(last_light_value != light_value) {
|
if(last_light_value != light_value) {
|
||||||
|
|
||||||
syslog("# ");
|
syslog("# ");
|
||||||
syslog_i32(light_value);
|
syslog_i32(light_value);
|
||||||
syslog("\n");
|
syslog("\n");
|
||||||
|
|
||||||
bool ok = set_cc48(light_value);
|
bool ok = set_cc48(light_value);
|
||||||
|
|
||||||
|
if(ok) {
|
||||||
|
last_light_value = light_value;
|
||||||
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
bus_timeout = 200;
|
||||||
|
} else {
|
||||||
|
syslog("reset_bus\n");
|
||||||
|
reset_bus();
|
||||||
|
printf("timeout: %d\n", bus_timeout);
|
||||||
|
vTaskDelay(bus_timeout / portTICK_PERIOD_MS);
|
||||||
|
bus_timeout *= 2;
|
||||||
|
if(bus_timeout > 10000)
|
||||||
|
bus_timeout = 10000;
|
||||||
|
while (bus_init_next())vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
if(ok) {
|
|
||||||
last_light_value = light_value;
|
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
|
||||||
} else {
|
} else {
|
||||||
syslog("reset_bus\n");
|
bool ping = bus_ping();
|
||||||
reset_bus();
|
if(!ping) {
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
syslog("ping: reset_bus\n");
|
||||||
}
|
reset_bus();
|
||||||
|
printf("timeout: %d\n", bus_timeout);
|
||||||
} else {
|
vTaskDelay(bus_timeout / portTICK_PERIOD_MS);
|
||||||
bool ping = bus_ping();
|
bus_timeout *= 2;
|
||||||
if(!ping) {
|
if(bus_timeout > 10000)
|
||||||
syslog("ping: reset_bus\n");
|
bus_timeout = 10000;
|
||||||
reset_bus();
|
while (bus_init_next())vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
} else {
|
||||||
|
bus_timeout = 200;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ bool is_on = true;
|
||||||
|
|
||||||
QueueHandle_t publish_queue;
|
QueueHandle_t publish_queue;
|
||||||
|
|
||||||
static void publish_state(){
|
static void publish_state() {
|
||||||
char msg[PUB_MSG_LEN];
|
char msg[PUB_MSG_LEN];
|
||||||
snprintf(msg, PUB_MSG_LEN, R"({"state":"%s", "brightness":%d})", is_on ? "ON" : "OFF", light_value >> 4);
|
snprintf(msg, PUB_MSG_LEN, R"({"state":"%s", "brightness":%d})", is_on ? "ON" : "OFF", light_value >> 4);
|
||||||
if(xQueueSend(publish_queue, (void *) msg, 0) == pdFALSE) {
|
if(xQueueSend(publish_queue, (void *) msg, 0) == pdFALSE) {
|
||||||
|
@ -87,7 +87,7 @@ class optional {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<T> &operator=(optional<T> &&other) noexcept {
|
optional<T> &operator=(optional<T> &&other) noexcept {
|
||||||
has_value_ = other.has_value_;
|
has_value_ = other.has_value_;
|
||||||
value_ = other.value_;
|
value_ = other.value_;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -95,7 +95,7 @@ class optional {
|
||||||
|
|
||||||
optional(const optional<T> &other) : has_value_(other.has_value_), value_(other.value_) {}
|
optional(const optional<T> &other) : has_value_(other.has_value_), value_(other.value_) {}
|
||||||
|
|
||||||
optional(optional<T> &&other) noexcept : has_value_(other.has_value_), value_(other.value_) {}
|
optional(optional<T> &&other) noexcept: has_value_(other.has_value_), value_(other.value_) {}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -165,11 +165,6 @@ class parser {
|
||||||
static void topic_received(mqtt_message_data_t *md) {
|
static void topic_received(mqtt_message_data_t *md) {
|
||||||
mqtt_message_t *message = md->message;
|
mqtt_message_t *message = md->message;
|
||||||
|
|
||||||
if(strncmp((char *) md->topic->lenstring.data, "fiatlux/light/fiatlux_test/set", md->topic->lenstring.len) != 0) {
|
|
||||||
printf("Invalid topic: %s\n", (char *) md->topic->lenstring.data);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *payload = (char *) message->payload;
|
char *payload = (char *) message->payload;
|
||||||
char *payload_end = payload + message->payloadlen;
|
char *payload_end = payload + message->payloadlen;
|
||||||
|
|
||||||
|
@ -238,6 +233,15 @@ static const char *get_my_id() {
|
||||||
return my_id;
|
return my_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char disco_msg_fmt[] = R"json({ "name": "Fiatlux Test %s",
|
||||||
|
"unique_id": "fiatlux_%s",
|
||||||
|
"command_topic": "fiatlux/light/fiatlux_%s/set",
|
||||||
|
"state_topic": "fiatlux/light/fiatlux_%s/state",
|
||||||
|
"brightness": true, "schema": "json" })json";
|
||||||
|
const char disco_topic_fmt[] = "homeassistant/light/fiatlux_%s/config";
|
||||||
|
const char state_topic_fmt[] = "fiatlux/light/fiatlux_%s/state";
|
||||||
|
const char set_topic_fmt[] = "fiatlux/light/fiatlux_%s/set";
|
||||||
|
|
||||||
extern "C" void mqtt_task(void *pvParameters) {
|
extern "C" void mqtt_task(void *pvParameters) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
mqtt_network network{};
|
mqtt_network network{};
|
||||||
|
@ -248,9 +252,16 @@ extern "C" void mqtt_task(void *pvParameters) {
|
||||||
mqtt_packet_connect_data_t data = mqtt_packet_connect_data_initializer;
|
mqtt_packet_connect_data_t data = mqtt_packet_connect_data_initializer;
|
||||||
|
|
||||||
mqtt_network_new(&network);
|
mqtt_network_new(&network);
|
||||||
memset(mqtt_client_id, 0, sizeof(mqtt_client_id));
|
snprintf(mqtt_client_id, sizeof(mqtt_client_id), "fiatlux-%s", get_my_id());
|
||||||
strcpy(mqtt_client_id, "fiatlux-");
|
char disco_msg[sizeof(disco_msg_fmt) + 24];
|
||||||
strcat(mqtt_client_id, get_my_id());
|
snprintf(disco_msg, sizeof(disco_msg), disco_msg_fmt, &get_my_id()[6], &get_my_id()[6], &get_my_id()[6],
|
||||||
|
&get_my_id()[6]);
|
||||||
|
char disco_topic[sizeof(disco_topic_fmt) + 6];
|
||||||
|
snprintf(disco_topic, sizeof(disco_topic), disco_topic_fmt, &get_my_id()[6]);
|
||||||
|
char state_topic[sizeof(state_topic_fmt) + 6];
|
||||||
|
snprintf(state_topic, sizeof(state_topic), state_topic_fmt, &get_my_id()[6]);
|
||||||
|
char set_topic[sizeof(set_topic_fmt) + 6];
|
||||||
|
snprintf(set_topic, sizeof(set_topic), set_topic_fmt, &get_my_id()[6]);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
xSemaphoreTake(wifi_alive, portMAX_DELAY);
|
xSemaphoreTake(wifi_alive, portMAX_DELAY);
|
||||||
|
@ -286,25 +297,20 @@ extern "C" void mqtt_task(void *pvParameters) {
|
||||||
|
|
||||||
//Mqtt auto dicovery
|
//Mqtt auto dicovery
|
||||||
|
|
||||||
mqtt_subscribe(&client, "fiatlux/light/fiatlux_test/set", MQTT_QOS1, topic_received);
|
mqtt_subscribe(&client, set_topic, MQTT_QOS1, topic_received);
|
||||||
//mqtt_subscribe(&client, "fiatlux/light/fiatlux_test/state", MQTT_QOS1, topic_received);
|
//mqtt_subscribe(&client, "fiatlux/light/fiatlux_test/state", MQTT_QOS1, topic_received);
|
||||||
xQueueReset(publish_queue);
|
xQueueReset(publish_queue);
|
||||||
|
|
||||||
{
|
{
|
||||||
const char *msg_txt = R"json({ "name": "Fiatlux Test 0",
|
|
||||||
"unique_id": "fiatlux_test",
|
|
||||||
"command_topic": "fiatlux/light/fiatlux_test/set",
|
|
||||||
"state_topic": "fiatlux/light/fiatlux_test/state",
|
|
||||||
"brightness": true, "schema": "json" })json";
|
|
||||||
mqtt_message_t message;
|
mqtt_message_t message;
|
||||||
message.payload = (void *) msg_txt;
|
message.payload = (void *) disco_msg;
|
||||||
message.payloadlen = strlen(msg_txt);
|
message.payloadlen = strlen(disco_msg);
|
||||||
message.dup = 0;
|
message.dup = 0;
|
||||||
message.qos = MQTT_QOS1;
|
message.qos = MQTT_QOS1;
|
||||||
message.retained = 0;
|
message.retained = 0;
|
||||||
ret = mqtt_publish(&client, "homeassistant/light/fiatlux_test/config", &message);
|
ret = mqtt_publish(&client, disco_topic, &message);
|
||||||
if(ret != MQTT_SUCCESS) {
|
if(ret != MQTT_SUCCESS) {
|
||||||
printf("error: %d %s\n", ret, msg_txt);
|
printf("error: %d %s\n", ret, disco_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +325,7 @@ extern "C" void mqtt_task(void *pvParameters) {
|
||||||
message.dup = 0;
|
message.dup = 0;
|
||||||
message.qos = MQTT_QOS1;
|
message.qos = MQTT_QOS1;
|
||||||
message.retained = 0;
|
message.retained = 0;
|
||||||
ret = mqtt_publish(&client, "fiatlux/light/fiatlux_test/state", &message);
|
ret = mqtt_publish(&client, state_topic, &message);
|
||||||
if(ret != MQTT_SUCCESS) {
|
if(ret != MQTT_SUCCESS) {
|
||||||
printf("error while publishing message: %d\n", ret);
|
printf("error while publishing message: %d\n", ret);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -351,6 +351,7 @@ extern "C" void wifi_task(void *pvParameters) {
|
||||||
//monitor loop connection here
|
//monitor loop connection here
|
||||||
uint8_t status = 0;
|
uint8_t status = 0;
|
||||||
uint8_t retries = 30;
|
uint8_t retries = 30;
|
||||||
|
uint32_t retry_delay = 100;
|
||||||
|
|
||||||
if(wifi_sta_enable) {
|
if(wifi_sta_enable) {
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -369,8 +370,10 @@ extern "C" void wifi_task(void *pvParameters) {
|
||||||
printf("WiFi: connection failed\r\n");
|
printf("WiFi: connection failed\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
vTaskDelay(retry_delay / portTICK_PERIOD_MS);
|
||||||
--retries;
|
--retries;
|
||||||
|
retry_delay *= 3;
|
||||||
|
retry_delay /= 2;
|
||||||
}
|
}
|
||||||
if(status == STATION_GOT_IP) {
|
if(status == STATION_GOT_IP) {
|
||||||
printf("WiFi: Connected\n\r");
|
printf("WiFi: Connected\n\r");
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7faa16b07ce0d606f9525a316990da5b58e61314
|
Subproject commit a8217311e0d8547127b69b7c4ead62ed3aa87b79
|
|
@ -86,49 +86,100 @@ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 12;
|
||||||
|
unsigned addr: 4;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint16_t _;
|
||||||
|
} cc48x6_frame;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CMD_NONE = 0,
|
||||||
|
CMD_READ = 1,
|
||||||
|
CMD_WRITE = 2,
|
||||||
|
CMD_INIT = 3,
|
||||||
|
CMD_RESET = 4,
|
||||||
|
CMD_VERSION = 5,
|
||||||
|
CMD_CONFIG = 6,
|
||||||
|
CMD_PING = 7
|
||||||
|
} bus_cmd;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 16;
|
||||||
|
unsigned addr: 8;
|
||||||
|
unsigned cmd: 8;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint32_t _;
|
||||||
|
} request_frame;
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
struct {
|
||||||
|
unsigned dat: 16;
|
||||||
|
unsigned addr: 8;
|
||||||
|
unsigned flags: 7;
|
||||||
|
unsigned: 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
uint32_t _;
|
||||||
|
} reply_frame;
|
||||||
|
|
||||||
|
uint8_t addr = 0;
|
||||||
|
|
||||||
void HAL_SPI_CpltCallback(SPI_HandleTypeDef *hspi) {
|
void HAL_SPI_CpltCallback(SPI_HandleTypeDef *hspi) {
|
||||||
|
|
||||||
if(RX_Buffer[0]) {
|
request_frame req = {._ = ((uint32_t) RX_Buffer[0]) << 16 | (uint32_t) RX_Buffer[1]};
|
||||||
union {
|
reply_frame rep = {._ = 0};
|
||||||
struct {
|
|
||||||
unsigned data: 12;
|
|
||||||
unsigned chan: 4;
|
|
||||||
} __attribute__((packed));
|
|
||||||
uint16_t raw;
|
|
||||||
|
|
||||||
} frame = {.raw=RX_Buffer[0]};
|
if(addr == 0) {
|
||||||
|
bool init = HAL_GPIO_ReadPin(INIT_IN_GPIO_Port, INIT_IN_Pin);
|
||||||
toggle = !toggle;
|
if(init && req.cmd == CMD_INIT) {
|
||||||
counter++;
|
addr = req.addr;
|
||||||
|
} else if(init) {
|
||||||
if(toggle) {
|
rep.flags = 5;
|
||||||
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_SET);
|
|
||||||
} else {
|
} else {
|
||||||
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_RESET);
|
rep.flags = 7;
|
||||||
}
|
}
|
||||||
|
} else if(addr == req.addr) {
|
||||||
|
if(req.cmd == CMD_PING){
|
||||||
|
rep.dat = req.dat;
|
||||||
|
}else {
|
||||||
|
cc48x6_frame frame = {._=req.dat};
|
||||||
|
|
||||||
if(frame.chan <= 6 && frame.chan >= 1) {
|
counter++;
|
||||||
frame.chan--;
|
|
||||||
if(frame.data > 0x300) {
|
toggle = !toggle;
|
||||||
mem[frame.chan * 2 + 1] = 0xFF;
|
if(toggle) {
|
||||||
mem[frame.chan * 2] = frame.data;
|
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_SET);
|
||||||
} else {
|
} else {
|
||||||
mem[frame.chan * 2 + 1] = (frame.data * 0xFF) / 0x300;
|
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_RESET);
|
||||||
mem[frame.chan * 2] = 0x300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dirty = true;
|
if(frame.addr <= 6 && frame.addr >= 1) {
|
||||||
TX_Buffer[0] = RX_Buffer[0];
|
frame.addr--;
|
||||||
|
if(frame.dat > 0x300) {
|
||||||
|
mem[frame.addr * 2 + 1] = 0xFF;
|
||||||
|
mem[frame.addr * 2] = frame.dat;
|
||||||
|
} else {
|
||||||
|
mem[frame.addr * 2 + 1] = (frame.dat * 0xFF) / 0x300;
|
||||||
|
mem[frame.addr * 2] = 0x300;
|
||||||
|
}
|
||||||
|
|
||||||
} else if(frame.chan == 15 && frame.data < 8) {
|
dirty = true;
|
||||||
TX_Buffer[0] = conf[frame.data];
|
rep.dat = req.dat;
|
||||||
} else {
|
|
||||||
TX_Buffer[0] = 0;
|
} else if(frame.addr == 15 && frame.dat < 8) {
|
||||||
|
TX_Buffer[0] = conf[frame.dat];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HAL_SPI_TransmitReceive_DMA(&hspi2, TX_Buffer, RX_Buffer, 1);
|
TX_Buffer[0] = rep._ >> 16;
|
||||||
|
TX_Buffer[1] = rep._ & 0xFFFF;
|
||||||
|
|
||||||
|
HAL_SPI_TransmitReceive_DMA(&hspi2, TX_Buffer, RX_Buffer, 2);
|
||||||
|
|
||||||
HAL_GPIO_WritePin(INIT_OUT_GPIO_Port, INIT_OUT_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(INIT_OUT_GPIO_Port, INIT_OUT_Pin, GPIO_PIN_SET);
|
||||||
for (volatile int i = 0; i < 3; i++);
|
for (volatile int i = 0; i < 3; i++);
|
||||||
|
@ -229,7 +280,7 @@ int main(void) {
|
||||||
|
|
||||||
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_SET);
|
HAL_GPIO_WritePin(SIGNAL_LED_GPIO_Port, SIGNAL_LED_Pin, GPIO_PIN_SET);
|
||||||
|
|
||||||
HAL_SPI_Receive_DMA(&hspi2, (uint8_t *) RX_Buffer, 1);
|
HAL_SPI_Receive_DMA(&hspi2, (uint8_t *) RX_Buffer, 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue