mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	add watchdog
This commit is contained in:
		| @@ -84,3 +84,6 @@ async def to_code(config): | ||||
|     cg.add_platformio_option("board_upload.use_1200bps_touch", "true") | ||||
|     cg.add_platformio_option("board_upload.require_upload_port", "true") | ||||
|     cg.add_platformio_option("board_upload.wait_for_upload_port", "true") | ||||
|     cg.add_build_flag("-DNRFX_WDT_ENABLED=1") | ||||
|     cg.add_build_flag("-DNRFX_WDT0_ENABLED=1") | ||||
|     cg.add_build_flag("-DNRFX_WDT_CONFIG_NO_IRQ=1") | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
|  | ||||
| #include <Arduino.h> | ||||
| #include "Adafruit_nRFCrypto.h" | ||||
| #include "nrfx_wdt.h" | ||||
|  | ||||
| namespace esphome { | ||||
|  | ||||
| @@ -10,8 +11,24 @@ uint32_t millis() { return ::millis(); } | ||||
| void delay(uint32_t ms) { ::delay(ms); } | ||||
| uint32_t micros() { return ::micros(); } | ||||
|  | ||||
| struct nrf5x_wdt_obj | ||||
| { | ||||
|     nrfx_wdt_t wdt; | ||||
|     nrfx_wdt_channel_id ch; | ||||
| }; | ||||
| static nrfx_wdt_config_t nrf5x_wdt_cfg = NRFX_WDT_DEFAULT_CONFIG; | ||||
|  | ||||
| static struct nrf5x_wdt_obj nrf5x_wdt = { | ||||
|     .wdt = NRFX_WDT_INSTANCE(0), | ||||
| }; | ||||
|  | ||||
| void arch_init() { | ||||
| 	 nRFCrypto.begin(); | ||||
|     //Configure WDT. | ||||
|     nrfx_wdt_init(&nrf5x_wdt.wdt, &nrf5x_wdt_cfg, nullptr); | ||||
|     nrfx_wdt_channel_alloc(&nrf5x_wdt.wdt, &nrf5x_wdt.ch); | ||||
|     nrfx_wdt_enable(&nrf5x_wdt.wdt); | ||||
|  | ||||
|     nRFCrypto.begin(); | ||||
|     // Init random seed | ||||
|     union seedParts { | ||||
|         uint32_t seed32; | ||||
| @@ -21,7 +38,9 @@ void arch_init() { | ||||
|     randomSeed(seed.seed32); | ||||
|  | ||||
| } | ||||
| void arch_feed_wdt() { /* TODO */ } | ||||
| void arch_feed_wdt() { | ||||
|     nrfx_wdt_feed(&nrf5x_wdt.wdt); | ||||
| } | ||||
|  | ||||
| void arch_restart() { /* TODO */ } | ||||
|  | ||||
|   | ||||
| @@ -1,3 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| namespace esphome { | ||||
|  | ||||
| void nrf52GetMacAddr(uint8_t *mac); | ||||
|  | ||||
| } | ||||
|   | ||||
							
								
								
									
										181
									
								
								esphome/components/nrf52/nrfx_wdt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								esphome/components/nrf52/nrfx_wdt.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,181 @@ | ||||
| /* | ||||
|  * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright notice, this | ||||
|  *    list of conditions and the following disclaimer. | ||||
|  * | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * | ||||
|  * 3. Neither the name of the copyright holder nor the names of its | ||||
|  *    contributors may be used to endorse or promote products derived from this | ||||
|  *    software without specific prior written permission. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||
|  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
|  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
|  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
|  * POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include <nrfx.h> | ||||
|  | ||||
| #if NRFX_CHECK(NRFX_WDT_ENABLED) | ||||
|  | ||||
| #if !(NRFX_CHECK(NRFX_WDT0_ENABLED) || NRFX_CHECK(NRFX_WDT1_ENABLED)) | ||||
| #error "No enabled WDT instances. Check <nrfx_config.h>." | ||||
| #endif | ||||
|  | ||||
| #include <nrfx_wdt.h> | ||||
|  | ||||
| #define NRFX_LOG_MODULE WDT | ||||
| #include <nrfx_log.h> | ||||
|  | ||||
| // Control block - driver instance local data. | ||||
| typedef struct | ||||
| { | ||||
|     nrfx_drv_state_t         state; | ||||
|     uint8_t                  alloc_index; | ||||
| #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) | ||||
|     nrfx_wdt_event_handler_t wdt_event_handler; | ||||
| #endif | ||||
| } wdt_control_block_t; | ||||
|  | ||||
| static wdt_control_block_t m_cb[NRFX_WDT_ENABLED_COUNT]; | ||||
|  | ||||
| nrfx_err_t nrfx_wdt_init(nrfx_wdt_t const *        p_instance, | ||||
|                          nrfx_wdt_config_t const * p_config, | ||||
|                          nrfx_wdt_event_handler_t  wdt_event_handler) | ||||
| { | ||||
|     NRFX_ASSERT(p_config); | ||||
|     nrfx_err_t err_code; | ||||
|  | ||||
|     wdt_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; | ||||
|  | ||||
| #if NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) | ||||
|     (void)wdt_event_handler; | ||||
| #else | ||||
|     p_cb->wdt_event_handler = wdt_event_handler; | ||||
| #endif | ||||
|  | ||||
|     if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED) | ||||
|     { | ||||
|         p_cb->state = NRFX_DRV_STATE_INITIALIZED; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         err_code = NRFX_ERROR_INVALID_STATE; | ||||
|         NRFX_LOG_WARNING("Function: %s, error code: %s.", | ||||
|                          __func__, | ||||
|                          NRFX_LOG_ERROR_STRING_GET(err_code)); | ||||
|         return err_code; | ||||
|     } | ||||
|  | ||||
|     nrf_wdt_behaviour_set(p_instance->p_reg, p_config->behaviour); | ||||
|  | ||||
|     uint64_t ticks = (p_config->reload_value * 32768ULL) / 1000; | ||||
|     NRFX_ASSERT(ticks <= UINT32_MAX); | ||||
|  | ||||
|     nrf_wdt_reload_value_set(p_instance->p_reg, (uint32_t) ticks); | ||||
|  | ||||
| #if !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) | ||||
|     if (wdt_event_handler) | ||||
|     { | ||||
|         nrf_wdt_int_enable(p_instance->p_reg, NRF_WDT_INT_TIMEOUT_MASK); | ||||
|         NRFX_IRQ_PRIORITY_SET(nrfx_get_irq_number(p_instance->p_reg), p_config->interrupt_priority); | ||||
|         NRFX_IRQ_ENABLE(nrfx_get_irq_number(p_instance->p_reg)); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     err_code = NRFX_SUCCESS; | ||||
|     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(err_code)); | ||||
|     return err_code; | ||||
| } | ||||
|  | ||||
|  | ||||
| void nrfx_wdt_enable(nrfx_wdt_t const * p_instance) | ||||
| { | ||||
|     wdt_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; | ||||
|     NRFX_ASSERT(p_cb->alloc_index != 0); | ||||
|     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); | ||||
|     nrf_wdt_task_trigger(p_instance->p_reg, NRF_WDT_TASK_START); | ||||
|     p_cb->state = NRFX_DRV_STATE_POWERED_ON; | ||||
|     NRFX_LOG_INFO("Enabled."); | ||||
| } | ||||
|  | ||||
|  | ||||
| void nrfx_wdt_feed(nrfx_wdt_t const * p_instance) | ||||
| { | ||||
|     wdt_control_block_t const * p_cb = &m_cb[p_instance->drv_inst_idx]; | ||||
|     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_POWERED_ON); | ||||
|     for (uint8_t i = 0; i < p_cb->alloc_index; i++) | ||||
|     { | ||||
|         nrf_wdt_reload_request_set(p_instance->p_reg, (nrf_wdt_rr_register_t)(NRF_WDT_RR0 + i)); | ||||
|     } | ||||
| } | ||||
|  | ||||
| nrfx_err_t nrfx_wdt_channel_alloc(nrfx_wdt_t const * p_instance, nrfx_wdt_channel_id * p_channel_id) | ||||
| { | ||||
|     nrfx_err_t result; | ||||
|     wdt_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; | ||||
|  | ||||
|     NRFX_ASSERT(p_channel_id); | ||||
|     NRFX_ASSERT(p_cb->state == NRFX_DRV_STATE_INITIALIZED); | ||||
|  | ||||
|     NRFX_CRITICAL_SECTION_ENTER(); | ||||
|     if (p_cb->alloc_index < NRF_WDT_CHANNEL_NUMBER) | ||||
|     { | ||||
|         *p_channel_id = (nrfx_wdt_channel_id)(NRF_WDT_RR0 + p_cb->alloc_index); | ||||
|         p_cb->alloc_index++; | ||||
|         nrf_wdt_reload_request_enable(p_instance->p_reg, *p_channel_id); | ||||
|         result = NRFX_SUCCESS; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         result = NRFX_ERROR_NO_MEM; | ||||
|     } | ||||
|     NRFX_CRITICAL_SECTION_EXIT(); | ||||
|     NRFX_LOG_INFO("Function: %s, error code: %s.", __func__, NRFX_LOG_ERROR_STRING_GET(result)); | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| void nrfx_wdt_channel_feed(nrfx_wdt_t const * p_instance, nrfx_wdt_channel_id channel_id) | ||||
| { | ||||
|     NRFX_ASSERT(m_cb[p_instance->drv_inst_idx].state == NRFX_DRV_STATE_POWERED_ON); | ||||
|     nrf_wdt_reload_request_set(p_instance->p_reg, channel_id); | ||||
| } | ||||
|  | ||||
| #if NRFX_CHECK(NRFX_WDT0_ENABLED) && !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) | ||||
| void nrfx_wdt_0_irq_handler(void) | ||||
| { | ||||
|     if (nrf_wdt_event_check(NRF_WDT0, NRF_WDT_EVENT_TIMEOUT)) | ||||
|     { | ||||
|         m_cb[NRFX_WDT0_INST_IDX].wdt_event_handler(); | ||||
|         nrf_wdt_event_clear(NRF_WDT0, NRF_WDT_EVENT_TIMEOUT); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if NRFX_CHECK(NRFX_WDT1_ENABLED) && !NRFX_CHECK(NRFX_WDT_CONFIG_NO_IRQ) | ||||
| void nrfx_wdt_1_irq_handler(void) | ||||
| { | ||||
|     if (nrf_wdt_event_check(NRF_WDT1, NRF_WDT_EVENT_TIMEOUT)) | ||||
|     { | ||||
|         m_cb[NRFX_WDT1_INST_IDX].wdt_event_handler(); | ||||
|         nrf_wdt_event_clear(NRF_WDT1, NRF_WDT_EVENT_TIMEOUT); | ||||
|     } | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif // NRFX_CHECK(NRFX_WDT_ENABLED) | ||||
		Reference in New Issue
	
	Block a user