Compare commits

...

2 Commits

Author SHA1 Message Date
jh.chun 39cf6068f7 주석 정리 2026-06-26 17:28:52 +09:00
jh.chun 0d719751c4 DFU activation 후 App 부팅 시 전원 OFF 처리 추가 2026-06-26 17:22:56 +09:00
7 changed files with 58 additions and 19 deletions
@@ -64,6 +64,7 @@ static volatile bool m_flash_write_done;
#define SCHED_QUEUE_SIZE 32 /**< Maximum number of events in the scheduler queue. */ #define SCHED_QUEUE_SIZE 32 /**< Maximum number of events in the scheduler queue. */
#define SCHED_EVENT_DATA_SIZE NRF_DFU_SCHED_EVENT_DATA_SIZE /**< Maximum app_scheduler event size. */ #define SCHED_EVENT_DATA_SIZE NRF_DFU_SCHED_EVENT_DATA_SIZE /**< Maximum app_scheduler event size. */
#define POST_DFU_APP_BOOT_GPREGRET2_MASK 0x02U
#if !(defined(NRF_BL_DFU_ENTER_METHOD_BUTTON) && \ #if !(defined(NRF_BL_DFU_ENTER_METHOD_BUTTON) && \
defined(NRF_BL_DFU_ENTER_METHOD_PINRESET) && \ defined(NRF_BL_DFU_ENTER_METHOD_PINRESET) && \
@@ -470,6 +471,7 @@ ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
break; break;
case ACTIVATION_SUCCESS: case ACTIVATION_SUCCESS:
nrf_power_gpregret2_set(nrf_power_gpregret2_get() | POST_DFU_APP_BOOT_GPREGRET2_MASK);
bootloader_reset(true); bootloader_reset(true);
NRF_LOG_ERROR("Unreachable"); NRF_LOG_ERROR("Unreachable");
return NRF_ERROR_INTERNAL; // Should not reach this. return NRF_ERROR_INTERNAL; // Should not reach this.
@@ -181,6 +181,7 @@
#define POWER_OFF_DELAY 3000 /* Power-off delay: 3s after LED indication */ #define POWER_OFF_DELAY 3000 /* Power-off delay: 3s after LED indication */
#define POWER_RESET_DELAY 2000 /* Reset delay: 2s */ #define POWER_RESET_DELAY 2000 /* Reset delay: 2s */
#define LED_NUM 24 /* LED pin number */ #define LED_NUM 24 /* LED pin number */
#define POST_DFU_APP_BOOT_GPREGRET2_MASK 0x02U /* Bootloader marker after DFU activation */
/*============================================================================== /*==============================================================================
* BLE Instances (statically allocated via SoftDevice macros) * BLE Instances (statically allocated via SoftDevice macros)
@@ -230,7 +231,7 @@ static char * roles_str[] = {"INVALID_ROLE", "CENTRAL", "PERIPHERAL"};
/*============================================================================== /*==============================================================================
* Global Variables * Global Variables
* IEC 62304 §5.5.3: all global buffers zero-initialized for deterministic startup * IEC 62304 5.5.3: all global buffers zero-initialized for deterministic startup
*============================================================================*/ *============================================================================*/
volatile uint8_t Sj_type; /* Command type identifier */ volatile uint8_t Sj_type; /* Command type identifier */
bool power_off_duble_prohibit = false; /* Power-off double prevention flag */ bool power_off_duble_prohibit = false; /* Power-off double prevention flag */
@@ -1545,7 +1546,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
DBG_PRINTF("[BLE] Connected\r\n"); DBG_PRINTF("[BLE] Connected\r\n");
#if BLE_DEV_MODE #if BLE_DEV_MODE
/* Dev: no passkey/SEC allow NUS TX/RX as soon as GAP is up (prod uses PM_EVT_CONN_SEC_SUCCEEDED). */ /* Dev: no passkey/SEC - allow NUS TX/RX as soon as GAP is up (prod uses PM_EVT_CONN_SEC_SUCCEEDED). */
ble_connection_st = BLE_CONNECTED_ST; ble_connection_st = BLE_CONNECTED_ST;
battery_timer_start(); battery_timer_start();
#endif #endif
@@ -2076,6 +2077,7 @@ static void main_s(void * p_context)
bool button_released = nrf_gpio_pin_read(POWER_BUTTON); bool button_released = nrf_gpio_pin_read(POWER_BUTTON);
/* ---- Running phase: post-boot button polling ---- */ /* ---- Running phase: post-boot button polling ---- */
if (booted) if (booted)
{ {
@@ -2120,7 +2122,7 @@ static void main_s(void * p_context)
go_device_power_off = true; go_device_power_off = true;
main_timer_start(); main_timer_start();
} }
else if (cnt_s > 250 || (m_reset_status == 2)) /* 250 x 5ms = 1.25s + α */ else if (cnt_s > 250 || (m_reset_status == 2)) /* 250 x 5ms = 1.25s + ¥á */
{ {
DBG_PRINTF("[BTN] Boot (cnt=%d)\r\n", cnt_s); DBG_PRINTF("[BTN] Boot (cnt=%d)\r\n", cnt_s);
device_reset = false; device_reset = false;
@@ -2149,7 +2151,7 @@ static void main_s(void * p_context)
cnt_s++; cnt_s++;
device_reset = false; device_reset = false;
if (cnt_s == 250) /* 250 x 5ms = 1.25s + α */ if (cnt_s == 250) /* 250 x 5ms = 1.25s + ¥á */
{ {
led_set_state(LED_STATE_POWER_ON); led_set_state(LED_STATE_POWER_ON);
DBG_PRINTF("[BTN] 2.0s\r\n"); DBG_PRINTF("[BTN] 2.0s\r\n");
@@ -2170,7 +2172,7 @@ int main(void)
{ {
bool erase_bonds_local = false; bool erase_bonds_local = false;
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Phase 1: Basic hardware init (BLE-independent) * Phase 1: Basic hardware init (BLE-independent)
* *
* - Power self-latch (P0.8 HIGH) * - Power self-latch (P0.8 HIGH)
@@ -2179,9 +2181,20 @@ int main(void)
* - App timers (power polling, battery, main loop) * - App timers (power polling, battery, main loop)
* - Default config (serial number, passkey) * - Default config (serial number, passkey)
* - Buttons/LEDs * - Buttons/LEDs
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
power_hold_init(); power_hold_init();
if ((NRF_POWER->GPREGRET2 & POST_DFU_APP_BOOT_GPREGRET2_MASK) != 0)
{
NRF_POWER->GPREGRET2 &= ~POST_DFU_APP_BOOT_GPREGRET2_MASK;
NRF_P0->OUTCLR = (1UL << 8);
NRF_P0->DIRSET = (1UL << 8);
while (true)
{
__WFE();
}
}
if (power_off_duble_prohibit) if (power_off_duble_prohibit)
{ {
return 0; return 0;
@@ -2191,7 +2204,7 @@ int main(void)
log_init(); log_init();
DBG_PRINTF("\r\n========================================\r\n"); DBG_PRINTF("\r\n========================================\r\n");
DBG_PRINTF(" Medithings v1.17\r\n"); DBG_PRINTF(" Medithings VesiScan-Basic\r\n");
DBG_PRINTF("========================================\r\n"); DBG_PRINTF("========================================\r\n");
DBG_PRINTF("[1] HW Init\r\n"); DBG_PRINTF("[1] HW Init\r\n");
@@ -2205,33 +2218,33 @@ int main(void)
#endif #endif
DBG_PRINTF(" gpio/timer/config/btn OK\r\n"); DBG_PRINTF(" gpio/timer/config/btn OK\r\n");
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Phase 2: BLE stack init * Phase 2: BLE stack init
* *
* - Power management module (WFE/sleep when idle) * - Power management module (WFE/sleep when idle)
* - SoftDevice S140 (BLE 5.0 protocol stack) * - SoftDevice S140 (BLE 5.0 protocol stack)
* - DC-DC converter enable (required after SoftDevice) * - DC-DC converter enable (required after SoftDevice)
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
DBG_PRINTF("[2] BLE Stack\r\n"); DBG_PRINTF("[2] BLE Stack\r\n");
power_management_init(); power_management_init();
ble_stack_init(); ble_stack_init();
APP_ERROR_CHECK(sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE)); APP_ERROR_CHECK(sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE));
DBG_PRINTF(" pwr/stack/dcdc OK\r\n"); DBG_PRINTF(" pwr/stack/dcdc OK\r\n");
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Phase 3: Internal flash config (must init after BLE stack) * Phase 3: Internal flash config (must init after BLE stack)
* *
* - FDS (Flash Data Storage) init * - FDS (Flash Data Storage) init
* - Read stored config from flash (serial, passkey, piezo, etc.) * - Read stored config from flash (serial, passkey, piezo, etc.)
* - Overwrite defaults with flash values * - Overwrite defaults with flash values
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
DBG_PRINTF("[3] FDS\r\n"); DBG_PRINTF("[3] FDS\r\n");
fs_storage_init(); fs_storage_init();
config_load(); config_load();
load_flash_config(); load_flash_config();
DBG_PRINTF(" fds OK\r\n"); DBG_PRINTF(" fds OK\r\n");
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Phase 4: BLE protocol setup * Phase 4: BLE protocol setup
* *
* - GAP: device name (serial number), connection params, passkey * - GAP: device name (serial number), connection params, passkey
@@ -2240,7 +2253,7 @@ int main(void)
* - Advertising: advertising data (name, UUID) * - Advertising: advertising data (name, UUID)
* - Connection parameter negotiation module * - Connection parameter negotiation module
* - Security: Peer Manager (bonding/passkey) * - Security: Peer Manager (bonding/passkey)
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
DBG_PRINTF("[4] BLE Protocol\r\n"); DBG_PRINTF("[4] BLE Protocol\r\n");
gap_params_init(); gap_params_init();
gatt_init(); gatt_init();
@@ -2275,14 +2288,14 @@ int main(void)
DBG_PRINTF(" fds defaults saved\r\n"); DBG_PRINTF(" fds defaults saved\r\n");
} }
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Phase 5: Application init * Phase 5: Application init
* *
* - Command parser: process BLE received commands (log, BLE TX, CRC) * - Command parser: process BLE received commands (log, BLE TX, CRC)
* - Piezo driver: GPIO/Timer/PPI setup for ultrasound measurement * - Piezo driver: GPIO/Timer/PPI setup for ultrasound measurement
* - IMU (ICM42670P) is NOT initialized here * - IMU (ICM42670P) is NOT initialized here
* -> imu_read_direct() self-configures/reads/sleeps on each msp? command * -> imu_read_direct() self-configures/reads/sleeps on each msp? command
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
DBG_PRINTF("[5] App\r\n"); DBG_PRINTF("[5] App\r\n");
g_plat.log = log_printf; g_plat.log = log_printf;
g_plat.tx_bin = dr_binary_tx_safe; g_plat.tx_bin = dr_binary_tx_safe;
@@ -2292,9 +2305,9 @@ int main(void)
dr_piezo_init(); dr_piezo_init();
DBG_PRINTF(" parser/piezo OK\r\n"); DBG_PRINTF(" parser/piezo OK\r\n");
/*────────────────────────────────────────────────────────────── /*--------------------------------------------------------------------------
* Boot complete -> start power button state machine * Boot complete -> start power button state machine
*────────────────────────────────────────────────────────────*/ *--------------------------------------------------------------------------*/
DBG_PRINTF("\r\n========================================\r\n"); DBG_PRINTF("\r\n========================================\r\n");
DBG_PRINTF(" READY [%s]\r\n", SERIAL_NO); DBG_PRINTF(" READY [%s]\r\n", SERIAL_NO);
DBG_PRINTF("========================================\r\n\r\n"); DBG_PRINTF("========================================\r\n\r\n");
@@ -53,7 +53,7 @@
* : Unify both IMU direct-read and FIFO outputs as raw data in datasheet axis convention. * : Unify both IMU direct-read and FIFO outputs as raw data in datasheet axis convention.
* - VBTFW0120 260615 jhChun : Add EMC mitigation logic for BLE link stability: extended supervision timeout and dynamic TX power control based on RSSI, RSSI silence, HVN latency, and TX queue congestion. * - VBTFW0120 260615 jhChun : Add EMC mitigation logic for BLE link stability: extended supervision timeout and dynamic TX power control based on RSSI, RSSI silence, HVN latency, and TX queue congestion.
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
#define FIRMWARE_VERSION "VBTFW0129" #define FIRMWARE_VERSION "VBTFW0120"
/*============================================================================== /*==============================================================================
* Data Length Constants * Data Length Constants
@@ -32,6 +32,8 @@ NOTICE: This file has been modified by Nordic Semiconductor ASA.
#include "system_nrf52_approtect.h" #include "system_nrf52_approtect.h"
#define __SYSTEM_CLOCK_64M (64000000UL) #define __SYSTEM_CLOCK_64M (64000000UL)
#define POWER_HOLD_PIN 8UL
#define POWER_HOLD_PIN_MASK (1UL << POWER_HOLD_PIN)
#if defined ( __CC_ARM ) #if defined ( __CC_ARM )
@@ -89,6 +91,15 @@ void SystemCoreClockUpdate(void)
void SystemInit(void) void SystemInit(void)
{ {
/* Keep the external power latch asserted immediately after reset. */
NRF_P0->OUTSET = POWER_HOLD_PIN_MASK;
NRF_P0->DIRSET = POWER_HOLD_PIN_MASK;
NRF_P0->PIN_CNF[POWER_HOLD_PIN] =
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
(GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
(GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
(GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) |
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
Specification to see which one). */ Specification to see which one). */
#if defined (ENABLE_SWO) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos) #if defined (ENABLE_SWO) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos)
+2
View File
@@ -76,6 +76,8 @@ static void dfu_observer(nrf_dfu_evt_type_t evt_type)
break; break;
case NRF_DFU_EVT_DFU_STARTED: case NRF_DFU_EVT_DFU_STARTED:
break; break;
case NRF_DFU_EVT_DFU_COMPLETED:
break;
default: default:
break; break;
} }
@@ -32,6 +32,8 @@ NOTICE: This file has been modified by Nordic Semiconductor ASA.
#include "system_nrf52_approtect.h" #include "system_nrf52_approtect.h"
#define __SYSTEM_CLOCK_64M (64000000UL) #define __SYSTEM_CLOCK_64M (64000000UL)
#define POWER_HOLD_PIN 8UL
#define POWER_HOLD_PIN_MASK (1UL << POWER_HOLD_PIN)
#if defined ( __CC_ARM ) #if defined ( __CC_ARM )
@@ -89,6 +91,15 @@ void SystemCoreClockUpdate(void)
void SystemInit(void) void SystemInit(void)
{ {
/* Keep the external power latch asserted immediately after reset. */
NRF_P0->OUTSET = POWER_HOLD_PIN_MASK;
NRF_P0->DIRSET = POWER_HOLD_PIN_MASK;
NRF_P0->PIN_CNF[POWER_HOLD_PIN] =
(GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
(GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
(GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
(GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) |
(GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
/* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product
Specification to see which one). */ Specification to see which one). */
#if defined (ENABLE_SWO) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos) #if defined (ENABLE_SWO) && defined(CLOCK_TRACECONFIG_TRACEMUX_Pos)
@@ -73,7 +73,7 @@
<LExpSel>0</LExpSel> <LExpSel>0</LExpSel>
</OPTXL> </OPTXL>
<OPTFL> <OPTFL>
<tvExp>0</tvExp> <tvExp>1</tvExp>
<tvExpOptDlg>0</tvExpOptDlg> <tvExpOptDlg>0</tvExpOptDlg>
<IsCurrentTarget>1</IsCurrentTarget> <IsCurrentTarget>1</IsCurrentTarget>
</OPTFL> </OPTFL>