mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-02 20:23:53 +00:00
companion radio set + tempradio bugfixes, touch 1200 support
This commit is contained in:
@@ -19,6 +19,8 @@ cmake_minimum_required(VERSION 3.20.0)
|
||||
# - dts/bindings/lora/semtech,lr1110.yaml: LR1110 DTS binding
|
||||
# - drivers/gnss/gnss_luatos_air530z.c: EASY ephemeris prediction (PMTK869)
|
||||
# - drivers/gnss/Kconfig.luatos_air530z: CONFIG_GNSS_LUATOS_AIR530Z_EASY
|
||||
# - drivers/lora/native/sx126x/sx126x.c: fix rx-enable-gpios not toggled
|
||||
# when dio2-tx-enable is set (breaks E22-900M30S and similar PA modules)
|
||||
# modules/:
|
||||
# - lib/loramac-node/src/radio/sx126x/radio.c: restore full 10-element
|
||||
# Bandwidths[] array + fix LDRO for sub-125kHz bandwidths
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
#if defined(CONFIG_SOC_SERIES_NRF52X) || defined(CONFIG_SOC_SERIES_NRF52)
|
||||
#include <hal/nrf_power.h>
|
||||
/* Adafruit bootloader GPREGRET magic values */
|
||||
#define BOOTLOADER_DFU_UF2_MAGIC 0x57 /* Enter UF2 mass storage mode */
|
||||
#define BOOTLOADER_DFU_OTA_MAGIC 0xA8 /* Enter BLE OTA DFU mode */
|
||||
#define BOOTLOADER_DFU_SERIAL_MAGIC 0x4e /* Enter serial DFU mode (CDC only) */
|
||||
#define BOOTLOADER_DFU_UF2_MAGIC 0x57 /* Enter UF2 mass storage mode (CDC + MSC) */
|
||||
#define BOOTLOADER_DFU_OTA_MAGIC 0xA8 /* Enter BLE OTA DFU mode */
|
||||
#define NRF52_GPREGRET 1
|
||||
#endif
|
||||
|
||||
@@ -150,7 +151,8 @@ void ZephyrBoard::reboot()
|
||||
void ZephyrBoard::rebootToBootloader()
|
||||
{
|
||||
#ifdef NRF52_GPREGRET
|
||||
/* Write magic value to GPREGRET0 - enter UF2 mass storage mode */
|
||||
/* Write magic value to GPREGRET0 - enter UF2 bootloader mode.
|
||||
* UF2 supports both drag-and-drop (.uf2) and serial DFU (nrfutil). */
|
||||
nrf_power_gpregret_set(NRF_POWER, 0, BOOTLOADER_DFU_UF2_MAGIC);
|
||||
#endif
|
||||
k_msleep(50); /* Let UART/USB flush */
|
||||
|
||||
@@ -57,9 +57,27 @@ USBD_CONFIGURATION_DEFINE(zephcore_hs_config,
|
||||
/* ZephyrBoard instance for bootloader entry */
|
||||
static mesh::ZephyrBoard usb_board;
|
||||
|
||||
/* Track DTR state for Arduino-style 1200 baud touch detection.
|
||||
* Arduino triggers on DTR drop (high→low) while baud rate is 1200.
|
||||
* adafruit-nrfutil --touch 1200 opens port at 1200 baud (DTR high),
|
||||
* then closes it (DTR low). We detect both the baud rate change and
|
||||
* the DTR drop to cover all host tool implementations. */
|
||||
static bool dtr_was_active;
|
||||
|
||||
static void enter_bootloader(void)
|
||||
{
|
||||
LOG_WRN("Entering bootloader (1200 baud touch)");
|
||||
/* Small delay to let USB disconnect cleanly */
|
||||
k_msleep(100);
|
||||
usb_board.rebootToBootloader();
|
||||
/* Never returns */
|
||||
}
|
||||
|
||||
/*
|
||||
* USB message callback - detect 1200 baud touch for bootloader entry.
|
||||
* Arduino uses this method: when host opens port at 1200 baud, enter DFU.
|
||||
* Two detection methods (matching Arduino behavior):
|
||||
* 1. Baud rate set to 1200 (SET_LINE_CODING)
|
||||
* 2. DTR drop while baud is 1200 (SET_CONTROL_LINE_STATE)
|
||||
*/
|
||||
static void usbd_msg_callback(struct usbd_context *const ctx, const struct usbd_msg *msg)
|
||||
{
|
||||
@@ -67,15 +85,22 @@ static void usbd_msg_callback(struct usbd_context *const ctx, const struct usbd_
|
||||
uint32_t baudrate = 0;
|
||||
int ret = uart_line_ctrl_get(msg->dev, UART_LINE_CTRL_BAUD_RATE, &baudrate);
|
||||
if (ret == 0) {
|
||||
LOG_DBG("CDC ACM baud rate change: %u", baudrate);
|
||||
LOG_INF("CDC ACM baud rate: %u", baudrate);
|
||||
if (baudrate == 1200) {
|
||||
LOG_INF("1200 baud touch detected - entering bootloader");
|
||||
/* Small delay to let USB disconnect cleanly */
|
||||
k_msleep(100);
|
||||
usb_board.rebootToBootloader();
|
||||
/* Never returns */
|
||||
enter_bootloader();
|
||||
}
|
||||
}
|
||||
} else if (msg->type == USBD_MSG_CDC_ACM_CONTROL_LINE_STATE) {
|
||||
uint32_t dtr = 0;
|
||||
uint32_t baudrate = 0;
|
||||
uart_line_ctrl_get(msg->dev, UART_LINE_CTRL_DTR, &dtr);
|
||||
uart_line_ctrl_get(msg->dev, UART_LINE_CTRL_BAUD_RATE, &baudrate);
|
||||
LOG_INF("CDC ACM DTR=%u baud=%u", dtr, baudrate);
|
||||
/* Arduino method: DTR drop (high→low) while baud is 1200 */
|
||||
if (dtr_was_active && !dtr && baudrate == 1200) {
|
||||
enter_bootloader();
|
||||
}
|
||||
dtr_was_active = (dtr != 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ void CommonCLI::scheduleReboot(uint8_t type)
|
||||
|
||||
void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, char* reply) {
|
||||
if (strcmp(command, "start dfu") == 0) {
|
||||
/* Reboot into UF2 mass storage bootloader for firmware update */
|
||||
/* Reboot into UF2 bootloader for firmware update */
|
||||
strcpy(reply, "OK - rebooting to UF2 DFU");
|
||||
scheduleReboot(REBOOT_DFU);
|
||||
} else if (memcmp(command, "start ota", 9) == 0) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,69 @@
|
||||
# dfu-flash.ps1 - Flash ZephCore via serial DFU with automatic port detection
|
||||
#
|
||||
# Usage: .\dfu-flash.ps1 -Port COM3 -Package path\to\zephyr.zip
|
||||
# .\dfu-flash.ps1 COM3 zephyr.zip
|
||||
#
|
||||
# The firmware and bootloader use different USB VID/PID, so Windows assigns
|
||||
# different COM ports. This script handles the port switch automatically:
|
||||
# 1. Triggers 1200 baud touch on the firmware's port
|
||||
# 2. Waits for the bootloader to enumerate on a new port
|
||||
# 3. Runs adafruit-nrfutil DFU on the bootloader's port
|
||||
|
||||
param(
|
||||
[Parameter(Position=0, Mandatory=$true)]
|
||||
[string]$Port,
|
||||
|
||||
[Parameter(Position=1, Mandatory=$true)]
|
||||
[string]$Package
|
||||
)
|
||||
|
||||
if (-not (Test-Path $Package)) {
|
||||
Write-Host "Error: package not found: $Package" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Snapshot current COM ports
|
||||
$before = [System.IO.Ports.SerialPort]::GetPortNames() | Sort-Object
|
||||
|
||||
Write-Host "Current ports: $($before -join ', ')"
|
||||
Write-Host "Triggering 1200 baud reset on $Port..."
|
||||
|
||||
try {
|
||||
$ser = New-Object System.IO.Ports.SerialPort $Port, 1200
|
||||
$ser.DtrEnable = $true
|
||||
$ser.Open()
|
||||
Start-Sleep -Milliseconds 200
|
||||
$ser.DtrEnable = $false
|
||||
Start-Sleep -Milliseconds 100
|
||||
$ser.Close()
|
||||
} catch {
|
||||
Write-Host "Error opening ${Port}: $_" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Wait for bootloader to enumerate (up to 10 seconds)
|
||||
Write-Host "Waiting for bootloader..."
|
||||
$dfuPort = $null
|
||||
$deadline = (Get-Date).AddSeconds(10)
|
||||
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
Start-Sleep -Milliseconds 500
|
||||
$after = [System.IO.Ports.SerialPort]::GetPortNames() | Sort-Object
|
||||
$newPorts = $after | Where-Object { $_ -notin $before }
|
||||
|
||||
if ($newPorts.Count -gt 0) {
|
||||
$dfuPort = $newPorts[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (-not $dfuPort) {
|
||||
Write-Host "Error: no new COM port detected. Bootloader may not have started." -ForegroundColor Red
|
||||
Write-Host "Available ports: $([System.IO.Ports.SerialPort]::GetPortNames() -join ', ')"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Bootloader found on $dfuPort" -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
adafruit-nrfutil --verbose dfu serial --package $Package -p $dfuPort -b 115200 --singlebank
|
||||
@@ -541,6 +541,12 @@ int main(void)
|
||||
/* Start mesh */
|
||||
companion_mesh.begin();
|
||||
|
||||
/* Redirect radio prefs pointer to the live companion_mesh.prefs.
|
||||
* The radio was constructed with &temp_prefs (a one-time copy needed
|
||||
* for static init). After begin(), point at the real prefs so that
|
||||
* CMD_SET_RADIO_PARAMS changes are visible to lora_radio.reconfigure(). */
|
||||
lora_radio.setPrefs(&companion_mesh.prefs);
|
||||
|
||||
/* Push initial state to UI display */
|
||||
ui_set_node_name(companion_mesh.prefs.node_name);
|
||||
ui_set_radio_params(
|
||||
|
||||
Reference in New Issue
Block a user