mirror of
https://github.com/manuelbl/ttn-esp32.git
synced 2025-06-15 04:14:28 +02:00
Add shutdown function
This commit is contained in:
parent
8d7d157445
commit
625968cd99
9
examples/shutdown/CMakeLists.txt
Normal file
9
examples/shutdown/CMakeLists.txt
Normal 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)
|
5
examples/shutdown/Makefile
Normal file
5
examples/shutdown/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
PROJECT_NAME := shutdown
|
||||||
|
|
||||||
|
EXTRA_COMPONENT_DIRS := $(abspath ../..)
|
||||||
|
|
||||||
|
include $(IDF_PATH)/make/project.mk
|
4
examples/shutdown/main/CMakeLists.txt
Normal file
4
examples/shutdown/main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
set(COMPONENT_SRCS "main.cpp")
|
||||||
|
set(COMPONENT_ADD_INCLUDEDIRS "")
|
||||||
|
|
||||||
|
register_component()
|
0
examples/shutdown/main/component.mk
Normal file
0
examples/shutdown/main/component.mk
Normal file
137
examples/shutdown/main/main.cpp
Normal file
137
examples/shutdown/main/main.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -68,7 +68,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @brief Reset the LoRaWAN radio.
|
* @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();
|
void reset();
|
||||||
|
|
||||||
@ -76,8 +77,8 @@ public:
|
|||||||
* @brief Configures the pins used to communicate with the LoRaWAN radio chip.
|
* @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.
|
* Before calling this member function, the SPI bus needs to be configured using `spi_bus_initialize()`.
|
||||||
* Additionally, 'gpio_install_isr_service()' must be called to initialize the GPIO ISR handler service.
|
* 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 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)
|
* @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.
|
* Returns whether Adaptive Data Rate (ADR) is enabled.
|
||||||
|
*
|
||||||
* @return true if enabled
|
* @return true if enabled
|
||||||
* @return false if disabled
|
* @return false if disabled
|
||||||
*/
|
*/
|
||||||
@ -244,6 +246,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
void setAdrEnabled(bool enabled);
|
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:
|
private:
|
||||||
TTNMessageCallback messageCallback;
|
TTNMessageCallback messageCallback;
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ void ttn_provisioning_task_caller(void* pvParameter)
|
|||||||
{
|
{
|
||||||
TTNProvisioning* provisioning = (TTNProvisioning*)pvParameter;
|
TTNProvisioning* provisioning = (TTNProvisioning*)pvParameter;
|
||||||
provisioning->provisioningTask();
|
provisioning->provisioningTask();
|
||||||
|
vTaskDelete(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTNProvisioning::provisioningTask()
|
void TTNProvisioning::provisioningTask()
|
||||||
@ -132,7 +133,6 @@ void TTNProvisioning::provisioningTask()
|
|||||||
|
|
||||||
free(line_buf);
|
free(line_buf);
|
||||||
uart_driver_delete(UART_NUM);
|
uart_driver_delete(UART_NUM);
|
||||||
vTaskDelete(nullptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TTNProvisioning::addLineData(int numBytes)
|
void TTNProvisioning::addLineData(int numBytes)
|
||||||
|
@ -111,10 +111,23 @@ void TheThingsNetwork::reset()
|
|||||||
ttn_hal.enterCriticalSection();
|
ttn_hal.enterCriticalSection();
|
||||||
LMIC_reset();
|
LMIC_reset();
|
||||||
waitingReason = eWaitingNone;
|
waitingReason = eWaitingNone;
|
||||||
if (lmicEventQueue != nullptr)
|
ttn_hal.leaveCriticalSection();
|
||||||
{
|
}
|
||||||
xQueueReset(lmicEventQueue);
|
|
||||||
}
|
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();
|
ttn_hal.leaveCriticalSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +207,7 @@ bool TheThingsNetwork::joinCore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ttn_hal.enterCriticalSection();
|
ttn_hal.enterCriticalSection();
|
||||||
|
xQueueReset(lmicEventQueue);
|
||||||
waitingReason = eWaitingForJoin;
|
waitingReason = eWaitingForJoin;
|
||||||
LMIC_startJoining();
|
LMIC_startJoining();
|
||||||
ttn_hal.wakeUp();
|
ttn_hal.wakeUp();
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define NOTIFY_BIT_DIO 1
|
#define NOTIFY_BIT_DIO 1
|
||||||
#define NOTIFY_BIT_TIMER 2
|
#define NOTIFY_BIT_TIMER 2
|
||||||
#define NOTIFY_BIT_WAKEUP 4
|
#define NOTIFY_BIT_WAKEUP 4
|
||||||
|
#define NOTIFY_BIT_STOP 8
|
||||||
|
|
||||||
|
|
||||||
static const char* const TAG = "ttn_hal";
|
static const char* const TAG = "ttn_hal";
|
||||||
@ -305,6 +306,9 @@ bool HAL_ESP32::wait(WaitKind waitKind)
|
|||||||
if (bits == 0)
|
if (bits == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if ((bits & NOTIFY_BIT_STOP) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
if ((bits & NOTIFY_BIT_WAKEUP) != 0)
|
if ((bits & NOTIFY_BIT_WAKEUP) != 0)
|
||||||
{
|
{
|
||||||
if (waitKind != WAIT_FOR_TIMER)
|
if (waitKind != WAIT_FOR_TIMER)
|
||||||
@ -449,8 +453,12 @@ void HAL_ESP32::leaveCriticalSection()
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void HAL_ESP32::lmicBackgroundTask(void* pvParameter) {
|
void HAL_ESP32::lmicBackgroundTask(void* pvParameter)
|
||||||
os_runloop();
|
{
|
||||||
|
HAL_ESP32* instance = (HAL_ESP32*)pvParameter;
|
||||||
|
while (instance->runBackgroundTask)
|
||||||
|
os_runloop_once();
|
||||||
|
vTaskDelete(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hal_init_ex(const void *pContext)
|
void hal_init_ex(const void *pContext)
|
||||||
@ -468,14 +476,25 @@ void HAL_ESP32::init()
|
|||||||
timerInit();
|
timerInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_ESP32::startLMICTask() {
|
void HAL_ESP32::startLMICTask()
|
||||||
xTaskCreate(lmicBackgroundTask, "ttn_lmic", 1024 * 4, nullptr, CONFIG_TTN_BG_TASK_PRIO, &lmicTask);
|
{
|
||||||
|
runBackgroundTask = true;
|
||||||
|
xTaskCreate(lmicBackgroundTask, "ttn_lmic", 1024 * 4, this, CONFIG_TTN_BG_TASK_PRIO, &lmicTask);
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
gpio_isr_handler_add(pinDIO0, dioIrqHandler, (void *)0);
|
gpio_isr_handler_add(pinDIO0, dioIrqHandler, (void *)0);
|
||||||
gpio_isr_handler_add(pinDIO1, dioIrqHandler, (void *)1);
|
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
|
// 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 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 init();
|
||||||
void startLMICTask();
|
void startLMICTask();
|
||||||
|
void stopLMICTask();
|
||||||
|
|
||||||
void wakeUp();
|
void wakeUp();
|
||||||
void initCriticalSection();
|
void initCriticalSection();
|
||||||
@ -84,6 +85,7 @@ private:
|
|||||||
SemaphoreHandle_t mutex;
|
SemaphoreHandle_t mutex;
|
||||||
esp_timer_handle_t timer;
|
esp_timer_handle_t timer;
|
||||||
int64_t nextAlarm;
|
int64_t nextAlarm;
|
||||||
|
volatile bool runBackgroundTask;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HAL_ESP32 ttn_hal;
|
extern HAL_ESP32 ttn_hal;
|
||||||
|
Loading…
Reference in New Issue
Block a user