Add shutdown function
This commit is contained in:
parent
8d7d157445
commit
625968cd99
|
@ -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)
|
|
@ -0,0 +1,5 @@
|
|||
PROJECT_NAME := shutdown
|
||||
|
||||
EXTRA_COMPONENT_DIRS := $(abspath ../..)
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
|
@ -0,0 +1,4 @@
|
|||
set(COMPONENT_SRCS "main.cpp")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||
|
||||
register_component()
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue