mirror of
				https://github.com/manuelbl/ttn-esp32.git
				synced 2025-10-31 10:40:35 +01:00 
			
		
		
		
	Prepare for deep sleep functions
This commit is contained in:
		| @ -436,17 +436,6 @@ class TheThingsNetwork | ||||
|     { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Resets the LoRaWAN radio. | ||||
|      * | ||||
|      * To restart communication, @ref join() must be called. | ||||
|      * Clears neither the provisioned keys nor the configured pins. | ||||
|      */ | ||||
|     void reset() | ||||
|     { | ||||
|         ttn_reset(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Configures the pins used to communicate with the LoRaWAN radio chip. | ||||
|      * | ||||
| @ -553,11 +542,14 @@ class TheThingsNetwork | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Activates the device via OTAA. | ||||
|      * @brief Activates the device via OTAA using previously provisioned keys. | ||||
|      * | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey must have already been provisioned by a call to provision(). | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey must have already been provisioned by a call | ||||
|      * to @ref provision() or @ref provisionWithMAC(). | ||||
|      * Before this function is called, `nvs_flash_init()` must have been called once. | ||||
|      * | ||||
|      * The RF module is initialized and the TTN background task is started. | ||||
|      * | ||||
|      * The function blocks until the activation has completed or failed. | ||||
|      * | ||||
|      * @return `true` if the activation was succesful, `false` if the activation failed | ||||
| @ -568,9 +560,12 @@ class TheThingsNetwork | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Sets the DevEUI, AppEUI/JoinEUI and AppKey and activate the device via OTAA. | ||||
|      * @brief Activates the device via OTAA using the provided keys. | ||||
|      * | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey are NOT saved in non-volatile memory. | ||||
|      * For the activation, the provided DevEUI, AppEUI/JoinEUI and AppKey are used. | ||||
|      * They are NOT saved in non-volatile memory. | ||||
|      * | ||||
|      * The RF module is initialized and the TTN background task is started. | ||||
|      * | ||||
|      * The function blocks until the activation has completed or failed. | ||||
|      * | ||||
| @ -584,6 +579,78 @@ class TheThingsNetwork | ||||
|         return ttn_join(devEui, appEui, appKey); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Resumes TTN communication after deep sleep. | ||||
|      *  | ||||
|      * The communcation state is restored from data previously saved in RTC memory. | ||||
|      * The RF module and the TTN background task are started. | ||||
|      *  | ||||
|      * This function is called instead of @ref join() or @ref join(const char*, const char*, const char*) | ||||
|      * to continue with the established communication and to avoid a further join procedure. | ||||
|      * | ||||
|      * @return `true` if the device was able to resume, `false` otherwise. | ||||
|      */ | ||||
|     bool resumeAfterDeepSleep() | ||||
|     { | ||||
|         return ttn_resume_after_deep_sleep(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies and prepares for deep sleep. | ||||
|      *  | ||||
|      * This function is called before entering deep sleep. It saves the current | ||||
|      * communication state in RTC memory and shuts down the RF module and the | ||||
|      * TTN background task. | ||||
|      *  | ||||
|      * It neither clears the provisioned keys nor the configured pins | ||||
|      * but they will be lost if the device goes into deep sleep. | ||||
|      *  | ||||
|      * Before calling this function, use @ref busyDuration() to check | ||||
|      * that the TTN device is idle and ready to go to deep sleep. | ||||
|      *  | ||||
|      * To restart communication, @ref resumeAfterDeepSleep() must be called. | ||||
|      */ | ||||
|     void prepareForDeepSleep() | ||||
|     { | ||||
|         ttn_prepare_for_deep_sleep(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Returns the minimum duration the TTN device is busy. | ||||
|      *  | ||||
|      * This function can be called to check whether the TTN device is | ||||
|      * still involved in communication or ready to go to deep sleep or | ||||
|      * to be powered off. | ||||
|      *  | ||||
|      * If it returns 0, the TTN communication is idle and the device can go | ||||
|      * to deep sleep or can be powered off. | ||||
|      *  | ||||
|      * If it returns a value different from 0, the value indicates the duration | ||||
|      * the device will be certainly busy. After that time, this function must be | ||||
|      * called again. It might still return a value different from 0. | ||||
|      *  | ||||
|      * @return busy duration (in FreeRTOS ticks) | ||||
|      */ | ||||
|     TickType_t busyDuration() | ||||
|     { | ||||
|         return ttn_busy_duration(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies. | ||||
|      *  | ||||
|      * This function shuts down the RF module and the TTN background task. It neither clears the | ||||
|      * provisioned keys nor the configured pins. The currentat device state (and activation) | ||||
|      * are lost. | ||||
|      * | ||||
|      * To restart communication, @ref join() or @ref join(const char*, const char*, const char*) | ||||
|      * must be called. | ||||
|      */ | ||||
|     void shutdown() | ||||
|     { | ||||
|         ttn_shutdown(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Transmits a message | ||||
|      * | ||||
| @ -697,27 +764,6 @@ class TheThingsNetwork | ||||
|         ttn_set_max_tx_pow(tx_pow); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies and shuts down the RF module and the background tasks. | ||||
|      * | ||||
|      * To restart communication, @ref startup() and @ref join() must be called. | ||||
|      * it neither clears the provisioned keys nor the configured pins. | ||||
|      */ | ||||
|     void shutdown() | ||||
|     { | ||||
|         ttn_shutdown(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Restarts the background tasks and RF module. | ||||
|      * | ||||
|      * This member function must only be called after a call to shutdowna(). | ||||
|      */ | ||||
|     void startup() | ||||
|     { | ||||
|         ttn_startup(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @brief Gets current RX/TX window | ||||
|      * @return window | ||||
|  | ||||
| @ -432,19 +432,13 @@ extern "C" | ||||
|      */ | ||||
|     void ttn_init(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Resets the LoRaWAN radio. | ||||
|      * | ||||
|      * To restart communication, @ref ttn_join() or @ref ttn_join_provisioned() must be called. | ||||
|      * It neither clears the provisioned keys nor the configured pins. | ||||
|      */ | ||||
|     void ttn_reset(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Configures the pins used to communicate with the LoRaWAN radio chip. | ||||
|      * | ||||
|      * 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. | ||||
|      *  | ||||
|      * Call this function after @ref ttn_init() and before all other TTN functions. | ||||
|      * | ||||
|      * @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) | ||||
| @ -528,11 +522,14 @@ extern "C" | ||||
|     void ttn_wait_for_provisioning(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Activates the device via OTAA. | ||||
|      * @brief Activates the device via OTAA using previously provisioned keys. | ||||
|      * | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey must have already been provisioned by a call to provision(). | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey must have already been provisioned by a call | ||||
|      * to @ref ttn_provision() or @ref ttn_provision_with_mac(). | ||||
|      * Before this function is called, `nvs_flash_init()` must have been called once. | ||||
|      * | ||||
|      * The RF module is initialized and the TTN background task is started. | ||||
|      * | ||||
|      * The function blocks until the activation has completed or failed. | ||||
|      * | ||||
|      * @return `true` if the activation was succesful, `false` if the activation failed | ||||
| @ -540,9 +537,12 @@ extern "C" | ||||
|     bool ttn_join_provisioned(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Sets the DevEUI, AppEUI/JoinEUI and AppKey and activate the device via OTAA. | ||||
|      * @brief Activates the device via OTAA using the provided keys. | ||||
|      *  | ||||
|      * For the activation, the provided DevEUI, AppEUI/JoinEUI and AppKey are used. | ||||
|      * They are NOT saved in non-volatile memory. | ||||
|      * | ||||
|      * The DevEUI, AppEUI/JoinEUI and AppKey are NOT saved in non-volatile memory. | ||||
|      * The RF module is initialized and the TTN background task is started. | ||||
|      * | ||||
|      * The function blocks until the activation has completed or failed. | ||||
|      * | ||||
| @ -553,6 +553,65 @@ extern "C" | ||||
|      */ | ||||
|     bool ttn_join(const char *dev_eui, const char *app_eui, const char *app_key); | ||||
|  | ||||
|     /** | ||||
|      * @brief Resumes TTN communication after deep sleep. | ||||
|      *  | ||||
|      * The communcation state is restored from data previously saved in RTC memory. | ||||
|      * The RF module and the TTN background task are started. | ||||
|      *  | ||||
|      * This function is called instead of @ref ttn_join() or @ref ttn_join_provisioned() | ||||
|      * to continue with the established communication and to avoid a further join procedure. | ||||
|      * | ||||
|      * @return `true` if the device was able to resume, `false` otherwise. | ||||
|      */ | ||||
|     bool ttn_resume_after_deep_sleep(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies and prepares for deep sleep. | ||||
|      *  | ||||
|      * This function is called before entering deep sleep. It saves the current | ||||
|      * communication state in RTC memory and shuts down the RF module and the | ||||
|      * TTN background task. | ||||
|      *  | ||||
|      * It neither clears the provisioned keys nor the configured pins | ||||
|      * but they will be lost if the device goes into deep sleep. | ||||
|      *  | ||||
|      * Before calling this function, use @ref ttn_busy_duration() to check | ||||
|      * that the TTN device is idle and ready to go to deep sleep. | ||||
|      *  | ||||
|      * To restart communication, @ref ttn_resume_after_deep_sleep() must be called. | ||||
|      */ | ||||
|     void ttn_prepare_for_deep_sleep(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Returns the minimum duration the TTN device will be busy. | ||||
|      *  | ||||
|      * This function can be called to check whether the TTN device is | ||||
|      * still involved in communication or ready to go to deep sleep or | ||||
|      * to be powered off. | ||||
|      *  | ||||
|      * If it returns 0, the TTN communication is idle and the device can go | ||||
|      * to deep sleep or can be powered off. | ||||
|      *  | ||||
|      * If it returns a value different from 0, the value indicates the duration | ||||
|      * the device will be certainly busy. After that time, this function must be | ||||
|      * called again. It might still return a value different from 0. | ||||
|      *  | ||||
|      * @return busy duration (in FreeRTOS ticks) | ||||
|      */ | ||||
|     TickType_t ttn_busy_duration(); | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies. | ||||
|      *  | ||||
|      * This function shuts down the RF module and the TTN background task. It neither clears the | ||||
|      * provisioned keys nor the configured pins. The currentat device state (and activation) | ||||
|      * are lost. | ||||
|      * | ||||
|      * To restart communication, @ref ttn_join() and @ref ttn_join_provisioned() must be called. | ||||
|      */ | ||||
|     void ttn_shutdown(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Transmits a message | ||||
|      * | ||||
| @ -642,21 +701,6 @@ extern "C" | ||||
|      */ | ||||
|     void ttn_set_max_tx_pow(int tx_pow); | ||||
|  | ||||
|     /** | ||||
|      * @brief Stops all activies and shuts down the RF module and the background tasks. | ||||
|      * | ||||
|      * To restart communication, @ref ttn_startup() and @ref ttn_join() must be called. | ||||
|      * it neither clears the provisioned keys nor the configured pins. | ||||
|      */ | ||||
|     void ttn_shutdown(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Restarts the background tasks and RF module. | ||||
|      * | ||||
|      * This member function must only be called after a call to shutdowna(). | ||||
|      */ | ||||
|     void ttn_startup(void); | ||||
|  | ||||
|     /** | ||||
|      * @brief Gets current RX/TX window | ||||
|      * @return window | ||||
|  | ||||
							
								
								
									
										51
									
								
								src/ttn.c
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								src/ttn.c
									
									
									
									
									
								
							| @ -58,6 +58,7 @@ typedef struct | ||||
| } ttn_lmic_event_t; | ||||
|  | ||||
| static bool is_started; | ||||
| static bool has_joined; | ||||
| static QueueHandle_t lmic_event_queue; | ||||
| static ttn_message_cb message_callback; | ||||
| static ttn_waiting_reason_t waiting_reason = TTN_WAITING_NONE; | ||||
| @ -67,6 +68,8 @@ static int subband = 2; | ||||
| static ttn_data_rate_t join_data_rate = TTN_DR_JOIN_DEFAULT; | ||||
| static int max_tx_power = DEFAULT_MAX_TX_POWER; | ||||
|  | ||||
| static void start(void); | ||||
| static void stop(void); | ||||
| static bool join_core(void); | ||||
| static void config_rf_params(void); | ||||
| static void event_callback(void *user_data, ev_t event); | ||||
| @ -93,16 +96,6 @@ void ttn_configure_pins(spi_host_device_t spi_host, uint8_t nss, uint8_t rxtx, u | ||||
| #if LMIC_ENABLE_event_logging | ||||
|     ttn_log_init(); | ||||
| #endif | ||||
|  | ||||
|     LMIC_registerEventCb(event_callback, NULL); | ||||
|     LMIC_registerRxMessageCb(message_received_callback, NULL); | ||||
|  | ||||
|     os_init_ex(NULL); | ||||
|     ttn_reset(); | ||||
|  | ||||
|     lmic_event_queue = xQueueCreate(4, sizeof(ttn_lmic_event_t)); | ||||
|     ASSERT(lmic_event_queue != NULL); | ||||
|     hal_esp32_start_lmic_task(); | ||||
| } | ||||
|  | ||||
| void ttn_set_subband(int band) | ||||
| @ -110,17 +103,32 @@ void ttn_set_subband(int band) | ||||
|     subband = band; | ||||
| } | ||||
|  | ||||
| void ttn_reset(void) | ||||
| void start(void) | ||||
| { | ||||
|     if (is_started) | ||||
|         return; | ||||
|  | ||||
|     LMIC_registerEventCb(event_callback, NULL); | ||||
|     LMIC_registerRxMessageCb(message_received_callback, NULL); | ||||
|  | ||||
|     os_init_ex(NULL); | ||||
|     hal_esp32_enter_critical_section(); | ||||
|     LMIC_reset(); | ||||
|     LMIC_setClockError(MAX_CLOCK_ERROR * 4 / 100); | ||||
|     waiting_reason = TTN_WAITING_NONE; | ||||
|     hal_esp32_leave_critical_section(); | ||||
|  | ||||
|     lmic_event_queue = xQueueCreate(4, sizeof(ttn_lmic_event_t)); | ||||
|     ASSERT(lmic_event_queue != NULL); | ||||
|     hal_esp32_start_lmic_task(); | ||||
|     is_started = true; | ||||
| } | ||||
|  | ||||
| void ttn_shutdown(void) | ||||
| void stop(void) | ||||
| { | ||||
|     if (!is_started) | ||||
|         return; | ||||
|      | ||||
|     hal_esp32_enter_critical_section(); | ||||
|     LMIC_shutdown(); | ||||
|     hal_esp32_stop_lmic_task(); | ||||
| @ -128,12 +136,9 @@ void ttn_shutdown(void) | ||||
|     hal_esp32_leave_critical_section(); | ||||
| } | ||||
|  | ||||
| void ttn_startup(void) | ||||
| void ttn_shutdown(void) | ||||
| { | ||||
|     hal_esp32_enter_critical_section(); | ||||
|     LMIC_reset(); | ||||
|     hal_esp32_start_lmic_task(); | ||||
|     hal_esp32_leave_critical_section(); | ||||
|     stop(); | ||||
| } | ||||
|  | ||||
| bool ttn_provision(const char *dev_eui, const char *app_eui, const char *app_key) | ||||
| @ -226,7 +231,9 @@ bool join_core(void) | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     is_started = true; | ||||
|     start(); | ||||
|  | ||||
|     has_joined = true; | ||||
|     hal_esp32_enter_critical_section(); | ||||
|     xQueueReset(lmic_event_queue); | ||||
|     waiting_reason = TTN_WAITING_FOR_JOIN; | ||||
| @ -239,8 +246,8 @@ bool join_core(void) | ||||
|  | ||||
|     ttn_lmic_event_t event; | ||||
|     xQueueReceive(lmic_event_queue, &event, portMAX_DELAY); | ||||
|     is_started = event.event == TTN_EVNT_JOIN_COMPLETED; | ||||
|     return is_started; | ||||
|     has_joined = event.event == TTN_EVNT_JOIN_COMPLETED; | ||||
|     return has_joined; | ||||
| } | ||||
|  | ||||
| ttn_response_code_t ttn_transmit_message(const uint8_t *payload, size_t length, ttn_port_t port, bool confirm) | ||||
| @ -317,7 +324,7 @@ void ttn_set_adr_enabled(bool enabled) | ||||
|  | ||||
| void ttn_set_data_rate(ttn_data_rate_t data_rate) | ||||
| { | ||||
|     if (is_started) | ||||
|     if (has_joined) | ||||
|     { | ||||
|         hal_esp32_enter_critical_section(); | ||||
|         LMIC_setDrTxpow(data_rate, LMIC.adrTxPow); | ||||
| @ -331,7 +338,7 @@ void ttn_set_data_rate(ttn_data_rate_t data_rate) | ||||
|  | ||||
| void ttn_set_max_tx_pow(int tx_pow) | ||||
| { | ||||
|     if (is_started) | ||||
|     if (has_joined) | ||||
|     { | ||||
|         hal_esp32_enter_critical_section(); | ||||
|         LMIC_setDrTxpow(LMIC.datarate, tx_pow); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user