diff --git a/source/application/Makefile b/source/application/Makefile index 7eb89336..9011df40 100644 --- a/source/application/Makefile +++ b/source/application/Makefile @@ -36,6 +36,7 @@ C_FILES += \ flash.c \ luaport.c \ spi.c \ + watchdog.c \ lua_libraries/bluetooth.c \ lua_libraries/camera.c \ lua_libraries/display.c \ @@ -89,6 +90,7 @@ C_FILES += \ $(LIBRARIES)/nrfx/drivers/src/nrfx_spim.c \ $(LIBRARIES)/nrfx/drivers/src/nrfx_systick.c \ $(LIBRARIES)/nrfx/drivers/src/nrfx_twim.c \ + $(LIBRARIES)/nrfx/drivers/src/nrfx_wdt.c \ $(LIBRARIES)/nrfx/helpers/nrfx_flag32_allocator.c \ $(LIBRARIES)/nrfx/mdk/system_nrf52840.c \ $(LIBRARIES)/segger/SEGGER_RTT.c \ diff --git a/source/application/lua_libraries/bluetooth.c b/source/application/lua_libraries/bluetooth.c index 5e471b34..65ac1fba 100644 --- a/source/application/lua_libraries/bluetooth.c +++ b/source/application/lua_libraries/bluetooth.c @@ -30,6 +30,7 @@ #include "lauxlib.h" #include "lua.h" #include "luaport.h" +#include "watchdog.h" static int lua_bluetooth_is_connected(lua_State *L) { @@ -93,7 +94,7 @@ static struct lua_bluetooth_callback static void lua_bluetooth_receive_callback_handler(lua_State *L, lua_Debug *ar) { - lua_sethook(L, NULL, 0, 0); + sethook_watchdog(L); lua_rawgeti(L, LUA_REGISTRYINDEX, lua_bluetooth_callback.function); diff --git a/source/application/lua_libraries/imu.c b/source/application/lua_libraries/imu.c index b63a5a9e..bc29570e 100644 --- a/source/application/lua_libraries/imu.c +++ b/source/application/lua_libraries/imu.c @@ -32,6 +32,7 @@ #include "nrfx_gpiote.h" #include "nrfx_systick.h" #include "pinout.h" +#include "watchdog.h" #define PI 3.14159265 @@ -55,7 +56,7 @@ static int lua_imu_callback_function = 0; static void lua_imu_tap_callback_handler(lua_State *L, lua_Debug *ar) { - lua_sethook(L, NULL, 0, 0); + sethook_watchdog(L); // Clear the interrupt by reading the status register check_error(i2c_read(ACCELEROMETER, 0x03, 0xFF).fail); diff --git a/source/application/luaport.c b/source/application/luaport.c index d2db1b80..d080a5d5 100644 --- a/source/application/luaport.c +++ b/source/application/luaport.c @@ -31,6 +31,7 @@ #include "lualib.h" #include "nrf_soc.h" #include "nrfx_log.h" +#include "watchdog.h" lua_State *L_global = NULL; @@ -50,7 +51,7 @@ void lua_write_to_repl(uint8_t *buffer, uint8_t length) static void lua_break_signal_handler(lua_State *L, lua_Debug *ar) { - lua_sethook(L, NULL, 0, 0); + sethook_watchdog(L); luaL_error(L, "break signal"); } @@ -72,6 +73,9 @@ void run_lua(bool factory_reset) error_with_message("Cannot create lua state: not enough memory"); } + // Attach watchdog to hook + sethook_watchdog(L); + // Open the standard libraries luaL_requiref(L, LUA_GNAME, luaopen_base, 1); luaL_requiref(L, LUA_COLIBNAME, luaopen_coroutine, 1); diff --git a/source/application/main.c b/source/application/main.c index 8435c680..f1bf8e45 100644 --- a/source/application/main.c +++ b/source/application/main.c @@ -43,6 +43,7 @@ #include "nrfx_systick.h" #include "pinout.h" #include "spi.h" +#include "watchdog.h" bool not_real_hardware = false; bool stay_awake = false; @@ -165,6 +166,11 @@ static void fpga_send_bitstream_bytes(void *context, static void hardware_setup(bool *factory_reset) { + // Configure watchdog + { + init_watchdog(); + } + // Configure systick so we can use it for simple delays { nrfx_systick_init(); @@ -403,6 +409,8 @@ int main(void) while (1) { + reload_watchdog(NULL, NULL); + run_lua(factory_reset); factory_reset = false; diff --git a/source/application/nrfx_config.h b/source/application/nrfx_config.h index 2862353c..274e59ed 100644 --- a/source/application/nrfx_config.h +++ b/source/application/nrfx_config.h @@ -47,4 +47,6 @@ #define NRFX_TWIM_ENABLED 1 #define NRFX_TWIM0_ENABLED 1 +#define NRFX_WDT_ENABLED 1 + #include "templates/nrfx_config_nrf52840.h" diff --git a/source/application/watchdog.c b/source/application/watchdog.c new file mode 100644 index 00000000..1854c184 --- /dev/null +++ b/source/application/watchdog.c @@ -0,0 +1,55 @@ +/* + * This file is a part of: https://github.com/brilliantlabsAR/frame-codebase + * + * Authored by: Raj Nakarja / Brilliant Labs Ltd. (raj@brilliant.xyz) + * Rohit Rathnam / Silicon Witchery AB (rohit@siliconwitchery.com) + * Uma S. Gupta / Techno Exponent (umasankar@technoexponent.com) + * + * ISC Licence + * + * Copyright © 2023 Brilliant Labs Ltd. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "lua.h" +#include "nrfx_wdt.h" + +static nrfx_wdt_t watchdog = NRFX_WDT_INSTANCE(0); + +void init_watchdog(void) +{ + nrfx_wdt_config_t watchdog_config = { + .behaviour = NRF_WDT_BEHAVIOUR_RUN_SLEEP_MASK, + .reload_value = 6000, + .interrupt_priority = NRFX_WDT_DEFAULT_CONFIG_IRQ_PRIORITY, + }; + + nrfx_wdt_channel_id watchdog_channel = NRF_WDT_RR0; + + check_error(nrfx_wdt_init(&watchdog, &watchdog_config, NULL)); + check_error(nrfx_wdt_channel_alloc(&watchdog, &watchdog_channel)); + + nrfx_wdt_enable(&watchdog); + nrfx_wdt_feed(&watchdog); +} + +void reload_watchdog(lua_State *L, lua_Debug *ar) +{ + nrfx_wdt_channel_feed(&watchdog, NRF_WDT_RR0); +} + +void sethook_watchdog(lua_State *L) +{ + lua_sethook(L, reload_watchdog, LUA_MASKCALL | LUA_MASKCOUNT, 2000); +} \ No newline at end of file diff --git a/source/application/watchdog.h b/source/application/watchdog.h new file mode 100644 index 00000000..52e30be2 --- /dev/null +++ b/source/application/watchdog.h @@ -0,0 +1,31 @@ +/* + * This file is a part of: https://github.com/brilliantlabsAR/frame-codebase + * + * Authored by: Raj Nakarja / Brilliant Labs Ltd. (raj@brilliant.xyz) + * Rohit Rathnam / Silicon Witchery AB (rohit@siliconwitchery.com) + * Uma S. Gupta / Techno Exponent (umasankar@technoexponent.com) + * + * ISC Licence + * + * Copyright © 2023 Brilliant Labs Ltd. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#pragma once + +#include "lua.h" + +void init_watchdog(void); +void reload_watchdog(lua_State *L, lua_Debug *ar); +void sethook_watchdog(lua_State *L); diff --git a/source/error_logging.c b/source/error_logging.c index c9144e5b..71435caf 100644 --- a/source/error_logging.c +++ b/source/error_logging.c @@ -146,10 +146,15 @@ void _check_error(nrfx_err_t error_code, const char *file, const int line) { if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) { - LOG("Crashed at %s:%u - %s", + LOG("Crashed at %s:%u - %s (0x%02x)", file, line, - lookup_error_code(error_code)); + lookup_error_code(error_code), + error_code); + + for (size_t i = 0; i < 1000; i++) + { + } __BKPT(); } diff --git a/source/nrfx_glue.h b/source/nrfx_glue.h index 7f412ef5..0837acf9 100644 --- a/source/nrfx_glue.h +++ b/source/nrfx_glue.h @@ -33,6 +33,7 @@ #define nrfx_gpiote_0_irq_handler GPIOTE_IRQHandler #define nrfx_rtc_1_irq_handler RTC1_IRQHandler #define nrfx_pdm_irq_handler PDM_IRQHandler +#define nrfx_wdt_0_irq_handler WDT_IRQHandler #define NRFX_ASSERT(expression) \ do \