Send Queues (experimental)
This commit is contained in:
parent
862c339166
commit
7b35c6a539
@ -227,7 +227,7 @@ function Converter(decoded, port) {
|
||||
|
||||
The device listenes for remote control commands on LoRaWAN Port 2.
|
||||
|
||||
Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once.
|
||||
Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings send remote command 09 02 09 00 unconfirmed(!) once.
|
||||
|
||||
0x01 set scan RSSI limit
|
||||
|
||||
|
@ -16,7 +16,7 @@ void readButton() {
|
||||
ESP_LOGI(TAG, "Button pressed");
|
||||
payload.reset();
|
||||
payload.addButton(0x01);
|
||||
senddata(BUTTONPORT);
|
||||
EnqueueSendData(BUTTONPORT, payload.getBuffer(), payload.getSize());
|
||||
}
|
||||
}
|
||||
#endif
|
@ -37,7 +37,7 @@ void doHomework() {
|
||||
"Memory full, counter cleared (heap low water mark = %d Bytes / "
|
||||
"free heap = %d bytes)",
|
||||
esp_get_minimum_free_heap_size(), ESP.getFreeHeap());
|
||||
senddata(COUNTERPORT); // send data before clearing counters
|
||||
EnqueueSendData(COUNTERPORT, payload.getBuffer(), payload.getSize()); // send data before clearing counters
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
reset_salt(); // get new salt for salting hashes
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <esp32-hal-log.h>
|
||||
|
||||
// attn: increment version after modifications to configData_t truct!
|
||||
#define PROGVERSION "1.4.1" // use max 10 chars here!
|
||||
#define PROGVERSION "1.4.2" // use max 10 chars here!
|
||||
#define PROGNAME "PAXCNT"
|
||||
|
||||
// std::set for unified array functions
|
||||
|
@ -108,7 +108,7 @@ void get_hard_deveui(uint8_t *pdeveui) {
|
||||
#ifdef VERBOSE
|
||||
|
||||
// Display OTAA keys
|
||||
void printKeys(void) {
|
||||
void showLoraKeys(void) {
|
||||
// LMIC may not have used callback to fill
|
||||
// all EUI buffer so we do it here to a temp
|
||||
// buffer to be able to display them
|
||||
|
@ -13,7 +13,7 @@ void get_hard_deveui(uint8_t *pdeveui);
|
||||
void os_getDevKey(u1_t *buf);
|
||||
void os_getArtEui(u1_t *buf);
|
||||
void os_getDevEui(u1_t *buf);
|
||||
void printKeys(void);
|
||||
void showLoraKeys(void);
|
||||
void lorawan_loop(void *pvParameters);
|
||||
|
||||
#endif
|
@ -106,7 +106,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||
#endif
|
||||
payload.reset();
|
||||
payload.addAlarm(rssi, beaconID);
|
||||
senddata(BEACONPORT);
|
||||
EnqueueSendData(BEACONPORT, payload.getBuffer(), payload.getSize());
|
||||
}
|
||||
};
|
||||
|
||||
|
32
src/main.cpp
32
src/main.cpp
@ -41,6 +41,10 @@ hw_timer_t *channelSwitch = NULL, *displaytimer = NULL, *sendCycle = NULL,
|
||||
volatile int ButtonPressedIRQ = 0, ChannelTimerIRQ = 0, SendCycleTimerIRQ = 0,
|
||||
DisplayTimerIRQ = 0, HomeCycleIRQ = 0;
|
||||
|
||||
// send queues
|
||||
QueueHandle_t LoraSendQueue, SPISendQueue;
|
||||
MessageBuffer_t SendBuffer;
|
||||
|
||||
portMUX_TYPE timerMux =
|
||||
portMUX_INITIALIZER_UNLOCKED; // sync main loop and ISR when modifying IRQ
|
||||
// handler shared variables
|
||||
@ -104,10 +108,30 @@ void setup() {
|
||||
|
||||
#endif // verbose
|
||||
|
||||
// initialize send queues for transmit channels
|
||||
#ifdef HAS_LORA
|
||||
LoraSendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(struct SendBuffer *));
|
||||
if (LoraSendQueue == 0) {
|
||||
ESP_LOGE(TAG, "Could not create LORA send queue. Aborting.");
|
||||
exit(0);
|
||||
} else
|
||||
ESP_LOGI(TAG, "LORA send queue created, size %d Bytes",
|
||||
SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE);
|
||||
#endif
|
||||
#ifdef HAS_SPI
|
||||
SPISendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(struct SendBuffer *));
|
||||
if (SPISendQueue == 0) {
|
||||
ESP_LOGE(TAG, "Could not create SPI send queue. Aborting.");
|
||||
exit(0);
|
||||
} else
|
||||
ESP_LOGI(TAG, "SPI send queue created, size %d Bytes",
|
||||
SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE);
|
||||
#endif
|
||||
|
||||
// read settings from NVRAM
|
||||
loadConfig(); // includes initialize if necessary
|
||||
|
||||
#ifdef VENDORFILTER
|
||||
#ifdef VENDORFILTER
|
||||
strcat_P(features, " OUIFLT");
|
||||
#endif
|
||||
|
||||
@ -223,7 +247,7 @@ void setup() {
|
||||
#ifdef HAS_LORA
|
||||
// output LoRaWAN keys to console
|
||||
#ifdef VERBOSE
|
||||
printKeys();
|
||||
showLoraKeys();
|
||||
#endif
|
||||
|
||||
// initialize LoRaWAN LMIC run-time environment
|
||||
@ -299,7 +323,9 @@ void loop() {
|
||||
|
||||
// check housekeeping cycle and if expired do homework
|
||||
checkHousekeeping();
|
||||
// check send cycle and send payload if cycle is expired
|
||||
// check send queue and process it
|
||||
processSendBuffer();
|
||||
// check send cycle and enqueue payload if cycle is expired
|
||||
sendPayload();
|
||||
// reset watchdog
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define PAYLOAD_BUFFER_SIZE 51 // maximum size of payload block per transmit
|
||||
#define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs
|
||||
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
||||
#define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue
|
||||
|
||||
// Ports on which the device sends and listenes on LoRaWAN and SPI
|
||||
#define COUNTERPORT 1 // Port on which device sends counts
|
||||
|
@ -293,7 +293,7 @@ void get_config(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get device configuration");
|
||||
payload.reset();
|
||||
payload.addConfig(cfg);
|
||||
senddata(CONFIGPORT);
|
||||
EnqueueSendData(CONFIGPORT, payload.getBuffer(), payload.getSize());
|
||||
};
|
||||
|
||||
void get_status(uint8_t val[]) {
|
||||
@ -305,7 +305,7 @@ void get_status(uint8_t val[]) {
|
||||
#endif
|
||||
payload.reset();
|
||||
payload.addStatus(voltage, uptime() / 1000, temperatureRead());
|
||||
senddata(STATUSPORT);
|
||||
EnqueueSendData(STATUSPORT, payload.getBuffer(), payload.getSize());
|
||||
};
|
||||
|
||||
void get_gps(uint8_t val[]) {
|
||||
@ -314,7 +314,7 @@ void get_gps(uint8_t val[]) {
|
||||
gps_read();
|
||||
payload.reset();
|
||||
payload.addGPS(gps_status);
|
||||
senddata(GPSPORT);
|
||||
EnqueueSendData(GPSPORT, payload.getBuffer(), payload.getSize());
|
||||
#else
|
||||
ESP_LOGW(TAG, "GPS function not supported");
|
||||
#endif
|
||||
@ -337,6 +337,8 @@ cmd_t table[] = {
|
||||
{0x80, get_config, 0, false}, {0x81, get_status, 0, false},
|
||||
{0x84, get_gps, 0, false}};
|
||||
|
||||
const uint8_t cmdtablesize = sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||
|
||||
// check and execute remote command
|
||||
void rcommand(uint8_t cmd[], uint8_t cmdlength) {
|
||||
|
||||
@ -345,14 +347,13 @@ void rcommand(uint8_t cmd[], uint8_t cmdlength) {
|
||||
else
|
||||
cmdlength--; // minus 1 byte for opcode
|
||||
|
||||
int i =
|
||||
sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||
int i = cmdtablesize;
|
||||
|
||||
while (i--) {
|
||||
if ((cmd[0] == table[i].opcode) &&
|
||||
(table[i].params == cmdlength)) { // lookup command in opcode table
|
||||
memmove(cmd, cmd + 1,
|
||||
cmdlength); // strip opcode
|
||||
cmdlength); // strip opcode from cmd array
|
||||
table[i].func(cmd); // execute assigned function with given parameters
|
||||
if (table[i].store) // ceck if function needs to store configuration
|
||||
saveConfig();
|
||||
|
@ -1,28 +1,27 @@
|
||||
// Basic Config
|
||||
#include "globals.h"
|
||||
|
||||
void senddata(uint8_t port) {
|
||||
// put data to send in RTos Queues used for transmit over channels Lora and SPI
|
||||
void EnqueueSendData(uint8_t port, uint8_t data[], uint8_t size) {
|
||||
MessageBuffer_t *xMsg; // create pointer to struct which holds the sendbuffer
|
||||
|
||||
SendBuffer.MessageSize = size;
|
||||
SendBuffer.MessagePort = PAYLOAD_ENCODER <= 2
|
||||
? port
|
||||
: (PAYLOAD_ENCODER == 4 ? LPP2PORT : LPP1PORT);
|
||||
memcpy(SendBuffer.Message, data, size);
|
||||
xMsg = &SendBuffer;
|
||||
|
||||
// enqueue message in LoRa send queue
|
||||
#ifdef HAS_LORA
|
||||
// Check if there is a pending TX/RX job running
|
||||
if (LMIC.opmode & OP_TXRXPEND) {
|
||||
ESP_LOGI(TAG, "LoRa busy, data not sent");
|
||||
sprintf(display_line7, "LORA BUSY");
|
||||
// to be done: add queuing here, e.g. use RTos xQueueSend
|
||||
} else {
|
||||
LMIC_setTxData2(
|
||||
PAYLOAD_ENCODER <= 2 ? port
|
||||
: (PAYLOAD_ENCODER == 4 ? LPP2PORT : LPP1PORT),
|
||||
payload.getBuffer(), payload.getSize(), (cfg.countermode & 0x02));
|
||||
|
||||
ESP_LOGI(TAG, "%d bytes queued to send on LoRa", payload.getSize());
|
||||
sprintf(display_line7, "PACKET QUEUED");
|
||||
}
|
||||
xQueueSend(LoraSendQueue, (void *)&xMsg, (TickType_t)0);
|
||||
ESP_LOGI(TAG, "%d bytes enqueued to send on LoRa", size);
|
||||
#endif
|
||||
|
||||
// enqueue message in SPI send queue
|
||||
#ifdef HAS_SPI
|
||||
// to come here: code for sending payload to a local master via SPI
|
||||
ESP_LOGI(TAG, "%d bytes sent on SPI", payload.getSize());
|
||||
xQueueSend(SPISendQueue, (void *)&xMsg, (TickType_t)0);
|
||||
ESP_LOGI(TAG, "%d bytes enqueued to send on SPI", size);
|
||||
#endif
|
||||
|
||||
// clear counter if not in cumulative counter mode
|
||||
@ -34,8 +33,8 @@ void senddata(uint8_t port) {
|
||||
|
||||
} // senddata
|
||||
|
||||
// cyclic called function to prepare payload to send
|
||||
void sendPayload() {
|
||||
|
||||
if (SendCycleTimerIRQ) {
|
||||
portENTER_CRITICAL(&timerMux);
|
||||
SendCycleTimerIRQ = 0;
|
||||
@ -64,12 +63,46 @@ void sendPayload() {
|
||||
ESP_LOGD(TAG, "No valid GPS position or GPS data mode disabled");
|
||||
}
|
||||
#endif
|
||||
senddata(COUNTERPORT);
|
||||
EnqueueSendData(COUNTERPORT, payload.getBuffer(), payload.getSize());
|
||||
}
|
||||
} // sendpayload();
|
||||
} // sendpayload()
|
||||
|
||||
// interrupt handler used for payload send cycle timer
|
||||
void IRAM_ATTR SendCycleIRQ() {
|
||||
portENTER_CRITICAL(&timerMux);
|
||||
SendCycleTimerIRQ++;
|
||||
portEXIT_CRITICAL(&timerMux);
|
||||
}
|
||||
}
|
||||
|
||||
// cyclic called function to eat data from RTos send queues and transmit it
|
||||
void processSendBuffer() {
|
||||
MessageBuffer_t *xMsg;
|
||||
|
||||
#ifdef HAS_LORA
|
||||
// Check if there is a pending TX/RX job running
|
||||
if (LMIC.opmode & OP_TXRXPEND) {
|
||||
sprintf(display_line7, "LORA BUSY");
|
||||
} else {
|
||||
if (xQueueReceive(LoraSendQueue, &(xMsg), (TickType_t)10)) {
|
||||
// xMsg now holds the struct MessageBuffer from queue
|
||||
LMIC_setTxData2(xMsg->MessagePort, xMsg->Message, xMsg->MessageSize,
|
||||
(cfg.countermode & 0x02));
|
||||
ESP_LOGI(TAG, "%d bytes sent to LORA", xMsg->MessageSize);
|
||||
sprintf(display_line7, "PACKET QUEUED");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_SPI
|
||||
if (xQueueReceive(SPISendQueue, &(xMsg), (TickType_t)10)) {
|
||||
|
||||
// to come here: send data over SPI
|
||||
// use these pointers to the payload:
|
||||
// xMsg->MessagePort
|
||||
// xMsg->MessageSize
|
||||
// xMsg->Message
|
||||
|
||||
ESP_LOGI(TAG, "%d bytes sent to SPI", xMsg->MessageSize);
|
||||
}
|
||||
#endif
|
||||
} // processSendBuffer
|
@ -1,8 +1,19 @@
|
||||
#ifndef _SENDDATA_H
|
||||
#define _SENDDATA_H
|
||||
|
||||
void senddata(uint8_t port);
|
||||
// Struct holding payload for data send queue
|
||||
typedef struct {
|
||||
uint8_t MessageSize;
|
||||
uint8_t MessagePort;
|
||||
uint8_t Message[PAYLOAD_BUFFER_SIZE];
|
||||
} MessageBuffer_t;
|
||||
|
||||
extern QueueHandle_t LoraSendQueue, SPISendQueue;
|
||||
extern MessageBuffer_t SendBuffer;
|
||||
|
||||
void EnqueueSendData(uint8_t port, uint8_t data[], uint8_t size);
|
||||
void sendPayload(void);
|
||||
void SendCycleIRQ(void);
|
||||
void processSendBuffer(void);
|
||||
|
||||
#endif // _SENDDATA_H_
|
Loading…
Reference in New Issue
Block a user