Add shutdown function

This commit is contained in:
Manuel Bl 2020-07-31 20:14:40 +02:00
parent 8d7d157445
commit 625968cd99
10 changed files with 219 additions and 12 deletions

View File

@ -0,0 +1,9 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
get_filename_component(TTN_DIR ../.. ABSOLUTE)
set(EXTRA_COMPONENT_DIRS "${TTN_DIR}")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(send_recv)

View File

@ -0,0 +1,5 @@
PROJECT_NAME := shutdown
EXTRA_COMPONENT_DIRS := $(abspath ../..)
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,4 @@
set(COMPONENT_SRCS "main.cpp")
set(COMPONENT_ADD_INCLUDEDIRS "")
register_component()

View File

View File

@ -0,0 +1,137 @@
/*******************************************************************************
*
* ttn-esp32 - The Things Network device library for ESP-IDF / SX127x
*
* Copyright (c) 2018 Manuel Bleichenbacher
*
* Licensed under MIT License
* https://opensource.org/licenses/MIT
*
* Sample program showing how to send and receive messages.
*******************************************************************************/
#include "freertos/FreeRTOS.h"
#include "esp_event.h"
#include "driver/gpio.h"
#include "nvs_flash.h"
#include "TheThingsNetwork.h"
// NOTE:
// The LoRaWAN frequency and the radio chip must be configured by running 'make menuconfig'.
// Go to Components / The Things Network, select the appropriate values and save.
// Copy the below hex string from the "Device EUI" field
// on your device's overview page in the TTN console.
const char *devEui = "????????????????";
// Copy the below two lines from bottom of the same page
const char *appEui = "????????????????";
const char *appKey = "????????????????????????????????";
// Pins and other resources
#define TTN_SPI_HOST HSPI_HOST
#define TTN_SPI_DMA_CHAN 1
#define TTN_PIN_SPI_SCLK 5
#define TTN_PIN_SPI_MOSI 27
#define TTN_PIN_SPI_MISO 19
#define TTN_PIN_NSS 18
#define TTN_PIN_RXTX TTN_NOT_CONNECTED
#define TTN_PIN_RST 14
#define TTN_PIN_DIO0 26
#define TTN_PIN_DIO1 35
static TheThingsNetwork ttn;
const unsigned TX_INTERVAL = 30;
static uint8_t msgData[] = "Hello, world";
bool join()
{
printf("Joining...\n");
if (ttn.join())
{
printf("Joined.\n");
return true;
}
else
{
printf("Join failed. Goodbye\n");
return false;
}
}
void sendMessages(void* pvParameter)
{
while (1) {
// Send 2 messages
for (int i = 0; i < 2; i++)
{
printf("Sending message...\n");
TTNResponseCode res = ttn.transmitMessage(msgData, sizeof(msgData) - 1);
printf(res == kTTNSuccessfulTransmission ? "Message sent.\n" : "Transmission failed.\n");
vTaskDelay(TX_INTERVAL * pdMS_TO_TICKS(1000));
}
// shutdown
ttn.shutdown();
// go to sleep
printf("Sleeping for 30s...\n");
vTaskDelay(pdMS_TO_TICKS(30000));
// startup
ttn.startup();
// join again
if (!join())
return;
}
}
void messageReceived(const uint8_t* message, size_t length, port_t port)
{
printf("Message of %d bytes received on port %d:", length, port);
for (int i = 0; i < length; i++)
printf(" %02x", message[i]);
printf("\n");
}
extern "C" void app_main(void)
{
esp_err_t err;
// Initialize the GPIO ISR handler service
err = gpio_install_isr_service(ESP_INTR_FLAG_IRAM);
ESP_ERROR_CHECK(err);
// Initialize the NVS (non-volatile storage) for saving and restoring the keys
err = nvs_flash_init();
ESP_ERROR_CHECK(err);
// Initialize SPI bus
spi_bus_config_t spi_bus_config;
spi_bus_config.miso_io_num = TTN_PIN_SPI_MISO;
spi_bus_config.mosi_io_num = TTN_PIN_SPI_MOSI;
spi_bus_config.sclk_io_num = TTN_PIN_SPI_SCLK;
spi_bus_config.quadwp_io_num = -1;
spi_bus_config.quadhd_io_num = -1;
spi_bus_config.max_transfer_sz = 0;
err = spi_bus_initialize(TTN_SPI_HOST, &spi_bus_config, TTN_SPI_DMA_CHAN);
ESP_ERROR_CHECK(err);
// Configure the SX127x pins
ttn.configurePins(TTN_SPI_HOST, TTN_PIN_NSS, TTN_PIN_RXTX, TTN_PIN_RST, TTN_PIN_DIO0, TTN_PIN_DIO1);
// The below line can be commented after the first run as the data is saved in NVS
ttn.provision(devEui, appEui, appKey);
ttn.onMessage(messageReceived);
if (join())
{
xTaskCreate(sendMessages, "send_messages", 1024 * 4, (void* )0, 3, nullptr);
}
}

View File

@ -68,7 +68,8 @@ public:
/**
* @brief Reset the LoRaWAN radio.
*
* Does not clear provisioned keys.
* To restart communication, `join()` must be called.
* Neither clears the provisioned keys nor the configured pins.
*/
void reset();
@ -76,8 +77,8 @@ public:
* @brief Configures the pins used to communicate with the LoRaWAN radio chip.
*
*
* The SPI bus must be first configured using spi_bus_initialize(). Then it is passed as the first parameter.
* Additionally, 'gpio_install_isr_service()' must be called to initialize the GPIO ISR handler service.
* Before calling this member function, the SPI bus needs to be configured using `spi_bus_initialize()`.
* Additionally, `gpio_install_isr_service()` must have been called to initialize the GPIO ISR handler service.
*
* @param spi_host The SPI bus/peripherial to use (SPI_HOST, HSPI_HOST or VSPI_HOST).
* @param nss The GPIO pin number connected to the radio chip's NSS pin (serving as the SPI chip select)
@ -229,6 +230,7 @@ public:
/**
* Returns whether Adaptive Data Rate (ADR) is enabled.
*
* @return true if enabled
* @return false if disabled
*/
@ -244,6 +246,21 @@ public:
*/
void setAdrEnabled(bool enabled);
/**
* @brief Stops all activies and shuts down the RF module and the background tasks.
*
* To restart communication, `startup()` and `join()` must be called.
* Neither clears the provisioned keys nor the configured pins.
*/
void shutdown();
/**
* @brief Restarts the background tasks and RF module.
*
* This member function must only be called after a call to `shutdowna()`.
*/
void startup();
private:
TTNMessageCallback messageCallback;

View File

@ -97,6 +97,7 @@ void ttn_provisioning_task_caller(void* pvParameter)
{
TTNProvisioning* provisioning = (TTNProvisioning*)pvParameter;
provisioning->provisioningTask();
vTaskDelete(nullptr);
}
void TTNProvisioning::provisioningTask()
@ -132,7 +133,6 @@ void TTNProvisioning::provisioningTask()
free(line_buf);
uart_driver_delete(UART_NUM);
vTaskDelete(nullptr);
}
void TTNProvisioning::addLineData(int numBytes)

View File

@ -111,10 +111,23 @@ void TheThingsNetwork::reset()
ttn_hal.enterCriticalSection();
LMIC_reset();
waitingReason = eWaitingNone;
if (lmicEventQueue != nullptr)
{
xQueueReset(lmicEventQueue);
}
ttn_hal.leaveCriticalSection();
}
void TheThingsNetwork::shutdown()
{
ttn_hal.enterCriticalSection();
LMIC_shutdown();
ttn_hal.stopLMICTask();
waitingReason = eWaitingNone;
ttn_hal.leaveCriticalSection();
}
void TheThingsNetwork::startup()
{
ttn_hal.enterCriticalSection();
LMIC_reset();
ttn_hal.startLMICTask();
ttn_hal.leaveCriticalSection();
}
@ -194,6 +207,7 @@ bool TheThingsNetwork::joinCore()
}
ttn_hal.enterCriticalSection();
xQueueReset(lmicEventQueue);
waitingReason = eWaitingForJoin;
LMIC_startJoining();
ttn_hal.wakeUp();

View File

@ -25,6 +25,7 @@
#define NOTIFY_BIT_DIO 1
#define NOTIFY_BIT_TIMER 2
#define NOTIFY_BIT_WAKEUP 4
#define NOTIFY_BIT_STOP 8
static const char* const TAG = "ttn_hal";
@ -305,6 +306,9 @@ bool HAL_ESP32::wait(WaitKind waitKind)
if (bits == 0)
return false;
if ((bits & NOTIFY_BIT_STOP) != 0)
return false;
if ((bits & NOTIFY_BIT_WAKEUP) != 0)
{
if (waitKind != WAIT_FOR_TIMER)
@ -449,8 +453,12 @@ void HAL_ESP32::leaveCriticalSection()
// -----------------------------------------------------------------------------
void HAL_ESP32::lmicBackgroundTask(void* pvParameter) {
os_runloop();
void HAL_ESP32::lmicBackgroundTask(void* pvParameter)
{
HAL_ESP32* instance = (HAL_ESP32*)pvParameter;
while (instance->runBackgroundTask)
os_runloop_once();
vTaskDelete(nullptr);
}
void hal_init_ex(const void *pContext)
@ -468,14 +476,25 @@ void HAL_ESP32::init()
timerInit();
}
void HAL_ESP32::startLMICTask() {
xTaskCreate(lmicBackgroundTask, "ttn_lmic", 1024 * 4, nullptr, CONFIG_TTN_BG_TASK_PRIO, &lmicTask);
void HAL_ESP32::startLMICTask()
{
runBackgroundTask = true;
xTaskCreate(lmicBackgroundTask, "ttn_lmic", 1024 * 4, this, CONFIG_TTN_BG_TASK_PRIO, &lmicTask);
// enable interrupts
gpio_isr_handler_add(pinDIO0, dioIrqHandler, (void *)0);
gpio_isr_handler_add(pinDIO1, dioIrqHandler, (void *)1);
}
void HAL_ESP32::stopLMICTask()
{
runBackgroundTask = false;
gpio_isr_handler_remove(pinDIO0);
gpio_isr_handler_remove(pinDIO1);
disarmTimer();
xTaskNotify(lmicTask, NOTIFY_BIT_STOP, eSetBits);
}
// -----------------------------------------------------------------------------
// Fatal failure

View File

@ -39,6 +39,7 @@ public:
void configurePins(spi_host_device_t spi_host, uint8_t nss, uint8_t rxtx, uint8_t rst, uint8_t dio0, uint8_t dio1);
void init();
void startLMICTask();
void stopLMICTask();
void wakeUp();
void initCriticalSection();
@ -84,6 +85,7 @@ private:
SemaphoreHandle_t mutex;
esp_timer_handle_t timer;
int64_t nextAlarm;
volatile bool runBackgroundTask;
};
extern HAL_ESP32 ttn_hal;