You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by vi...@apache.org on 2025/08/27 23:02:53 UTC

(mynewt-core) branch debug_u_s_b created (now a572ffb6b)

This is an automated email from the ASF dual-hosted git repository.

vipulrahane pushed a change to branch debug_u_s_b
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


      at a572ffb6b Init

This branch includes the following new commits:

     new a572ffb6b Init

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(mynewt-core) 01/01: Init

Posted by vi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vipulrahane pushed a commit to branch debug_u_s_b
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit a572ffb6b2d61c1180dd44c42fdd50ae760064b5
Author: Vipul Rahane <vi...@juul.com>
AuthorDate: Wed Aug 27 16:02:25 2025 -0700

    Init
---
 hw/usb/tinyusb/da146xx/include/tusb_hw.h           |  33 +++
 hw/usb/tinyusb/da146xx/pkg.yml                     |   3 +
 hw/usb/tinyusb/da146xx/src/da1469x.c               | 185 +++++++++++++++-
 .../include/keepalive_detect/keepalive_detect.h    | 110 ++++++++++
 .../tinyusb/{da146xx => keepalive_detect}/pkg.yml  |  16 +-
 .../keepalive_detect/src/keepalive_detect.c        | 234 +++++++++++++++++++++
 .../pkg.yml => keepalive_detect/syscfg.yml}        |  30 +--
 hw/usb/tinyusb/syscfg.yml                          |   4 +
 8 files changed, 589 insertions(+), 26 deletions(-)

diff --git a/hw/usb/tinyusb/da146xx/include/tusb_hw.h b/hw/usb/tinyusb/da146xx/include/tusb_hw.h
index 54c48602f..f02c3171a 100644
--- a/hw/usb/tinyusb/da146xx/include/tusb_hw.h
+++ b/hw/usb/tinyusb/da146xx/include/tusb_hw.h
@@ -25,6 +25,39 @@
 #include <syscfg/syscfg.h>
 #include <stdbool.h>
 
+#if MYNEWT_VAL(DA1469X_USB_KEEPALIVE_DETECT)
+/**
+ * Set event queue for keep-alive monitoring
+ */
+void tinyusb_ka_evq_set(struct os_eventq *evq);
+
+/**
+ * Check if USB keep-alive detection considers USB to be active
+ */
+bool tinyusb_ka_is_active(void);
+
+/**
+ * Get number of SOFs received since last USB disconnect
+ */
+uint32_t tinyusb_ka_get_sof_cnt(void);
+
+/**
+ * Reset SOF count to zero
+ */
+void tinyusb_ka_reset_sof_cnt(void);
+
+/**
+ *
+ * Register callback for keep-alive state changes
+ */
+void tinyusb_ka_register_cb(void (*cb)(bool connected));
+#endif
+
+/**
+ * Check if USB is connected (based on keep-alive and VBUS if used)
+ */
+bool tinyusb_is_connected(void);
+
 /* Function should be exported from TinyUSB */
 void tusb_vbus_changed(bool present);
 
diff --git a/hw/usb/tinyusb/da146xx/pkg.yml b/hw/usb/tinyusb/da146xx/pkg.yml
index 5e0e9c2d0..88c7c3d84 100644
--- a/hw/usb/tinyusb/da146xx/pkg.yml
+++ b/hw/usb/tinyusb/da146xx/pkg.yml
@@ -31,3 +31,6 @@ pkg.apis:
 pkg.deps:
     - "@apache-mynewt-core/kernel/os"
     - "@apache-mynewt-core/hw/usb/tinyusb"
+
+pkg.deps.USB_KEEPALIVE_DETECT:
+    - "@apache-mynewt-core/hw/usb/tinyusb/keepalive_detect"
diff --git a/hw/usb/tinyusb/da146xx/src/da1469x.c b/hw/usb/tinyusb/da146xx/src/da1469x.c
index 02e224e5b..d3fb215c5 100644
--- a/hw/usb/tinyusb/da146xx/src/da1469x.c
+++ b/hw/usb/tinyusb/da146xx/src/da1469x.c
@@ -24,21 +24,34 @@
 
 #include <device/usbd.h>
 
-static bool vbus_present;
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
 
-static void
-USBD_IRQHandler(void)
-{
-    tud_int_handler(0);
-}
+#ifdef MYNEWT_VAL_USB_KEEPALIVE_EVQ
+struct os_eventq MYNEWT_VAL(USB_KEEPALIVE_EVQ);
+#endif
+
+#include <keepalive_detect/keepalive_detect.h>
+
+/* USB register bit definitions moved here when keepalive is enabled,
+ * this combines position and mask, so an absolute mask can be used
+ */
+#define USB_MAMSK_REG_USB_M_FRAME_Msk          (0x0001U)
+#define USB_ALTMSK_REG_USB_M_SD3_Msk           (0x0008U)
+#define USB_ALTMSK_REG_USB_M_RESUME_Msk        (0x0004U)
+#define USB_MAEV_REG_USB_FRAME_Msk             (0x0001U)
+#define USB_ALTEV_REG_USB_SD3_Msk              (0x0008U)
+#define USB_ALTEV_REG_USB_RESUME_Msk           (0x0004U)
+#endif
+
+static bool g_vbus_present;
 
 static void
 tinyusb_vbus_changed(bool present)
 {
-    if (vbus_present == present) {
+    if (g_vbus_present == present) {
         return;
     }
-    vbus_present = present;
+    g_vbus_present = present;
 
     if (present) {
         da1469x_pd_acquire(MCU_PD_DOMAIN_SYS);
@@ -49,6 +62,99 @@ tinyusb_vbus_changed(bool present)
     }
 }
 
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+/*
+ * DA1469x-specific keep-alive callbacks implementation
+ */
+static uint16_t
+da1469x_get_frame_number(void)
+{
+    uint16_t frame_num;
+
+    frame_num = USB->USB_FNL_REG & 0xFF;
+    frame_num |= (USB->USB_FNH_REG & 0x07) << 8;
+
+    return frame_num;
+}
+
+static void
+da1469x_handle_sof_interrupt(void)
+{
+    uint32_t maev;
+
+    maev = USB->USB_MAEV_REG;
+
+    if (maev & USB_MAEV_REG_USB_FRAME_Msk) {
+        /* Clear the interrupt flag */
+        USB->USB_MAEV_REG = USB_MAEV_REG_USB_FRAME_Msk;
+
+        /* Notify keep-alive module */
+        usb_keepalive_handle_sof();
+    }
+}
+
+static void
+da1469x_check_suspend(void)
+{
+    uint32_t altev;
+
+    altev = USB->USB_ALTEV_REG;
+
+    if (altev & USB_ALTEV_REG_USB_SD3_Msk) {
+        /* No SOF for 3ms - USB suspended */
+        USB->USB_ALTEV_REG = USB_ALTEV_REG_USB_SD3_Msk;
+        usb_keepalive_handle_suspend();
+    }
+
+    if (altev & USB_ALTEV_REG_USB_RESUME_Msk) {
+        /* Resume detected */
+        USB->USB_ALTEV_REG = USB_ALTEV_REG_USB_RESUME_Msk;
+        usb_keepalive_handle_resume();
+    }
+}
+
+static void
+da1469x_enable_ka_interrupts(void)
+{
+    /* Enable frame/SOF interrupt */
+    USB->USB_MAMSK_REG |= USB_MAMSK_REG_USB_M_FRAME_Msk;
+
+    /* Enable suspend detection */
+    USB->USB_ALTMSK_REG |= USB_ALTMSK_REG_USB_M_SD3_Msk |
+                           USB_ALTMSK_REG_USB_M_RESUME_Msk;
+}
+
+static const struct usb_keepalive_cbs da1469x_keepalive_cbs = {
+    .handle_sof_interrupt = da1469x_handle_sof_interrupt,
+    .check_suspend = da1469x_check_suspend,
+    .enable_interrupts = da1469x_enable_ka_interrupts,
+    .get_frame_number = da1469x_get_frame_number,
+};
+
+static void
+da1469x_keepalive_cb(bool connected)
+{
+    /* Trigger vbus change if not using VBUS detection */
+    if (MYNEWT_VAL_CHOICE(DA1469X_USB_VBUS_HANDLING, ignore)) {
+        tinyusb_vbus_changed(connected);
+    }
+}
+#endif /* MYNEWT_VAL(USB_KEEPALIVE_DETECT) */
+
+static void
+USBD_IRQHandler(void)
+{
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+    /* Handle SOF/keep-alive interrupts */
+    da1469x_handle_sof_interrupt();
+
+    /* Check for suspend (no keep-alives) */
+    da1469x_check_suspend();
+#endif
+
+    tud_int_handler(0);
+}
+
 void
 tinyusb_hardware_init(void)
 {
@@ -69,6 +175,69 @@ tinyusb_hardware_init(void)
     }
     else if (MYNEWT_VAL_CHOICE(DA1469X_USB_VBUS_HANDLING, ignore)) {
         /* If VBUS handling is ignored notify TinyUSB that VBUS is on */
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+        /* With keep-alive detection, don't immediately notify VBUS on */
+        /* Wait for actual USB activity (SOF) to be detected */
+#else
         tinyusb_vbus_changed(true);
+#endif
     }
+
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+    /* Register DA1469x-specific callbacks */
+    usb_keepalive_register_cbs(&da1469x_keepalive_cbs);
+
+    /* Register callback for connection events */
+    usb_keepalive_register_cb(da1469x_keepalive_cb);
+
+    /* Set event queue if specified */
+#if MYNEWT_VAL(USB_KEEPALIVE_EVQ)
+    usb_keepalive_evq_set(MYNEWT_VAL(USB_KEEPALIVE_EVQ));
+#endif
+
+    /* Initialize keep-alive detection */
+    usb_keepalive_init();
+#endif
 }
+
+/*
+ * Public API functions - map to keepalive_detect functions
+ */
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+
+bool
+tinyusb_ka_is_active(void)
+{
+    return usb_keepalive_is_active();
+}
+
+uint32_t
+tinyusb_ka_get_sof_cnt(void)
+{
+    return usb_keepalive_get_sof_cnt();
+}
+
+void
+tinyusb_ka_register_cb(void (*cb)(bool connected))
+{
+    usb_keepalive_register_cb(cb);
+}
+
+bool
+tinyusb_is_connected(void)
+{
+    bool ka_active;
+
+    /* Check keep-alive detection status */
+    ka_active = usb_keepalive_is_active();
+
+    /* If using auto VBUS handling, also check VBUS */
+    if (MYNEWT_VAL_CHOICE(DA1469X_USB_VBUS_HANDLING, auto)) {
+        return g_vbus_present || ka_active;
+    }
+
+    /* If ignoring VBUS, rely only on keep-alive */
+    return ka_active;
+}
+
+#endif /* MYNEWT_VAL(USB_KEEPALIVE_DETECT) */
diff --git a/hw/usb/tinyusb/keepalive_detect/include/keepalive_detect/keepalive_detect.h b/hw/usb/tinyusb/keepalive_detect/include/keepalive_detect/keepalive_detect.h
new file mode 100644
index 000000000..da8dd637a
--- /dev/null
+++ b/hw/usb/tinyusb/keepalive_detect/include/keepalive_detect/keepalive_detect.h
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_USB_KEEPALIVE_DETECT_
+#define H_USB_KEEPALIVE_DETECT_
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <os/os.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * USB keep-alive detection callback type
+ *
+ * @param connected true when USB is connected, false when disconnected
+ */
+typedef void (*usb_keepalive_cb_t)(bool connected);
+
+/**
+ * USB keep-alive detection callbacks
+ * Platform-specific implementations must provide these functions
+ */
+struct usb_keepalive_cbs {
+    void (*handle_sof_interrupt)(void);
+    void (*check_suspend)(void);
+    void (*enable_interrupts)(void);
+    uint16_t (*get_frame_number)(void);
+};
+
+/**
+ * Initialize USB keep-alive detection
+ *
+ * @return 0 on success, error code on failure
+ */
+int usb_keepalive_init(void);
+
+/**
+ * Set event queue for keep-alive monitoring
+ *
+ * @param evq Event queue to use (NULL for default)
+ */
+void usb_keepalive_evq_set(struct os_eventq *evq);
+
+/**
+ * Register platform-specific callbacks
+ *
+ * @param cbs Platform-specific callback implementation
+ */
+void usb_keepalive_register_cbs(const struct usb_keepalive_cbs *cbs);
+
+/**
+ * Register callback for USB connection status changes
+ *
+ * @param cb Callback function
+ */
+void usb_keepalive_register_cb(usb_keepalive_cb_t cb);
+
+/**
+ * Check if USB is active (receiving keep-alives)
+ *
+ * @return true if USB is active, false otherwise
+ */
+bool usb_keepalive_is_active(void);
+
+/**
+ * Get number of SOF packets received
+ *
+ * @return SOF cnt since last disconnect
+ */
+uint32_t usb_keepalive_get_sof_cnt(void);
+
+/**
+ * Handle SOF interrupt (called by platform code)
+ */
+void usb_keepalive_handle_sof(void);
+
+/**
+ * Handle suspend event (called by platform code)
+ */
+void usb_keepalive_handle_suspend(void);
+
+/**
+ * Handle resume event (called by platform code)
+ */
+void usb_keepalive_handle_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* H_USB_KEEPALIVE_DETECT_ */
diff --git a/hw/usb/tinyusb/da146xx/pkg.yml b/hw/usb/tinyusb/keepalive_detect/pkg.yml
similarity index 79%
copy from hw/usb/tinyusb/da146xx/pkg.yml
copy to hw/usb/tinyusb/keepalive_detect/pkg.yml
index 5e0e9c2d0..29b2d0112 100644
--- a/hw/usb/tinyusb/da146xx/pkg.yml
+++ b/hw/usb/tinyusb/keepalive_detect/pkg.yml
@@ -17,17 +17,21 @@
 # under the License.
 #
 
-pkg.name: hw/usb/tinyusb/da146xx
-pkg.description: Hardware initialization for Tinyusb
+pkg.name: hw/usb/tinyusb/keepalive_detect
+pkg.description: USB keep-alive detection for TinyUSB
 pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
     - usb
+    - keepalive
     - tinyusb
 
-pkg.apis:
-    - TINYUSB_HW_INIT
-
 pkg.deps:
     - "@apache-mynewt-core/kernel/os"
-    - "@apache-mynewt-core/hw/usb/tinyusb"
+    - "@apache-mynewt-core/hw/hal"
+
+pkg.apis:
+    - usb_keepalive_detect
+
+pkg.init:
+    usb_keepalive_init: 'MYNEWT_VAL(USB_KEEPALIVE_SYSINIT_STAGE)'
diff --git a/hw/usb/tinyusb/keepalive_detect/src/keepalive_detect.c b/hw/usb/tinyusb/keepalive_detect/src/keepalive_detect.c
new file mode 100644
index 000000000..afd0e0cce
--- /dev/null
+++ b/hw/usb/tinyusb/keepalive_detect/src/keepalive_detect.c
@@ -0,0 +1,234 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <os/mynewt.h>
+#include <string.h>
+#include "keepalive_detect/keepalive_detect.h"
+#include "syscfg/syscfg.h"
+
+#if MYNEWT_VAL(USB_KEEPALIVE_DETECT)
+
+/* Keep-alive detection state structure */
+struct usb_keepalive_state {
+    uint32_t last_frame_num;
+    uint32_t sof_cnt;
+    uint32_t prev_sof_time;
+    bool usb_active;
+    uint32_t suspend_cnt;
+    struct os_callout monitor_callout;
+    uint32_t ticks;
+    uint32_t prev_sof_cnt;
+};
+
+/* Keep-alive detection variables */
+static struct usb_keepalive_state g_uks;
+static struct os_mutex g_uks_mutex;
+static usb_keepalive_cb_t g_usb_ka_cb;
+static const struct usb_keepalive_cbs *g_keepalive_cbs;
+
+/*
+ * Monitor callout callback for periodic SOF checking
+ */
+static void
+keepalive_monitor_cb(struct os_event *ev)
+{
+    uint32_t curr_sof_cnt;
+    uint32_t sof_diff;
+
+    os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+    curr_sof_cnt = g_uks.sof_cnt;
+    os_mutex_release(&g_uks_mutex);
+
+    /* Calculate SOF rate */
+    sof_diff = curr_sof_cnt - g_uks.prev_sof_cnt;
+    g_uks.prev_sof_cnt = curr_sof_cnt;
+
+    /* Check if we're receiving SOFs */
+    if (sof_diff > 0) {
+        g_uks.ticks = 0;
+
+        if (!usb_keepalive_is_active()) {
+            os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+            g_uks.usb_active = true;
+            os_mutex_release(&g_uks_mutex);
+
+            if (g_usb_ka_cb) {
+                g_usb_ka_cb(true);
+            }
+        }
+    } else {
+        g_uks.ticks += MYNEWT_VAL(USB_KEEPALIVE_MONITOR_RATE_MS);
+
+        if (g_uks.ticks >= MYNEWT_VAL(USB_KEEPALIVE_TIMEOUT_MS)) {
+            if (usb_keepalive_is_active()) {
+                os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+                g_uks.usb_active = false;
+                os_mutex_release(&g_uks_mutex);
+
+                if (g_usb_ka_cb) {
+                    g_usb_ka_cb(false);
+                }
+            }
+            g_uks.ticks = 0;
+        }
+    }
+
+    /* Reset callout */
+    os_callout_reset(&g_uks.monitor_callout,
+                     os_time_ms_to_ticks32(MYNEWT_VAL(USB_KEEPALIVE_MONITOR_RATE_MS)));
+}
+
+int
+usb_keepalive_init(void)
+{
+    int rc;
+
+    /* Initialize mutex */
+    rc = os_mutex_init(&g_uks_mutex);
+    if (rc != 0) {
+        return rc;
+    }
+
+    /* Initialize state */
+    memset(&g_uks, 0, sizeof(g_uks));
+
+    /* Initialize callout */
+    os_callout_init(&g_uks.monitor_callout, os_eventq_dflt_get(),
+                    keepalive_monitor_cb, NULL);
+
+    /* Enable platform-specific interrupts if callbacks are registered */
+    if (g_keepalive_cbs && g_keepalive_cbs->enable_interrupts) {
+        g_keepalive_cbs->enable_interrupts();
+    }
+
+    /* Start monitoring */
+    os_callout_reset(&g_uks.monitor_callout,
+                     os_time_ms_to_ticks32(MYNEWT_VAL(USB_KEEPALIVE_MONITOR_RATE_MS)));
+
+    return 0;
+}
+
+void
+usb_keepalive_evq_set(struct os_eventq *evq)
+{
+    if (evq == NULL) {
+        evq = os_eventq_dflt_get();
+    }
+
+    os_callout_init(&g_uks.monitor_callout, evq,
+                    keepalive_monitor_cb, NULL);
+}
+
+void
+usb_keepalive_register_cbs(const struct usb_keepalive_cbs *cbs)
+{
+    g_keepalive_cbs = cbs;
+}
+
+void
+usb_keepalive_register_cb(usb_keepalive_cb_t cb)
+{
+    g_usb_ka_cb = cb;
+}
+
+bool
+usb_keepalive_is_active(void)
+{
+    bool active;
+
+    os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+    active = g_uks.usb_active;
+    os_mutex_release(&g_uks_mutex);
+
+    return active;
+}
+
+uint32_t
+usb_keepalive_get_sof_cnt(void)
+{
+    uint32_t cnt;
+
+    os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+    cnt = g_uks.sof_cnt;
+    os_mutex_release(&g_uks_mutex);
+
+    return cnt;
+}
+
+void
+usb_keepalive_handle_sof(void)
+{
+    uint16_t current_frame;
+
+    if (g_keepalive_cbs && g_keepalive_cbs->get_frame_number) {
+        current_frame = g_keepalive_cbs->get_frame_number();
+
+        os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+
+        /* Check if frame number changed (valid SOF) */
+        if (current_frame != g_uks.last_frame_num) {
+            g_uks.last_frame_num = current_frame;
+            g_uks.sof_cnt++;
+            g_uks.prev_sof_time = os_cputime_get32();
+
+            /* USB is active if we're receiving SOFs */
+            if (!g_uks.usb_active) {
+                g_uks.usb_active = true;
+                if (g_usb_ka_cb) {
+                    g_usb_ka_cb(true);
+                }
+            }
+
+            /* Reset suspend cnter */
+            g_uks.suspend_cnt = 0;
+        }
+
+        os_mutex_release(&g_uks_mutex);
+    }
+}
+
+void
+usb_keepalive_handle_suspend(void)
+{
+    os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+
+    g_uks.suspend_cnt++;
+
+    if (g_uks.usb_active &&
+        g_uks.suspend_cnt > MYNEWT_VAL(USB_KEEPALIVE_SUSPEND_COUNT)) {
+        /* USB disconnected (no keep-alives) */
+        g_uks.usb_active = false;
+        g_uks.sof_cnt = 0;
+        if (g_usb_ka_cb) {
+            g_usb_ka_cb(false);
+        }
+    }
+
+    os_mutex_release(&g_uks_mutex);
+}
+
+void
+usb_keepalive_handle_resume(void)
+{
+    os_mutex_pend(&g_uks_mutex, OS_TIMEOUT_NEVER);
+    g_uks.suspend_cnt = 0;
+    os_mutex_release(&g_uks_mutex);
+}
+
+#endif /* MYNEWT_VAL(USB_KEEPALIVE_DETECT) */
diff --git a/hw/usb/tinyusb/da146xx/pkg.yml b/hw/usb/tinyusb/keepalive_detect/syscfg.yml
similarity index 55%
copy from hw/usb/tinyusb/da146xx/pkg.yml
copy to hw/usb/tinyusb/keepalive_detect/syscfg.yml
index 5e0e9c2d0..29608865f 100644
--- a/hw/usb/tinyusb/da146xx/pkg.yml
+++ b/hw/usb/tinyusb/keepalive_detect/syscfg.yml
@@ -17,17 +17,23 @@
 # under the License.
 #
 
-pkg.name: hw/usb/tinyusb/da146xx
-pkg.description: Hardware initialization for Tinyusb
-pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-    - usb
-    - tinyusb
+syscfg.defs:
+    USB_KEEPALIVE_MONITOR_RATE_MS:
+        description: 'Keep-alive monitor check rate in milliseconds'
+        value: 5
 
-pkg.apis:
-    - TINYUSB_HW_INIT
+    USB_KEEPALIVE_TIMEOUT_MS:
+        description: 'Timeout for USB disconnection detection in milliseconds'
+        value: 10
 
-pkg.deps:
-    - "@apache-mynewt-core/kernel/os"
-    - "@apache-mynewt-core/hw/usb/tinyusb"
+    USB_KEEPALIVE_SUSPEND_COUNT:
+        description: 'Number of suspend events before declaring USB disconnected'
+        value: 2
+
+    USB_KEEPALIVE_SYSINIT_STAGE:
+        description: 'Sysinit stage for USB keep-alive detection'
+        value: 500
+
+    USB_KEEPALIVE_EVQ:
+        description: 'Event queue for keep-alive monitoring (NULL for default)'
+        value: ""
diff --git a/hw/usb/tinyusb/syscfg.yml b/hw/usb/tinyusb/syscfg.yml
index 9ccd8c5d6..12cf678f3 100644
--- a/hw/usb/tinyusb/syscfg.yml
+++ b/hw/usb/tinyusb/syscfg.yml
@@ -60,3 +60,7 @@ syscfg.defs:
         choices:
             - USB0
             - USB1
+
+    USB_KEEPALIVE_DETECT:
+        description: 'Enable USB keep-alive detection'
+        value: 0