Skip to content

Commit

Permalink
Add the EFR32 watchdog to RPC firmware (#33)
Browse files Browse the repository at this point in the history
* Create a `.gitignore` file

* Add a watchdog Gecko SDK extension

* Trust Gecko SDK extensions when building

* Allow patching the generated project file

* Add watchdog to RCP firmwares

* Ensure `pip` is available

* `yq` is available in Debian, use it directly

* Use correct parameter for `slc signature trust` command

* Ensure extension path is absolute

* Link extensions within the SDK to get slc-cli to actually work

* Revert namespacing for `#define`s hard-coded in the SDK

* [WIP] Simplify extension to bare minimum

* Register watchdog initialization later

* Remove debugging code

* Reset the watchdog timer at 25%

* Pass through `slcp_yaml_changes`

* Feed watchdog timer within the app, not in a timer interrupt handler

* Drop watchdog period to 2 seconds

* Stop running the watchdog when in debugger
  • Loading branch information
puddly authored Jan 4, 2024
1 parent 476b3ed commit 5d3cdd0
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,16 @@ jobs:
device: MGM210PA32JIA
components: simple_led:board_activity,cpc_security_secondary_none,zigbee_mfglib
patchpath: "RCPMultiPAN/Yellow"
slcp_yaml_changes: >
. += {"sdk_extension": [{"id": "nc_efr32_watchdog", version: "1.0.0"}]}
| .component += [{"from": "nc_efr32_watchdog", "id": "nc_efr32_watchdog"}]
- target: skyconnect
device: EFR32MG21A020F512IM32
components: cpc_security_secondary_none,zigbee_mfglib
patchpath: "RCPMultiPAN/SkyConnect"
slcp_yaml_changes: >
. += {"sdk_extension": [{"id": "nc_efr32_watchdog", version: "1.0.0"}]}
| .component += [{"from": "nc_efr32_watchdog", "id": "nc_efr32_watchdog"}]
uses: ./.github/workflows/silabs-firmware-build.yaml
with:
image_name: ${{ needs.build-container.outputs.image_name }}
Expand All @@ -111,6 +117,7 @@ jobs:
device: ${{ matrix.device }}
components: ${{ matrix.components }}
patchpath: ${{ matrix.patchpath }}
slcp_yaml_changes: ${{ matrix.slcp_yaml_changes }}
sdk_version: ${{ needs.build-container.outputs.sdk_version }}
metadata_fw_type: "rcp-uart-802154"
baudrate: 460800
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/silabs-firmware-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ on:
required: false
default: "null"
type: string
slcp_yaml_changes:
required: false
type: string

jobs:
firmware-build:
Expand All @@ -63,6 +66,19 @@ jobs:
- name: Adjust permission
shell: bash
run: chown builder .

- name: Link SDK extensions
shell: bash
run: |
# XXX: slc-cli does not actually work when the extensions aren't in the SDK!
ln -s $PWD/gecko_sdk_extensions /gecko_sdk/extension
- name: Trust SDK extensions
run: |
for ext in /gecko_sdk/extension/*/; do
slc signature trust --extension-path="$ext"
done
- name: Generate Firmware Project
run: |
slc generate \
Expand Down Expand Up @@ -110,6 +126,12 @@ jobs:
sed -i "s/^C_DEFS\s*=.*$/C_DEFS = '-DOPENTHREAD_BUILD_DATETIME=\"$meta_datetime\"' ${{ inputs.extra_c_defs }}/" \
"${{ inputs.project_name }}.Makefile"
- name: Patch SLCP project file
if: "${{ inputs.slcp_yaml_changes != '' }}"
run: |
cd ${{ inputs.firmware_name }}
yq --in-place --yaml-output '${{ inputs.slcp_yaml_changes }}' "${{ inputs.project_name }}.slcp"
- name: Build Firmware
run: |
cd ${{ inputs.firmware_name }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.DS_Store
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ RUN \
git \
git-lfs \
jq \
yq \
libgl1 \
make \
default-jre-headless \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/***************************************************************************//**
* @file nc_efr32_wdog.h
* @brief Legacy HAL Watchdog
*******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories, Inc, www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/

#include <stdio.h>
#include "em_cmu.h"
#include "em_wdog.h"
#include "em_rmu.h"
#include "sli_cpc_timer.h"
#include "sl_component_catalog.h"

void nc_enable_watchdog(void);
void nc_periodic_timer(sli_cpc_timer_handle_t *handle, void *data);
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
root_path: ./
id: nc_efr32_watchdog
label: EFR32 Watchdog
package: ext-comp
category: External Components
quality: production
description: >
EFR32 Watchdog.
requires:
- name: component_catalog
- name: emlib_wdog
- name: emlib_wdog
provides:
- name: nc_efr32_watchdog

source:
- path: src/nc_efr32_wdog.c

include:
- path: inc
file_list:
- path: nc_efr32_wdog.h

template_contribution:
- name: component_catalog
value: nc_efr32_watchdog
- name: event_handler
value:
event: service_init
include: "nc_efr32_wdog.h"
handler: nc_enable_watchdog
priority: 9999 # load very very late
- name: event_handler
value:
event: service_process_action
include: "nc_efr32_wdog.h"
handler: nc_poke_watchdog
priority: 9999 # run last
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
id: "nc_efr32_watchdog"
label: "EFR32 Watchdog"
version: "1.0.0"
sdk:
id: "gecko_sdk"
version: 4.3.2
component_path:
- path: "./"
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/***************************************************************************//**
* @file nc_efr32_wdog.c
* @brief Legacy HAL Watchdog
*******************************************************************************
* # License
* <b>Copyright 2022 Silicon Laboratories, Inc, www.silabs.com</b>
*******************************************************************************
*
* The licensor of this software is Silicon Laboratories Inc. Your use of this
* software is governed by the terms of Silicon Labs Master Software License
* Agreement (MSLA) available at
* www.silabs.com/about-us/legal/master-software-license-agreement. This
* software is distributed to you in Source Code format and is governed by the
* sections of the MSLA applicable to Source Code.
*
******************************************************************************/

#include "em_wdog.h"
#include "nc_efr32_wdog.h"

static bool feed_watchdog_on_warn_interrupt;


#if (_SILICON_LABS_32B_SERIES >= 1)
void WDOG0_IRQHandler(void)
{
uint32_t interrupts;

interrupts = WDOGn_IntGet(WDOG0);
WDOGn_IntClear(WDOG0, interrupts);

if (feed_watchdog_on_warn_interrupt) {
WDOGn_Feed(WDOG0);
feed_watchdog_on_warn_interrupt = false;
}
}
#endif


void nc_enable_watchdog(void)
{
// Enable LE interface
#if !defined(_SILICON_LABS_32B_SERIES_2)
CMU_ClockEnable(cmuClock_HFLE, true);
CMU_OscillatorEnable(cmuOsc_LFRCO, true, true);
#endif

#if defined(_SILICON_LABS_32B_SERIES_2) && !defined(_SILICON_LABS_32B_SERIES_2_CONFIG_1)
CMU_ClockEnable(cmuClock_WDOG0, true);
#endif

// Make sure FULL reset is used on WDOG timeout
#if defined(_RMU_CTRL_WDOGRMODE_MASK)
RMU_ResetControl(rmuResetWdog, rmuResetModeFull);
#endif

WDOG_Init_TypeDef init = WDOG_INIT_DEFAULT;
init.enable = false;
init.debugRun = false;
init.perSel = wdogPeriod_64k; // 2 seconds
init.warnSel = wdogWarnTime75pct;

#if defined(_WDOG_CTRL_CLKSEL_MASK)
init.clkSel = wdogClkSelLFRCO;
#else
// Series 2 devices select watchdog oscillator with the CMU.
CMU_ClockSelectSet(cmuClock_WDOG0, cmuSelect_LFRCO);
#endif

WDOGn_Unlock(WDOG0);
WDOGn_Init(WDOG0, &init);

// Enable warning interrupt
NVIC_ClearPendingIRQ(WDOG0_IRQn);
WDOGn_IntClear(WDOG0, WDOG_IF_WARN);
NVIC_EnableIRQ(WDOG0_IRQn);
WDOGn_IntEnable(WDOG0, WDOG_IEN_WARN);

WDOGn_Enable(WDOG0, true);
WDOGn_Feed(WDOG0);

feed_watchdog_on_warn_interrupt = false;
}


void nc_poke_watchdog()
{
CORE_DECLARE_IRQ_STATE;
CORE_ENTER_ATOMIC();
feed_watchdog_on_warn_interrupt = true;
CORE_EXIT_ATOMIC();
}

0 comments on commit 5d3cdd0

Please sign in to comment.