commit
b9584a2fdf
@ -364,7 +364,7 @@ Hereafter described is the default *plain* format, which uses MSB bit numbering.
|
||||
|
||||
# Remote control
|
||||
|
||||
The device listenes for remote control commands on LoRaWAN Port 2. Multiple commands per downlink are possible by concatenating them.
|
||||
The device listenes for remote control commands on LoRaWAN Port 2. Multiple commands per downlink are possible by concatenating them, but must not exceed a maximum of 10 bytes per downlink.
|
||||
|
||||
Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||
|
||||
|
@ -15,6 +15,11 @@
|
||||
#include "timesync.h"
|
||||
#include "blescan.h"
|
||||
|
||||
// maximum number of elements in rcommand interpreter queue
|
||||
#define RCMD_QUEUE_SIZE 5
|
||||
|
||||
extern TaskHandle_t rcmdTask;
|
||||
|
||||
// table of remote commands and assigned functions
|
||||
typedef struct {
|
||||
const uint8_t opcode;
|
||||
@ -23,9 +28,16 @@ typedef struct {
|
||||
const bool store;
|
||||
} cmd_t;
|
||||
|
||||
extern bool rcmd_busy;
|
||||
// Struct for remote command processing queue
|
||||
typedef struct {
|
||||
uint8_t cmd[10];
|
||||
uint8_t cmdLen;
|
||||
} RcmdBuffer_t;
|
||||
|
||||
void rcommand(const uint8_t cmd[], const uint8_t cmdlength);
|
||||
void do_reset(bool warmstart);
|
||||
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength);
|
||||
void rcmd_queuereset(void);
|
||||
uint32_t rcmd_queuewaiting(void);
|
||||
void rcmd_deinit(void);
|
||||
esp_err_t rcmd_init(void);
|
||||
|
||||
#endif
|
||||
|
@ -277,12 +277,11 @@ void start_BLEscan(void) {
|
||||
// Register callback function for capturing bluetooth packets
|
||||
register_ble_callback(false);
|
||||
ESP_LOGI(TAG, "Bluetooth scanner started");
|
||||
#endif // BLECOUNTER
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Bluetooth controller start failed. Resetting device");
|
||||
do_reset(true);
|
||||
}
|
||||
|
||||
#endif // BLECOUNTER
|
||||
} // start_BLEscan
|
||||
|
||||
void stop_BLEscan(void) {
|
||||
|
@ -14,7 +14,7 @@ extern boolean isSDS011Active;
|
||||
#endif
|
||||
|
||||
void setCyclicIRQ() {
|
||||
xTaskNotifyFromISR(irqHandlerTask, CYCLIC_IRQ, eSetBits, NULL);
|
||||
xTaskNotify(irqHandlerTask, CYCLIC_IRQ, eSetBits);
|
||||
}
|
||||
|
||||
// do all housekeeping
|
||||
@ -34,6 +34,8 @@ void doHousekeeping() {
|
||||
ESP_LOGD(TAG, "MACprocessor %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(macProcessTask),
|
||||
eTaskGetState(macProcessTask));
|
||||
ESP_LOGD(TAG, "Rcommand interpreter %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(rcmdTask), eTaskGetState(rcmdTask));
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
||||
|
@ -19,7 +19,7 @@ RTC_DATA_ATTR lmic_t RTC_LMIC;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
QueueHandle_t LoraSendQueue;
|
||||
static QueueHandle_t LoraSendQueue;
|
||||
TaskHandle_t lmicTask = NULL, lorasendTask = NULL;
|
||||
|
||||
class MyHalConfig_t : public Arduino_LMIC::HalConfiguration_t {
|
||||
|
@ -6,7 +6,7 @@
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
QueueHandle_t MacQueue;
|
||||
static QueueHandle_t MacQueue;
|
||||
TaskHandle_t macProcessTask;
|
||||
|
||||
static uint32_t salt = renew_salt();
|
||||
|
13
src/main.cpp
13
src/main.cpp
@ -38,7 +38,8 @@ timesync_proc 1 3 processes realtime time sync requests
|
||||
irqhandler 1 2 cyclic tasks (i.e. displayrefresh) triggered by timers
|
||||
gpsloop 1 1 reads data from GPS via serial or i2c
|
||||
lorasendtask 1 1 feeds data from lora sendqueue to lmcic
|
||||
macprocess 1 1 analyzes sniffed MACs
|
||||
macprocess 1 1 MAC analyzer loop
|
||||
rmcd_process 1 1 Remote command interpreter loop
|
||||
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
|
||||
|
||||
Low priority numbers denote low priority tasks.
|
||||
@ -60,8 +61,10 @@ irqHandlerTask (Core 1), see irqhandler.cpp
|
||||
|
||||
fired by hardware
|
||||
DisplayIRQ -> esp32 timer 0
|
||||
ButtonIRQ -> external gpio
|
||||
PMUIRQ -> PMU chip gpio
|
||||
CLOCKIRQ -> esp32 timer 1 or external GPIO (RTC_INT or GPS_INT)
|
||||
MatrixDisplayIRQ-> esp32 timer 3
|
||||
ButtonIRQ -> external GPIO
|
||||
PMUIRQ -> PMU chip GPIO
|
||||
|
||||
fired by software (Ticker.h)
|
||||
TIMESYNC_IRQ -> setTimeSyncIRQ()
|
||||
@ -291,6 +294,10 @@ void setup() {
|
||||
ESP_LOGI(TAG, "Starting MAC processor...");
|
||||
macQueueInit();
|
||||
|
||||
// start rcommand processing task
|
||||
ESP_LOGI(TAG, "Starting rcommand interpreter...");
|
||||
rcmd_init();
|
||||
|
||||
// start BLE scan callback if BLE function is enabled in NVRAM configuration
|
||||
// or remove bluetooth stack from RAM, if option bluetooth is not compiled
|
||||
#if (BLECOUNTER)
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
QueueHandle_t MQTTSendQueue;
|
||||
static QueueHandle_t MQTTSendQueue;
|
||||
TaskHandle_t mqttTask;
|
||||
|
||||
Ticker mqttTimer;
|
||||
@ -12,6 +12,7 @@ WiFiClient netClient;
|
||||
MQTTClient mqttClient;
|
||||
|
||||
void mqtt_deinit(void) {
|
||||
mqttClient.unsubscribe(MQTT_INTOPIC);
|
||||
mqttClient.onMessageAdvanced(NULL);
|
||||
mqttClient.disconnect();
|
||||
vTaskDelete(mqttTask);
|
||||
@ -22,6 +23,7 @@ esp_err_t mqtt_init(void) {
|
||||
// setup network connection and MQTT client
|
||||
ETH.begin();
|
||||
mqttClient.begin(MQTT_SERVER, MQTT_PORT, netClient);
|
||||
mqttClient.setKeepAlive(MQTT_KEEPALIVE);
|
||||
mqttClient.onMessageAdvanced(mqtt_callback);
|
||||
|
||||
_ASSERT(SEND_QUEUE_SIZE > 0);
|
||||
|
@ -5,8 +5,8 @@
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
// global variable indicating if rcommand() is executing
|
||||
bool rcmd_busy = false;
|
||||
static QueueHandle_t RcmdQueue;
|
||||
TaskHandle_t rcmdTask;
|
||||
|
||||
// set of functions that can be triggered by remote commands
|
||||
void set_reset(uint8_t val[]) {
|
||||
@ -396,14 +396,13 @@ static const uint8_t cmdtablesize =
|
||||
sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||
|
||||
// check and execute remote command
|
||||
void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
|
||||
void rcmd_execute(const uint8_t cmd[], const uint8_t cmdlength) {
|
||||
|
||||
if (cmdlength == 0)
|
||||
return;
|
||||
|
||||
uint8_t foundcmd[cmdlength], cursor = 0;
|
||||
bool storeflag = false;
|
||||
rcmd_busy = true;
|
||||
|
||||
while (cursor < cmdlength) {
|
||||
|
||||
@ -436,6 +435,65 @@ void rcommand(const uint8_t cmd[], const uint8_t cmdlength) {
|
||||
if (storeflag)
|
||||
saveConfig();
|
||||
|
||||
rcmd_busy = false;
|
||||
} // rcmd_execute()
|
||||
|
||||
// remote command processing task
|
||||
void rcmd_process(void *pvParameters) {
|
||||
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
|
||||
|
||||
RcmdBuffer_t RcmdBuffer;
|
||||
|
||||
while (1) {
|
||||
// fetch next or wait for incoming rcommand from queue
|
||||
if (xQueueReceive(RcmdQueue, &RcmdBuffer, portMAX_DELAY) != pdTRUE) {
|
||||
ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!");
|
||||
continue;
|
||||
}
|
||||
rcmd_execute(RcmdBuffer.cmd, RcmdBuffer.cmdLen);
|
||||
}
|
||||
|
||||
delay(2); // yield to CPU
|
||||
} // rcmd_process()
|
||||
|
||||
// enqueue remote command
|
||||
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength) {
|
||||
|
||||
RcmdBuffer_t rcmd = {0};
|
||||
|
||||
rcmd.cmdLen = cmdlength;
|
||||
memcpy(rcmd.cmd, cmd, cmdlength);
|
||||
|
||||
if (xQueueSendToBack(RcmdQueue, (void *)&rcmd, (TickType_t)0) != pdTRUE)
|
||||
ESP_LOGW(TAG, "Remote command queue is full");
|
||||
} // rcommand()
|
||||
|
||||
void rcmd_queuereset(void) { xQueueReset(RcmdQueue); }
|
||||
|
||||
uint32_t rcmd_queuewaiting(void) { return uxQueueMessagesWaiting(RcmdQueue); }
|
||||
|
||||
void rcmd_deinit(void) {
|
||||
rcmd_queuereset();
|
||||
vTaskDelete(rcmdTask);
|
||||
}
|
||||
|
||||
esp_err_t rcmd_init(void) {
|
||||
|
||||
_ASSERT(RCMD_QUEUE_SIZE > 0);
|
||||
RcmdQueue = xQueueCreate(RCMD_QUEUE_SIZE, sizeof(RcmdBuffer_t));
|
||||
if (RcmdQueue == 0) {
|
||||
ESP_LOGE(TAG, "Could not create rcommand send queue. Aborting.");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Rcommand send queue created, size %d Bytes",
|
||||
RCMD_QUEUE_SIZE * sizeof(RcmdBuffer_t));
|
||||
|
||||
xTaskCreatePinnedToCore(rcmd_process, // task function
|
||||
"rcmdloop", // name of task
|
||||
3072, // stack size of task
|
||||
(void *)1, // parameter of the task
|
||||
1, // priority of the task
|
||||
&rcmdTask, // task handle
|
||||
1); // CPU core
|
||||
|
||||
return ESP_OK;
|
||||
} // rcmd_init()
|
@ -143,14 +143,6 @@ void enter_deepsleep(const uint64_t wakeup_sec, gpio_num_t wakeup_gpio) {
|
||||
spi_deinit();
|
||||
#endif
|
||||
|
||||
// wait until rcommands are all done
|
||||
for (i = 10; i > 0; i--) {
|
||||
if (rcmd_busy)
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// save LMIC state to RTC RAM
|
||||
#if (HAS_LORA)
|
||||
SaveLMICToRTC(wakeup_sec);
|
||||
|
@ -4,7 +4,7 @@
|
||||
Ticker sendTimer;
|
||||
|
||||
void setSendIRQ() {
|
||||
xTaskNotifyFromISR(irqHandlerTask, SENDCYCLE_IRQ, eSetBits, NULL);
|
||||
xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
|
||||
}
|
||||
|
||||
// put data to send in RTos Queues used for transmit over channels Lora and SPI
|
||||
@ -12,8 +12,7 @@ void SendPayload(uint8_t port) {
|
||||
|
||||
ESP_LOGD(TAG, "sending Payload for Port %d", port);
|
||||
|
||||
MessageBuffer_t
|
||||
SendBuffer; // contains MessageSize, MessagePort, Message[]
|
||||
MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[]
|
||||
|
||||
SendBuffer.MessageSize = payload.getSize();
|
||||
|
||||
@ -190,6 +189,7 @@ void sendData() {
|
||||
} // sendData()
|
||||
|
||||
void flushQueues(void) {
|
||||
rcmd_queuereset();
|
||||
#if (HAS_LORA)
|
||||
lora_queuereset();
|
||||
#endif
|
||||
@ -202,7 +202,7 @@ void flushQueues(void) {
|
||||
}
|
||||
|
||||
bool allQueuesEmtpy(void) {
|
||||
uint32_t rc = 0;
|
||||
uint32_t rc = rcmd_queuewaiting();
|
||||
#if (HAS_LORA)
|
||||
rc += lora_queuewaiting();
|
||||
#endif
|
||||
|
@ -43,7 +43,7 @@ static const char TAG[] = __FILE__;
|
||||
DMA_ATTR uint8_t txbuf[BUFFER_SIZE];
|
||||
DMA_ATTR uint8_t rxbuf[BUFFER_SIZE];
|
||||
|
||||
QueueHandle_t SPISendQueue;
|
||||
static QueueHandle_t SPISendQueue;
|
||||
|
||||
TaskHandle_t spiTask;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user