Skip to content

hslink: add button trigger reset #67

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@
[submodule "projects/HSLink-Pro/third_party_components/b64.c/b64.c"]
path = projects/HSLink-Pro/third_party_components/b64.c/b64.c
url = https://github.com/jwerle/b64.c.git
[submodule "projects/HSLink-Pro/third_party_components/MultiTimer/MultiTimer"]
path = projects/HSLink-Pro/third_party_components/MultiTimer/MultiTimer
url = https://github.com/HSLink/MultiTimer.git
1 change: 1 addition & 0 deletions projects/HSLink-Pro/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ sdk_inc(../common)

sdk_app_src(main.cpp)
sdk_app_src(dp_common.c)
sdk_app_src(reset_way.cpp)
sdk_app_src(setting.cpp)
sdk_app_src(led_extern.cpp)

Expand Down
1 change: 1 addition & 0 deletions projects/HSLink-Pro/src/DAP_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void)
- 0: issue a device hardware reset.
- 1: release device hardware reset.
*/
#include "reset_way.h"
__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit)
{
if (bit & 0x01) {
Expand Down
31 changes: 24 additions & 7 deletions projects/HSLink-Pro/src/HSLink_Pro_expansion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@
#include <hpm_ewdg_drv.h>
#include <hpm_spi.h>
#include "HSLink_Pro_expansion.h"

#include <dp_common.h>
#include <led_extern.h>
#include <MultiTimer.h>

#include "board.h"
#include "hpm_gptmr_drv.h"
#include "hpm_gpio_drv.h"
#include "hpm_adc16_drv.h"
#include "setting.h"

#define LOG_TAG "HSP"
#include <elog.h>
#include <reset_way.h>

volatile bool VREF_ENABLE = false;

const double ADC_REF = 3.3;
Expand Down Expand Up @@ -400,7 +408,15 @@ static void Button_Init() {
}, BOARD_BTN_PRESSED_VALUE, 0);
button_attach(&btn, SINGLE_CLICK, [](void *) {
printf("single click, send reset to target\r\n");
// TODO
if (SETTING_GET_RESET_MODE(HSLink_Setting.reset, RESET_NRST)) {
srst_reset();
}
if (SETTING_GET_RESET_MODE(HSLink_Setting.reset, RESET_ARM_SWD_SOFT)) {
software_reset();
}
if (SETTING_GET_RESET_MODE(HSLink_Setting.reset, RESET_POR)) {
por_reset();
}
Comment on lines +411 to +419
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify reset function ISR safety.

The button callback now calls reset functions (srst_reset(), software_reset(), por_reset()) which will execute in ISR context due to the timer-driven approach. Ensure these functions are ISR-safe and don't perform blocking operations.


🏁 Script executed:

#!/bin/bash
# Description: Analyze reset functions for ISR safety
# Expected: Functions should be lightweight and avoid blocking operations

echo "=== Checking reset function implementations ==="
ast-grep --pattern 'uint8_t software_reset(void) {
  $$$
}'

ast-grep --pattern 'void por_reset(void) {
  $$$
}'

ast-grep --pattern 'void srst_reset(void) {
  $$$
}'

Length of output: 275


🏁 Script executed:

#!/bin/bash
echo "=== Locating reset function implementations ==="
rg -n "software_reset" -C5
rg -n "por_reset" -C5
rg -n "srst_reset" -C5

Length of output: 9914


Heavy reset calls in ISR: software_reset() and por_reset() are not ISR-safe

software_reset() (reset_way.cpp:22–31) invokes swd_read_word() and swd_write_word(), which perform bit-banged SWD transfers with inherent delays.
por_reset() (reset_way.cpp:33–43) calls Power_Turn() and multiTimerStart(), scheduling timers and manipulating power rails.
These operations can block or re-enter timer APIs and must not run in interrupt context.

• srst_reset() (reset_way.cpp:45–50) merely toggles a GPIO and is ISR-safe.
• Defer software_reset() and por_reset() to a task or the main loop (e.g., post an event or set a flag) so they execute outside the ISR.

🤖 Prompt for AI Agents
In projects/HSLink-Pro/src/HSLink_Pro_expansion.cpp around lines 411 to 419,
software_reset() and por_reset() are called directly in an ISR, but these
functions are not ISR-safe due to blocking operations and timer usage. To fix
this, remove direct calls to software_reset() and por_reset() from the ISR and
instead set flags or post events indicating these resets are needed. Then,
handle these flags or events in the main loop or a dedicated task to perform the
resets safely outside the interrupt context.

});
button_attach(&btn, DOUBLE_CLICK, [](void *) {
printf("double click, enter system Bootloader\n");
Expand All @@ -413,6 +429,13 @@ static void Button_Init() {
HSP_EnterHSLinkBootloader();
});
button_start(&btn);

static MultiTimer timer_btn;
static auto button_ticks_ = [](MultiTimer* timer, void *user_data) {
button_ticks();
};

multiTimerStart(&timer_btn, 10, true, button_ticks_, NULL);
}

extern "C" void HSP_Init(void) {
Expand Down Expand Up @@ -477,12 +500,6 @@ extern "C" void HSP_Loop(void) {
VREF_ENABLE = false;
}
}

static uint32_t last_btn_chk_time = 0;
if (millis() - last_btn_chk_time > TICKS_INTERVAL) {
last_btn_chk_time = millis();
button_ticks();
}
}

extern "C" void HSP_Reboot(void) {
Expand Down
27 changes: 0 additions & 27 deletions projects/HSLink-Pro/src/dp_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,30 +129,3 @@ void Set_Clock_Delay(uint32_t clock)
IO_Set_Clock_Delay(clock);
}
}
// Use the CMSIS-Core definition if available.
#if !defined(SCB_AIRCR_PRIGROUP_Pos)
#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
#endif

uint8_t software_reset(void)
{
if (DAP_Data.debug_port != DAP_PORT_SWD) {
return 1;
}
uint8_t ret = 0;
uint32_t val;
ret |= swd_read_word(NVIC_AIRCR, &val);
ret |= swd_write_word(NVIC_AIRCR, VECTKEY | (val & SCB_AIRCR_PRIGROUP_Msk) | SYSRESETREQ);
return ret;
}

void por_reset(void)
{
if ((!VREF_ENABLE && HSLink_Setting.power.power_on)
|| VREF_ENABLE) {
Power_Turn(false);
board_delay_ms(10);
Power_Turn(true);
}
}
3 changes: 1 addition & 2 deletions projects/HSLink-Pro/src/dp_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

#include <stdint.h>

uint8_t software_reset(void);
void por_reset(void);


#endif //HSLINK_PRO_DP_COMMON_H
4 changes: 4 additions & 0 deletions projects/HSLink-Pro/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <hpm_gpio_drv.h>
#include <hpm_gpiom_drv.h>
#include <hpm_romapi.h>
#include "MultiTimer.h"

static void serial_number_init(void) {
#define OTP_CHIP_UUID_IDX_START (88U)
Expand Down Expand Up @@ -69,6 +70,9 @@ int main() {

Setting_Init();

multiTimerInstall(millis); // warning: timer cb all called in isr, and timer gap should align to 5ms
board_timer_create(5, []() {multiTimerYield();});

HSP_Init();
intc_set_irq_priority(CONFIG_HPM_USBD_IRQn, 5);
uartx_preinit();
Expand Down
64 changes: 64 additions & 0 deletions projects/HSLink-Pro/src/reset_way.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//
// Created by yekai on 2025/8/5.
//

#include "reset_way.h"

#include <MultiTimer.h>

#include "DAP_config.h"
#include "DAP.h"
#include "hpm_spi_drv.h"
#include "hpm_clock_drv.h"
#include "swd_host.h"
#include "HSLink_Pro_expansion.h"

// Use the CMSIS-Core definition if available.
#if !defined(SCB_AIRCR_PRIGROUP_Pos)
#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
#endif

uint8_t software_reset(void) {
if (DAP_Data.debug_port != DAP_PORT_SWD) {
return 1;
}
uint8_t ret = 0;
uint32_t val;
ret |= swd_read_word(NVIC_AIRCR, &val);
ret |= swd_write_word(NVIC_AIRCR, VECTKEY | (val & SCB_AIRCR_PRIGROUP_Msk) | SYSRESETREQ);
return ret;
}

void por_reset(void) {
if ((!VREF_ENABLE && HSLink_Setting.power.power_on)
|| VREF_ENABLE) {
// we change the settings temporarily to turn off the power
// TODO this is temporarily solution and cannot control when using vref
HSLink_Setting.power.power_on = false;
static MultiTimer timer_;
static auto timer_cb = [](MultiTimer *timer, void *user_data) {
HSLink_Setting.power.power_on = true;
};
multiTimerStart(&timer_, 50, false, timer_cb, NULL);
}
}

void srst_reset(void) {
gpio_write_pin(
HPM_FGPIO,
GPIO_GET_PORT_INDEX(PIN_SRST),
GPIO_GET_PIN_INDEX(PIN_SRST),
HSLink_Global.reset_level
);
static MultiTimer timer_;
static auto timer_cb = [](MultiTimer *timer, void *user_data) {
gpio_write_pin(
HPM_FGPIO,
GPIO_GET_PORT_INDEX(PIN_SRST),
GPIO_GET_PIN_INDEX(PIN_SRST),
!HSLink_Global.reset_level
);
};
multiTimerStart(&timer_, 50, false, timer_cb, NULL);
}
22 changes: 22 additions & 0 deletions projects/HSLink-Pro/src/reset_way.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Created by yekai on 2025/8/5.
//

#ifndef RESET_WAY_H
#define RESET_WAY_H

#include "stdint.h"

#ifdef __cplusplus
extern "C" {
#endif

uint8_t software_reset(void);
void por_reset(void);
void srst_reset(void);

#ifdef __cplusplus
}
#endif

#endif //RESET_WAY_H
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ add_subdirectory(${THIRD_PARTY_COMPONENTS_DIR}/flashdb ${CMAKE_CURRENT_BINARY_DI

add_subdirectory(${THIRD_PARTY_COMPONENTS_DIR}/b64.c ${CMAKE_CURRENT_BINARY_DIR}/b64.c)

add_subdirectory(${THIRD_PARTY_COMPONENTS_DIR}/crc32 ${CMAKE_CURRENT_BINARY_DIR}/crc32)
add_subdirectory(${THIRD_PARTY_COMPONENTS_DIR}/crc32 ${CMAKE_CURRENT_BINARY_DIR}/crc32)

add_subdirectory(${THIRD_PARTY_COMPONENTS_DIR}/MultiTimer ${CMAKE_CURRENT_BINARY_DIR}/MultiTimer)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sdk_app_inc(MultiTimer)
sdk_app_src(MultiTimer/MultiTimer.c)
Submodule MultiTimer added at fe7748