Compare commits
26
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36e63aeff0 | ||
|
|
dff6783b3f | ||
|
|
2f30ea2a7b | ||
|
|
17caa64ed7 | ||
|
|
e28472c5bd | ||
|
|
3be89cb70b | ||
|
|
b04eeba139 | ||
|
|
cdce17874a | ||
|
|
e7d1f1524d | ||
|
|
5799a283e8 | ||
|
|
6156429c34 | ||
|
|
f183836b0f | ||
|
|
fc34d457a0 | ||
|
|
9b1f96bf92 | ||
|
|
c1886a666c | ||
|
|
c59e8aefda | ||
|
|
45c0c6b795 | ||
|
|
847f0bb157 | ||
|
|
b8c32c84a1 | ||
|
|
8c4661665b | ||
|
|
2571aeaa4f | ||
|
|
d48f415bcf | ||
|
|
438b2fd47e | ||
|
|
a8c9985704 | ||
|
|
79659433ea | ||
|
|
bdd949c8c7 |
@@ -0,0 +1,66 @@
|
|||||||
|
name: Build HiLink URLLC firmware
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: openipc-builder
|
||||||
|
timeout-minutes: 360
|
||||||
|
env:
|
||||||
|
DEVICE: ssc338q_fpv_openipc-urllc-aio
|
||||||
|
BR2_DL_DIR: /tmp/builder-dl
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout builder branch
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Verify provisioned Buildroot toolchain
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -eu
|
||||||
|
id
|
||||||
|
missing=0
|
||||||
|
for tool in \
|
||||||
|
bash bc bison ccache cpio curl file flex gawk gcc git gzip make \
|
||||||
|
patch perl python3 rsync sed tar tree unzip wget xz; do
|
||||||
|
if ! command -v "$tool" >/dev/null 2>&1; then
|
||||||
|
echo "::error::Missing runner dependency: $tool"
|
||||||
|
missing=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
test "$missing" = 0
|
||||||
|
|
||||||
|
- name: Build exactly the HiLink URLLC profile
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
export GIT_HASH="$(git rev-parse --short HEAD)"
|
||||||
|
export GIT_BRANCH="$(git branch --show-current)"
|
||||||
|
mkdir -p "$BR2_DL_DIR" /tmp/ccache
|
||||||
|
ln -s /tmp/ccache "$HOME/.ccache"
|
||||||
|
|
||||||
|
if ! bash builder.sh "$DEVICE"; then
|
||||||
|
echo '--- largest files retained in the failed rootfs ---'
|
||||||
|
find openipc/output/target -type f -printf '%s\t%p\n' | \
|
||||||
|
sort -nr | sed -n '1,100p' || true
|
||||||
|
echo '--- rootfs target usage ---'
|
||||||
|
du -sh openipc/output/target 2>/dev/null || true
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p dist
|
||||||
|
firmware=$(find openipc/output/images -type f -name 'openipc*nor*.tgz' -print -quit)
|
||||||
|
test -n "$firmware"
|
||||||
|
cp "$firmware" "dist/${DEVICE}-nor.tgz"
|
||||||
|
sha256sum "dist/${DEVICE}-nor.tgz" > "dist/${DEVICE}-nor.tgz.sha256"
|
||||||
|
|
||||||
|
find dist -maxdepth 1 -type f -printf '%f %s bytes\n'
|
||||||
|
cat "dist/${DEVICE}-nor.tgz.sha256"
|
||||||
|
|
||||||
|
- name: Upload firmware artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: hilink-urllc-${{ github.sha }}
|
||||||
|
retention-days: 30
|
||||||
|
path: dist/*
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
bash \
|
||||||
|
bc \
|
||||||
|
bison \
|
||||||
|
build-essential \
|
||||||
|
ca-certificates \
|
||||||
|
ccache \
|
||||||
|
cpio \
|
||||||
|
curl \
|
||||||
|
file \
|
||||||
|
flex \
|
||||||
|
gawk \
|
||||||
|
git \
|
||||||
|
gzip \
|
||||||
|
libncurses-dev \
|
||||||
|
make \
|
||||||
|
nodejs \
|
||||||
|
patch \
|
||||||
|
perl \
|
||||||
|
python3 \
|
||||||
|
rsync \
|
||||||
|
sed \
|
||||||
|
tar \
|
||||||
|
tree \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
xz-utils \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /workspace
|
||||||
@@ -0,0 +1,481 @@
|
|||||||
|
# RTL8812EU enumerating at 12 Mbit/s on `Sstar-ehci-1` — investigation record (root cause found; acceptance pending)
|
||||||
|
|
||||||
|
Device: `ssc338q_fpv_openipc-urllc-aio` (HiLink URLLC, SSC338Q / infinity6e).
|
||||||
|
Radio: Realtek RTL8812EU, USB ID `0bda:a81a`, directly attached to the SSC338Q
|
||||||
|
USB 2.0 EHCI port (`Sstar-ehci-1`).
|
||||||
|
|
||||||
|
## Fixed observations (treated as inputs, not re-derived here)
|
||||||
|
|
||||||
|
- The radio repeatedly enumerated at **12 Mbit/s (full speed)** after USB
|
||||||
|
unbind/rebind cycles (pre-rework symptom; HS since restored — see the
|
||||||
|
series-damping experiment below).
|
||||||
|
- The active device tree reports `dpdm_swap = <0>` and
|
||||||
|
`power-enable-pad = <PAD_UNKNOWN>` (0xffff).
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** the full `soc:Sstar-ehci-1`
|
||||||
|
platform-driver unbind/bind cycle (step 5 below) was performed over
|
||||||
|
Ethernet, waited out, and `/sys/bus/usb/devices/1-1/speed` still returned
|
||||||
|
`12`. A complete HCD/UTMI re-initialization therefore **does not** restore
|
||||||
|
high-speed negotiation on this board.
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** changing the input supply
|
||||||
|
capacity did not improve negotiation. Supply-headroom tuning is ruled out.
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** the radio is a custom
|
||||||
|
carrier/module assembly, **not** a drop-in USB dongle: a four-wire host
|
||||||
|
harness/pad connection, two RF pigtails, and visible local regulation on
|
||||||
|
the carrier.
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** 5.13 V measured directly at the
|
||||||
|
module input, inside the common 4.75–5.25 V input range. The earlier
|
||||||
|
"3.3 V fed into the 5 V input" hypothesis is therefore ruled out **at
|
||||||
|
module ingress** (upstream of the carrier's local regulation).
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** each USB data net was physically
|
||||||
|
traced as `SSC338Q-side -> approximately 100 ohm series resistor ->
|
||||||
|
RTL8812EU-module D+ or D-`; each component measured about 100 ohm across
|
||||||
|
its own endpoints with all power removed. These are **two separate
|
||||||
|
per-line series resistors**, not one 100-ohm differential termination.
|
||||||
|
- **Verified on hardware (2026-10, Piotr):** both previously verified 100
|
||||||
|
ohm per-line resistors were **replaced with matched 12 ohm parts**;
|
||||||
|
immediately afterward `/sys/bus/usb/devices/1-1/speed` returned **`480`**.
|
||||||
|
This is direct A/B evidence that the original 100 ohm-per-line network
|
||||||
|
**blocked High-Speed negotiation** on this unit.
|
||||||
|
- RF/FEC configuration is not a USB fix and is out of scope for this issue.
|
||||||
|
- This document contains no credentials, pairing or RF-access material.
|
||||||
|
|
||||||
|
## Conclusion (root cause found; acceptance pending)
|
||||||
|
|
||||||
|
Combined with the exact vendor EHCI/UTMI source audit below (which found no
|
||||||
|
HiLink-specific software discrepancy in anything this overlay or the shipped
|
||||||
|
kernel build controls), the verified on-hardware results above eliminate the
|
||||||
|
remaining software-adjacent candidates that are cheap to test:
|
||||||
|
|
||||||
|
- **Ruled out:** wifibroadcast/OpenIPC configuration, RF/FEC settings,
|
||||||
|
ordinary userspace timing, a simple USB-device rebind, a full
|
||||||
|
HCD/UTMI re-initialization (done on hardware, no change),
|
||||||
|
input-supply-capacity tuning (done on hardware, no change), and
|
||||||
|
wrong-voltage-at-module-ingress (measured 5.13 V at the input, within the
|
||||||
|
4.75–5.25 V range).
|
||||||
|
- **Fault domain where the cause was found:** the USB **high-speed physical
|
||||||
|
path / signal integrity / rework** — D+/D− routing and symmetry across
|
||||||
|
the carrier, harness/pads and intervening components, controlled impedance
|
||||||
|
and stubs, series/ESD/common-mode components on the pair, connector and
|
||||||
|
solder integrity, or PHY-side / device-side silicon-level hardware —
|
||||||
|
exactly the boundary detailed in the hardware section below. Two supply
|
||||||
|
points were ruled out specifically (capacity tuning, ingress voltage);
|
||||||
|
power **quality** downstream of the measured input — supply noise/ripple
|
||||||
|
and the carrier's local regulator output — remains untested and stays
|
||||||
|
inside the open (now margin-focused) fault domain.
|
||||||
|
|
||||||
|
Two caveats stay attached to this record: the audited paths never
|
||||||
|
characterized the vendor PHY's undocumented analog tuning, and this
|
||||||
|
document distinguishes **immediate HS restoration from full acceptance** —
|
||||||
|
long-term stability and signal margin are unproven (see the acceptance
|
||||||
|
gates below).
|
||||||
|
|
||||||
|
**Root cause (proven on this unit):** the traced per-line ~100 ohm series
|
||||||
|
resistors were the negotiation blocker. FS signaling at 12 Mbit/s is
|
||||||
|
edge-slow and tolerant, while HS chirp/negotiation is amplitude- and
|
||||||
|
timing-critical; replacing both 100 ohm parts with matched 12 ohm parts
|
||||||
|
restored `480` immediately — a direct A/B result. This proof is scoped to
|
||||||
|
**this unit**: the exact SSC338Q PHY/reference-design series value remains
|
||||||
|
undocumented in this repository (the commonly seen external USB 2.0
|
||||||
|
practice of roughly 15-33 ohm is illustrative, not a requirement), so other
|
||||||
|
builds of this carrier should not assume 12 ohm is universally correct.
|
||||||
|
|
||||||
|
Operating posture: the **12 ohm parts stay installed** and **no further
|
||||||
|
resistance changes** are permitted until all three owner-run acceptance
|
||||||
|
gates below are recorded. The **4096 kbit/s** conservative limit remains in
|
||||||
|
force until then; one immediate speed read does not justify higher WFB
|
||||||
|
settings or any claim about long-term signal margin.
|
||||||
|
|
||||||
|
## Audited sources
|
||||||
|
|
||||||
|
Audited 2026-10-02. Everything the firmware ships is stock upstream of this
|
||||||
|
builder overlay — the per-device delta in this repository carries no USB
|
||||||
|
configuration at all. Exact provenance used for the audit:
|
||||||
|
|
||||||
|
| Artifact | Source | Ref |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Kernel | `github.com/openipc/linux`, branch `sigmastar-infinity6e` | branch tip `97b7fc4e` at audit time, Linux 4.9.84 (the defconfig pins the branch, not the SHA, so later builds may move) |
|
||||||
|
| Kernel ref resolution | `OpenIPC/firmware` `general/external.mk` | `OPENIPC_KERNEL := $(OPENIPC_SOC_VENDOR)-$(OPENIPC_SOC_FAMILY)` |
|
||||||
|
| Kernel config | `OpenIPC/firmware` `br-ext-chip-sigmastar/board/infinity6e/infinity6e-ssc012b.config` | selected by this device's defconfig (`BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE`); moving master, HEAD `1b0d5e2` at audit time |
|
||||||
|
| DTB | `arch/arm/boot/dts/infinity6e-ssc012b-s01a.dtb`, built from the in-tree DTS and **compiled into the kernel Image** (`CONFIG_SS_BUILTIN_DTB=y`, `CONFIG_SS_DTB_NAME="infinity6e-ssc012b-s01a"`) | same kernel ref |
|
||||||
|
| WiFi driver | OpenIPC package `rtl88x2eu-openipc` → `github.com/libc0607/rtl88x2eu-20230815` (HEAD) + one cflags patch | `general/package/rtl88x2eu-openipc/rtl88x2eu-openipc.mk` |
|
||||||
|
| Builder overlay | this repository, `devices/ssc338q_fpv_openipc-urllc-aio/` | working tree |
|
||||||
|
|
||||||
|
The bootloader does not hand the kernel an FDT on this platform: with
|
||||||
|
`CONFIG_SS_BUILTIN_DTB=y`, `arch/arm/kernel/devtree.c:281-299` falls back to
|
||||||
|
the DTB embedded in the Image and merges the bootloader's ATAGs (memory,
|
||||||
|
cmdline) into it. The audited DTS is what the running kernel sees.
|
||||||
|
|
||||||
|
### Active DT node (matches the reported runtime state)
|
||||||
|
|
||||||
|
`arch/arm/boot/dts/infinity6e.dtsi:818-828`:
|
||||||
|
|
||||||
|
```
|
||||||
|
Sstar-ehci-1 {
|
||||||
|
compatible = "Sstar-ehci-1";
|
||||||
|
clocks = <&CLK_utmi>;
|
||||||
|
camclk = <CAMCLK_utmi>; /* compiled out: CONFIG_CAM_CLK is not set */
|
||||||
|
interrupts = <GIC_SPI INT_IRQ_UHC IRQ_TYPE_LEVEL_HIGH>;
|
||||||
|
dpdm_swap=<0>;
|
||||||
|
power-enable-pad = <PAD_UNKNOWN>;
|
||||||
|
status = "ok";
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
`PAD_UNKNOWN = 0xFFFF` (`drivers/sstar/include/infinity6e/gpio.h:150`).
|
||||||
|
The board DTS `infinity6e-ssc012b-s01a.dts` applies **no** USB override, and
|
||||||
|
`CONFIG_SS_BUILTIN_UNFDT` is not set, so the kernel Image's builtin DTB is the
|
||||||
|
only device tree in play (see the boot path above). This matches the runtime
|
||||||
|
facts exactly.
|
||||||
|
|
||||||
|
### Kernel config (USB-relevant, `infinity6e-ssc012b.config`)
|
||||||
|
|
||||||
|
- `CONFIG_USB_EHCI_HCD=y` built-in; xHCI/OHCI/DWC2/DWC3 disabled; USB 3.0 node
|
||||||
|
unused for this radio.
|
||||||
|
- `CONFIG_MP_USB_MSTAR=y` — enables the Sstar patch set in
|
||||||
|
`drivers/usb/host/ehci-hcd.c` and `drivers/usb/core/hub.c`.
|
||||||
|
- `# CONFIG_SS_USB_LOWPWR_SUSPEND is not set`; no USB PHY framework drivers
|
||||||
|
(all UTMI handling is inside the Sstar EHCI driver).
|
||||||
|
- `CONFIG_USB_ANNOUNCE_NEW_DEVICES=y` — dmesg reports the enumerated speed.
|
||||||
|
|
||||||
|
## HS chirp / squelch / reset / PHY-tuning paths (as built)
|
||||||
|
|
||||||
|
All tuning is compile-time; there are no runtime knobs in this repo.
|
||||||
|
|
||||||
|
1. **Probe-time UTMI init** — `drivers/sstar/usb/host/ehci-mstar.c`,
|
||||||
|
`Titania3_series_start_ehc()` (lines 232-579), called from
|
||||||
|
`ehci_hcd_mstar_drv_probe()` for `soc:Sstar-ehci-1` (call at line 681):
|
||||||
|
- USBC `0x0a`/`0x28` handshake resets the UHC MAC (lines 297-298).
|
||||||
|
- CA (RX calibration) start/poll at UTMI `0x3c` with a "CA Fail" warning if
|
||||||
|
the result reads all-ones or all-zeros (lines 330-339).
|
||||||
|
- Squelch/disconnect level: `UTMI_DISCON_LEVEL_2A = 0x62`
|
||||||
|
(`ehci-mstar.h:310`) written to UTMI `0x2a` (lines 323-328, 396-397).
|
||||||
|
- Chirp source select UTMI `0x15` bit5 (line 387); new-HW chirp overwrite
|
||||||
|
cleared at UTMI `0x40` bit4 (line 394). `ENABLE_NEW_HW_CHRIP_PATCH` is
|
||||||
|
**not** defined, so the chirp-detect-level register UTMI `0x42` keeps its
|
||||||
|
hardware default.
|
||||||
|
- Eye/ TX tuning: `UTMI_EYE_SETTING_2C..2F = 0x10,0x02,0x00,0x81`
|
||||||
|
(`ehci-mstar.h:355-361`) at UTMI `0x2c..0x2f` (lines 406-410).
|
||||||
|
- `ENABLE_HS_CONNECTION_FAIL_INTO_VFALL_ECO` is on (`ehci-mstar.h:152`),
|
||||||
|
USBC `0x11` bit1 (line 453) — the known "HS connection fails into VFALL"
|
||||||
|
mitigation is active.
|
||||||
|
- DP/DM swap: `_USB_UTMI_DPDM_SWAP_P0 = 0` (`ehci-mstar.h:294`) and
|
||||||
|
`dpdm_swap=<0>` in DT (probe lines 674-678 OR the DT value into `flag`)
|
||||||
|
both agree: no swap. UTMI `0x0b` bit5 stays clear.
|
||||||
|
- `_USB_ANALOG_RX_SQUELCH_PATCH = 0` (`ehci-mstar.h:254-258`): the
|
||||||
|
CA-calibration-based squelch adjustment is compiled out.
|
||||||
|
2. **Per-port-reset chirp window** — `drivers/usb/core/hub.c`
|
||||||
|
`hub_port_reset()` (lines 3124-3216), the `_USB_HS_CHIRP_PATCH` block, runs
|
||||||
|
on every root-hub port reset for USB 2.0:
|
||||||
|
- Before asserting reset: eye parameters zeroed (UTMI `0x2c..0x2f`) and
|
||||||
|
squelch switched to `0x80` at UTMI `0x2a` (line 3168) — the value the
|
||||||
|
Sstar chirp patch uses inside the reset window to catch a weak device
|
||||||
|
chirp.
|
||||||
|
- After the reset: eye parameters and squelch `0x62` restored, then a
|
||||||
|
UTMI TX/RX software-reset pulse (UTMI `0x06` bits1:0, lines 3207-3212).
|
||||||
|
- The FS/HS verdict comes from the EHCI port status alone. The
|
||||||
|
speed-report cross-check against the UHC `0x84/0x85` registers is
|
||||||
|
guarded by `_USB_SPEED_REPORT_RESET_PATCH`, which is referenced at
|
||||||
|
`hub.c:3007` but **never defined anywhere** — that block is compiled
|
||||||
|
out in this build.
|
||||||
|
3. **Full-speed fallback latch** — `hub.c` "bad dev" retry (lines 6113-6165):
|
||||||
|
after repeated failed enumerations the driver sets UHC `0x40` bit7
|
||||||
|
("force full speed", line 6138, via `hcd->ehc_base`); it is cleared on
|
||||||
|
root-hub reinit when the
|
||||||
|
device disconnects (lines 2353, 5557-5559). A device that enumerates
|
||||||
|
successfully at FS from insertion did not need this latch — the port
|
||||||
|
verdict itself was FS.
|
||||||
|
4. **VBUS gating** — `drivers/sstar/usb/host/infinity6e/usb_pad.c`
|
||||||
|
`Enable_USB_VBUS()` (lines 49-106): the DT property is present
|
||||||
|
(`0xffff`), so the fallback default (`PAD_PM_GPIO2`) is not used; the value
|
||||||
|
is truncated to `(unsigned char)0xffff = 255` (line 80). 255 is out of
|
||||||
|
range on this SoC — `GPIO_NR = 127`
|
||||||
|
(`drivers/sstar/include/infinity6e/gpio.h:149`, range-checked in
|
||||||
|
`mhal_pinmux.c:2054`) — so `gpio_request(255)` fails and the function
|
||||||
|
returns early. The probe ignores the return value
|
||||||
|
(`ehci-mstar.c:680`). Net effect: **no kernel-side VBUS gate**; VBUS to
|
||||||
|
the module is board-hardwired. Consistent with the device enumerating at
|
||||||
|
all.
|
||||||
|
5. **Clocks** — nothing in Linux consumes `CLK_utmi`/`CAMCLK_utmi` for this
|
||||||
|
controller: the EHCI driver contains no clock/camclk code at all, so the
|
||||||
|
UTMI reference clock state is inherited from the bootloader. There is no
|
||||||
|
in-Linux analog power-cycle; the closest in-kernel equivalent is a full
|
||||||
|
HCD unbind/rebind (below), which re-runs the whole
|
||||||
|
`Titania3_series_start_ehc()` block including CA calibration.
|
||||||
|
6. **WiFi driver** — `rtl88x2eu-20230815` `os_dep/linux/usb_intf.c`
|
||||||
|
(lines 637-661) passively records `pusbd->speed` (`USB_SPEED_FULL` →
|
||||||
|
`RTW_USB_SPEED_1_1`). There is no module parameter, retry or force-HS
|
||||||
|
logic in the Realtek driver; at most it *adapts* to the reported speed
|
||||||
|
(e.g. `USB_FULL_SPEED_BULK_SIZE` in `include/usb_ops.h:128-145`). The
|
||||||
|
speed is decided entirely by the host controller/PHY.
|
||||||
|
|
||||||
|
## Why no device-specific software discrepancy was found (in this repository)
|
||||||
|
|
||||||
|
- This repository's per-device delta for `ssc338q_fpv_openipc-urllc-aio`
|
||||||
|
contains no USB-host configuration anywhere: the defconfig selects
|
||||||
|
packages/flash size only, `load_sigmastar` drives the camera pipeline only,
|
||||||
|
the overlay seeds WiFi/wifibroadcast config, and the exclude list only
|
||||||
|
trims rootfs files.
|
||||||
|
- The defconfig is byte-identical to the closest sibling device
|
||||||
|
(`ssc338q_fpv_openipc-mario-aio`), so there is no per-device divergence to
|
||||||
|
correct.
|
||||||
|
- Kernel, builtin DTB and kernel config are stock `openipc/linux`
|
||||||
|
`sigmastar-infinity6e` / `OpenIPC/firmware` artifacts; the DT state
|
||||||
|
(`dpdm_swap=0`, `power-enable-pad=0xffff`) matches the reported runtime
|
||||||
|
state, i.e. the firmware built is the firmware audited.
|
||||||
|
- The FS fallback mitigations that exist in the kernel (chirp-window squelch
|
||||||
|
`0x80`, VFALL ECO) are compiled in and active for this build; the
|
||||||
|
speed-report cross-check is compiled out (undefined macro), which weakens
|
||||||
|
detection of a mis-reported speed but cannot by itself cause one.
|
||||||
|
- Therefore a device-specific **software** correction within this repository
|
||||||
|
is not justified by the evidence. A real fix would be a kernel-side change
|
||||||
|
(openipc/linux driver/DT) or hardware — both outside this overlay's scope.
|
||||||
|
|
||||||
|
### Candidate corrections considered and rejected
|
||||||
|
|
||||||
|
- `dpdm_swap=<1>`: a swapped D+/D- pair would break full-speed enumeration
|
||||||
|
too (same pair, same polarity); the device enumerates at FS, so polarity is
|
||||||
|
correct. Flipping it would kill enumeration entirely. Rejected.
|
||||||
|
- Enable `_USB_ANALOG_RX_SQUELCH_PATCH` or change `UTMI_DISCON_LEVEL_2A` /
|
||||||
|
eye settings: driver-source macro changes in `openipc/linux`, with no
|
||||||
|
in-repo evidence to pick values; the chirp window already uses the most
|
||||||
|
sensitive squelch (`0x80`). Rejected without on-hardware UTMI measurements.
|
||||||
|
- `power-enable-pad` → a real pad: VBUS is evidently board-hardwired
|
||||||
|
(device enumerates with the property at `PAD_UNKNOWN`); pointing the gate
|
||||||
|
at a wrong pad risks switching VBUS off. Rejected.
|
||||||
|
- WiFi driver module options: none exist that influence enumeration speed
|
||||||
|
(driver is passive). Rejected.
|
||||||
|
|
||||||
|
## HiLink D+/D- hardware / rework investigation boundary
|
||||||
|
|
||||||
|
Assembly as observed (2026-10, Piotr): the radio is a custom
|
||||||
|
carrier/module — not a drop-in dongle — connected to the host by a
|
||||||
|
**four-wire harness/pad** connection, with **two RF pigtails** and visible
|
||||||
|
**local regulation** on the carrier. The pad assignments have **not** been
|
||||||
|
documented yet; nothing below assumes one.
|
||||||
|
|
||||||
|
With the software and software-adjacent candidates ruled out (see the
|
||||||
|
conclusion above), the remaining fault domain is the USB **high-speed
|
||||||
|
physical path / signal integrity / rework**, explicitly outside software
|
||||||
|
scope:
|
||||||
|
|
||||||
|
- D+/D- pair routing on the HiLink carrier and through the four-wire
|
||||||
|
harness: continuity and symmetry from the SSC338Q pads to the module
|
||||||
|
pads; controlled impedance along the pair; stubs or test points hanging
|
||||||
|
off it; series resistors / ESD protection / common-mode chokes or other
|
||||||
|
intervening components; via, connector/harness and solder joint integrity.
|
||||||
|
- HS chirp failure with FS working is the classic marginal-analog signature:
|
||||||
|
the same pair carries FS traffic fine while the HS chirp (a short,
|
||||||
|
amplitude-critical burst at reset) is missed by the host squelch detector.
|
||||||
|
|
||||||
|
**Next physical gate (before any rework):**
|
||||||
|
|
||||||
|
1. **Macro photographs of both sides** of the carrier/module — not yet
|
||||||
|
reported.
|
||||||
|
2. **Identify all four host pads** — determine which are VBUS, GND, D+,
|
||||||
|
D- (the four-wire harness implies the classic set, but the actual
|
||||||
|
assignment must come from tracing, not assumption) — not yet reported in
|
||||||
|
full; the two data nets and their series resistors have been traced (see
|
||||||
|
the fixed observations above).
|
||||||
|
3. **Trace D+/D- end to end**, identifying every intervening component —
|
||||||
|
series resistors, ESD arrays, common-mode chokes, vias, connectors,
|
||||||
|
harness wires — and where the pair leaves the board. **Status: performed
|
||||||
|
for both data nets** — each net is `SSC338Q-side -> ~100 ohm series
|
||||||
|
resistor -> module D+/D-`, each resistor measuring ~100 ohm across its
|
||||||
|
own endpoints, de-energized. No other intervening component was reported
|
||||||
|
on the data nets.
|
||||||
|
|
||||||
|
**Safety rule for all continuity/ohmmeter work:** only with **all power
|
||||||
|
removed and rails discharged** (unplug, then verify the rails are at 0 V
|
||||||
|
before touching meter probes to pads). No powered measurements are proposed
|
||||||
|
at this stage.
|
||||||
|
|
||||||
|
### Series-damping experiment — COMPLETED AND SUCCESSFUL (2026-10, Piotr)
|
||||||
|
|
||||||
|
**Result:** instead of the planned parallel-resistor step, Piotr performed a
|
||||||
|
direct A/B replacement: **both 100 ohm per-line series resistors were
|
||||||
|
replaced with matched 12 ohm parts**, and `/sys/bus/usb/devices/1-1/speed`
|
||||||
|
returned **`480`** immediately afterward. This **proves the original 100
|
||||||
|
ohm-per-line network blocked High-Speed negotiation** on this unit. The
|
||||||
|
proposed parallel route below is **superseded** (never executed) and is kept
|
||||||
|
only as the historical rationale for why the series value was the prime
|
||||||
|
suspect.
|
||||||
|
|
||||||
|
Rationale (historical): if the ~100 ohm per-line series resistors over-damp
|
||||||
|
the pair, reducing the effective per-line series resistance into the range
|
||||||
|
of common external USB 2.0 practice may let the HS chirp/eye reach the host
|
||||||
|
squelch/timing margins again. This was a **bounded, fully reversible**
|
||||||
|
framing: the target value was an example chosen from common practice,
|
||||||
|
**not** the documented SSC338Q PHY/reference-design requirement, which
|
||||||
|
remains undocumented in this repository.
|
||||||
|
|
||||||
|
Proposed steps as planned (historical — superseded by the direct
|
||||||
|
replacement actually performed; retained for reproducibility of the method):
|
||||||
|
|
||||||
|
Pre-flight gate (no soldering before this is done):
|
||||||
|
|
||||||
|
1. Confirm the two resistors' **package size** and mark their **exact
|
||||||
|
locations** (photograph before touching anything).
|
||||||
|
2. Confirm the workmanship/ESD plan for soldering on the carrier.
|
||||||
|
|
||||||
|
Experiment (reversible — nothing is removed, parts are added in parallel):
|
||||||
|
|
||||||
|
1. With **all power removed and rails discharged and verified at 0 V**
|
||||||
|
(same rule as above). The work setup itself must not be able to feed
|
||||||
|
voltage onto the unpowered board — including through the soldering
|
||||||
|
iron's supply path — so use an isolated or battery-powered iron or
|
||||||
|
equivalent isolation. Solder **one matched resistor in parallel across
|
||||||
|
each** existing 100 ohm part — **D+ and D- must be treated
|
||||||
|
identically**.
|
||||||
|
2. Example value: 33 ohm in parallel with 100 ohm gives an effective
|
||||||
|
(33 x 100) / (33 + 100) = 3300 / 133 = **24.8 ohm per line** (~25 ohm).
|
||||||
|
Any parallel pair follows R_eff = (R1 x R2) / (R1 + R2); keep the same
|
||||||
|
value on both lines.
|
||||||
|
3. Inspect under magnification for **bridges, solder balls or damage** to
|
||||||
|
the parts and neighbours; the two lines must look identical.
|
||||||
|
4. **Before restoring power**, measure each modified net again (de-energized)
|
||||||
|
and confirm both read the same effective value, within part tolerance.
|
||||||
|
5. Restore power **only after inspection** and run a fresh USB enumeration
|
||||||
|
check (`cat /sys/bus/usb/devices/1-1/speed`).
|
||||||
|
|
||||||
|
**Acceptance criterion:** actual **480** Mbit/s negotiation. The
|
||||||
|
enumeration result is the only judge of this test: no final line impedance
|
||||||
|
or eye-quality outcome is assumed without signal-integrity measurement (a
|
||||||
|
later diagnostic above). If behaviour regresses in any way or HS is **not**
|
||||||
|
achieved, **revert immediately**: remove the parallel parts to restore the
|
||||||
|
original ~100 ohm per line, and record what was observed. Until HS is
|
||||||
|
actually demonstrated, keep the **4096 kbit/s** operating limit (see the
|
||||||
|
conclusion) regardless of this experiment. (That historical condition is
|
||||||
|
now met — the current rule for the 4096 kbit/s limit is the acceptance
|
||||||
|
gates in the next subsection, not this paragraph.)
|
||||||
|
|
||||||
|
### Acceptance gates after the successful rework (outstanding, owner-run)
|
||||||
|
|
||||||
|
Immediate HS restoration is **not yet full acceptance**. The 12 ohm parts
|
||||||
|
stay installed, and **no further resistance changes** are to be made until
|
||||||
|
all three of these gates are recorded on this unit:
|
||||||
|
|
||||||
|
1. **Fresh dmesg** shows a new high-speed enumeration for the radio without
|
||||||
|
relevant USB errors.
|
||||||
|
2. A **full `soc:Sstar-ehci-1` platform-driver unbind/bind** (step 5 in the
|
||||||
|
on-device section below, over Ethernet/console) still returns `480`.
|
||||||
|
3. The **established wifibroadcast baseline operates stably** with no USB
|
||||||
|
disconnect/reset events during operation.
|
||||||
|
|
||||||
|
The **4096 kbit/s** conservative limit stays in force until all three pass;
|
||||||
|
do not infer higher WFB settings or long-term signal margin from the single
|
||||||
|
immediate `480` read. Safety/rework provenance as documented above applies:
|
||||||
|
all board work was and remains de-energized work with verified discharged
|
||||||
|
rails.
|
||||||
|
|
||||||
|
Isolation diagnostics (historical — moot on this unit now that the root
|
||||||
|
cause is fixed and HS is restored; retained for future units of this
|
||||||
|
carrier or if symptoms return; all of them need rework access — the radio
|
||||||
|
is pad-connected, not socketed, so this may mean a temporary rework socket
|
||||||
|
or piggyback harness):
|
||||||
|
|
||||||
|
- Try a **known-good HS USB device** (any USB 2.0 flash disk) on the same
|
||||||
|
host pads. HS on the disk but not on the radio points at the
|
||||||
|
carrier/module side; FS on both points at the board-side pair.
|
||||||
|
- Try the **RTL8812EU carrier on a different known-good HS host** (a PC).
|
||||||
|
HS there isolates the fault to this board's physical path.
|
||||||
|
- With suitable equipment, capture the HS chirp amplitude/eye at the host
|
||||||
|
pads against the USB 2.0 electrical limits.
|
||||||
|
|
||||||
|
Any board rework (series resistor changes, pair shortening, shielding)
|
||||||
|
invalidates prior software observations; re-verify from the on-device
|
||||||
|
commands below after any hardware change.
|
||||||
|
|
||||||
|
Evidence status: the platform-driver re-probe (step 5 below), the
|
||||||
|
input-supply-capacity change, the module-input voltage measurement, the
|
||||||
|
per-line series-resistor tracing (de-energized resistance checks), and the
|
||||||
|
series-resistor replacement (100 ohm -> matched 12 ohm per line, both data
|
||||||
|
nets) were performed on hardware (2026-10, Piotr). The replacement restored
|
||||||
|
`480` immediately; the three acceptance gates above are **outstanding**.
|
||||||
|
The register-read diagnostics (steps 1-4 below) have not been reported; the
|
||||||
|
parallel-resistor variant was never executed.
|
||||||
|
|
||||||
|
## On-device verification (read-only diagnostics; step 5 re-probe already completed on hardware)
|
||||||
|
|
||||||
|
Run from a root shell on the device over a link that is **not** the USB radio
|
||||||
|
(Ethernet or serial console — see the wlan0 warning in step 5). All register
|
||||||
|
reads are read-only `devmem` accesses; do **not** write UTMI/USBC/UHC
|
||||||
|
registers from userspace (a write can wedge the bus until reboot).
|
||||||
|
Steps 1-4 have not been run/reported on the affected board yet and remain
|
||||||
|
the cheapest way to capture register-level evidence (CA calibration result,
|
||||||
|
squelch value, line state, force-FS latch) alongside the hardware work.
|
||||||
|
|
||||||
|
Register addresses (physical; the RIU window maps virtual `0xFD200000` to
|
||||||
|
physical `0x1F200000` — `MS_IO_OFFSET 0xDE000000`,
|
||||||
|
`drivers/sstar/include/ms_platform.h:24`, plus `registers.h:37-38`). Register
|
||||||
|
number `n` sits at byte offset `2*n`, except odd `n` which sits at `2*n - 1`
|
||||||
|
(exactly what `hcd_readb` does, `hub.c:116-129`). All reads are byte or
|
||||||
|
16-bit reads at these byte addresses.
|
||||||
|
|
||||||
|
| Block | Base (physical) | Derived from |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| UTMI0 | `0x1F284200` | `_MSTAR_UTMI0_BASE = 0xFD200000 + 0x42100*2` (`ehci-mstar-chip.h:37`) |
|
||||||
|
| USBC0 | `0x1F284600` | `+ 0x42300*2` (`ehci-mstar-chip.h:39`) |
|
||||||
|
| UHC0 (EHCI) | `0x1F284800` | `+ 0x42400*2` (`ehci-mstar-chip.h:40`) |
|
||||||
|
|
||||||
|
1. **Current enumerated speed**
|
||||||
|
```
|
||||||
|
cat /sys/bus/usb/devices/*/speed # expect 12 (FS symptom) or 480 (HS fixed)
|
||||||
|
dmesg | grep -E 'new (full|high)-speed USB device'
|
||||||
|
```
|
||||||
|
2. **Force-full-speed latch check** (stuck FS from a past failed HS enum)
|
||||||
|
```
|
||||||
|
devmem 0x1F284880 8 # UHC+0x40 bit7: 0x00/0x80
|
||||||
|
```
|
||||||
|
Expected if healthy: bit7 clear. If bit7 is set, a previous enumeration
|
||||||
|
failure latched FS; disconnect/reconnect the module's power (the
|
||||||
|
root-hub reinit on disconnect clears it) and repeat.
|
||||||
|
3. **Port / line state** (all UHC0 = EHCI bank, `hcd->ehc_base`; bit
|
||||||
|
semantics as used by the driver: `hub.c:4998` enable=bit2, `urb.c:532`
|
||||||
|
connect=bit0, `message.c:88` csc=bit1, `hub.c:5801-5802` line state)
|
||||||
|
```
|
||||||
|
devmem 0x1F284860 8 # UHC+0x30: bit0 connect, bit1 csc, bit2 enable
|
||||||
|
devmem 0x1F284881 8 # UHC+0x41: bits2:1 line state (odd reg -> 2n-1)
|
||||||
|
devmem 0x1F284908 8 # UHC+0x84: bit7 of the speed report
|
||||||
|
devmem 0x1F28490A 8 # UHC+0x85: bits3:0 of the speed report
|
||||||
|
```
|
||||||
|
Speed-report composition (`hub.c:3007-3030`; the kernel-side cross-check
|
||||||
|
is compiled out — these are raw hardware registers):
|
||||||
|
`spd = (bit7 of UHC+0x84) | ((UHC+0x85 & 0xf) << 1)`; `0x0c` = high
|
||||||
|
speed, `0x06` = full speed.
|
||||||
|
4. **UTMI tuning as left by the driver**
|
||||||
|
```
|
||||||
|
devmem 0x1F284254 8 # UTMI+0x2a squelch: expect 0x62 idle
|
||||||
|
devmem 0x1F284278 16 # UTMI+0x3c CA calibration (16-bit)
|
||||||
|
```
|
||||||
|
`CA_FAIL` signature (as the driver checks it, `ehci-mstar.c:337-339`):
|
||||||
|
the 16-bit value at UTMI+0x78 masked with `0xFFF0` reading `0x0000` or
|
||||||
|
`0xFFF0` — a failed RX calibration suppresses chirp detection and points
|
||||||
|
at power/analog, not software. `dmesg` also prints `WARNING: CA Fail !!`.
|
||||||
|
5. **Full PHY re-init (in-kernel equivalent of a power cycle) — COMPLETED,
|
||||||
|
no improvement** (2026-10, Piotr: performed over Ethernet, device still
|
||||||
|
enumerated at 12 Mbit/s). Kept here for reproducibility:
|
||||||
|
```
|
||||||
|
ls /sys/bus/platform/drivers/Sstar-ehci-1/ # note the device name
|
||||||
|
echo <device> > /sys/bus/platform/drivers/Sstar-ehci-1/unbind
|
||||||
|
echo <device> > /sys/bus/platform/drivers/Sstar-ehci-1/bind
|
||||||
|
```
|
||||||
|
Safety: `wlan0` on this device is the USB radio itself (`8812eu`,
|
||||||
|
`S40network:6`), so unbinding the EHCI **takes wlan0 down** — run this
|
||||||
|
from Ethernet or a serial console, never over the USB radio's link. The
|
||||||
|
radio disappears and re-enumerates after `bind`; if `wlan0` does not come
|
||||||
|
back on its own, re-run the network init (`/etc/init.d/S40network`
|
||||||
|
restart) rather than poking WiFi config.
|
||||||
|
Rebind re-runs `Titania3_series_start_ehc()` (USBC reset handshake, CA
|
||||||
|
calibration, squelch/eye init) and then re-enumerates the radio. Expected
|
||||||
|
dmesg on HS success: `Sstar-ehci-1 H.W init`, `[USB] init squelch level 0x..`
|
||||||
|
and a `new high-speed USB device number N` line. Re-running steps 1-4
|
||||||
|
afterwards gives the post-init register state. Observed on hardware: the
|
||||||
|
device re-enumerated at full speed again.
|
||||||
|
6. **True analog power cycle** — only a full board re-power removes power
|
||||||
|
from the UTMI PHY and the module (VBUS is hardwired; `power-enable-pad`
|
||||||
|
is not driven by Linux). Note this is distinct from the already-tested
|
||||||
|
input-supply-*capacity* change, which alters headroom but was recorded as
|
||||||
|
not improving negotiation. Power-cycle, then repeat steps 1-5 and compare:
|
||||||
|
identical FS results across cold boot, re-probe and replug indicate the
|
||||||
|
condition is stable (analog/hardware), while an occasional HS success
|
||||||
|
would point at marginal timing.
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
start() {
|
||||||
|
echo "Starting network..."
|
||||||
|
ifup lo
|
||||||
|
modprobe 8812eu rtw_tx_pwr_by_rate=0 rtw_tx_pwr_lmt_enable=0
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
ifdown lo
|
||||||
|
ifdown -f wlan0
|
||||||
|
ifdown -f eth0
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start|stop) "$1" ;;
|
||||||
|
restart|reload) stop; start ;;
|
||||||
|
*) echo "Usage: $0 {start|stop|restart|reload}"; exit 1 ;;
|
||||||
|
esac
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
ifdown eth0 2>/dev/null || true
|
||||||
|
ifup eth0
|
||||||
|
sleep 5
|
||||||
|
/usr/bin/mgmt-net --force
|
||||||
|
|
||||||
|
if [ -r /run/mgmt-netd.pid ] &&
|
||||||
|
kill -0 "$(cat /run/mgmt-netd.pid)" 2>/dev/null; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
(
|
||||||
|
while :; do
|
||||||
|
/usr/bin/mgmt-net
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
echo $! >/run/mgmt-netd.pid
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
[ -r /run/mgmt-netd.pid ] &&
|
||||||
|
kill "$(cat /run/mgmt-netd.pid)" 2>/dev/null || true
|
||||||
|
rm -f /run/mgmt-netd.pid /run/mgmt-net.state
|
||||||
|
;;
|
||||||
|
esac
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
pidof wfb_tx wfb_rx wfb_tun wifilink >/dev/null && exit 0
|
||||||
|
pidof msposd >/dev/null && exit 0
|
||||||
|
|
||||||
|
size=$(curl -s localhost/api/v1/config.json | \
|
||||||
|
jsonfilter -qe "@.video0.size")
|
||||||
|
size="${size:-1280x720}"
|
||||||
|
|
||||||
|
msposd \
|
||||||
|
-b 115200 \
|
||||||
|
-c 8 \
|
||||||
|
-c 6 \
|
||||||
|
-p 500 \
|
||||||
|
-w 1000 \
|
||||||
|
--mspvtx \
|
||||||
|
-r 20 \
|
||||||
|
-m /dev/ttyS2 \
|
||||||
|
-o 127.0.0.1:14551 \
|
||||||
|
-z "$size" \
|
||||||
|
>/tmp/msposd-management.log 2>&1 &
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
echo "Starting wifibroadcast..."
|
||||||
|
wifibroadcast start
|
||||||
|
;;
|
||||||
|
|
||||||
|
stop)
|
||||||
|
echo "Stopping wifibroadcast..."
|
||||||
|
wifibroadcast stop
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
system:
|
||||||
|
webPort: 80
|
||||||
|
httpsPort: 443
|
||||||
|
logLevel: info
|
||||||
|
isp:
|
||||||
|
antiFlicker: disabled
|
||||||
|
sensorConfig: /etc/sensors/imx415_infinity6e.bin
|
||||||
|
exposure: 5
|
||||||
|
iqServer: false
|
||||||
|
image:
|
||||||
|
mirror: false
|
||||||
|
flip: false
|
||||||
|
rotate: 0
|
||||||
|
contrast: 50
|
||||||
|
hue: 50
|
||||||
|
saturation: 50
|
||||||
|
luminance: 50
|
||||||
|
video0:
|
||||||
|
enabled: true
|
||||||
|
codec: h264
|
||||||
|
fps: 60
|
||||||
|
bitrate: 4096
|
||||||
|
rcMode: cbr
|
||||||
|
gopSize: 0.2
|
||||||
|
size: 1280x720
|
||||||
|
profile: main
|
||||||
|
sliceUnits: 0
|
||||||
|
video1:
|
||||||
|
enabled: false
|
||||||
|
codec: h264
|
||||||
|
size: 704x576
|
||||||
|
fps: 15
|
||||||
|
jpeg:
|
||||||
|
enabled: true
|
||||||
|
qfactor: 50
|
||||||
|
fps: 5
|
||||||
|
osd:
|
||||||
|
enabled: false
|
||||||
|
font: /usr/share/fonts/truetype/UbuntuMono-Regular.ttf
|
||||||
|
template: '%d.%m.%Y %H:%M:%S'
|
||||||
|
posX: 16
|
||||||
|
posY: 16
|
||||||
|
audio:
|
||||||
|
enabled: false
|
||||||
|
volume: 30
|
||||||
|
srate: 8000
|
||||||
|
codec: opus
|
||||||
|
outputEnabled: false
|
||||||
|
outputVolume: 30
|
||||||
|
rtsp:
|
||||||
|
enabled: false
|
||||||
|
port: 554
|
||||||
|
nightMode:
|
||||||
|
colorToGray: true
|
||||||
|
irCutSingleInvert: false
|
||||||
|
lightMonitor: false
|
||||||
|
lightSensorInvert: false
|
||||||
|
motionDetect:
|
||||||
|
enabled: false
|
||||||
|
visualize: false
|
||||||
|
debug: false
|
||||||
|
records:
|
||||||
|
enabled: false
|
||||||
|
path: /mnt/mmcblk0p1/%F
|
||||||
|
split: 1
|
||||||
|
maxUsage: 95
|
||||||
|
notime: true
|
||||||
|
outgoing:
|
||||||
|
enabled: true
|
||||||
|
naluSize: 1400
|
||||||
|
wfb: true
|
||||||
|
server:
|
||||||
|
substream: false
|
||||||
|
watchdog:
|
||||||
|
enabled: true
|
||||||
|
timeout: 300
|
||||||
|
hls:
|
||||||
|
enabled: false
|
||||||
|
fpv:
|
||||||
|
enabled: true
|
||||||
|
noiseLevel: 1
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
iface eth0 inet static
|
||||||
|
hwaddress ether $(fw_printenv -n ethaddr || echo 00:00:23:34:45:66)
|
||||||
|
address 192.168.0.10
|
||||||
|
netmask 255.255.255.0
|
||||||
|
gateway 192.168.0.1
|
||||||
|
post-up echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
auto wlan0
|
||||||
|
iface wlan0 inet static
|
||||||
|
address 192.168.0.10
|
||||||
|
netmask 255.255.255.0
|
||||||
|
gateway 192.168.0.1
|
||||||
|
pre-up wpa_passphrase "$(fw_printenv -n wlanssid)" "$(fw_printenv -n wlanpass)" > /tmp/wpa_supplicant.conf
|
||||||
|
pre-up sed -i 's/#psk.*/scan_ssid=1/g' /tmp/wpa_supplicant.conf
|
||||||
|
pre-up wpa_supplicant -B -i wlan0 -D nl80211,wext -c /tmp/wpa_supplicant.conf
|
||||||
|
post-up echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||||
|
post-down killall -q wpa_supplicant
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
wireless:
|
||||||
|
txpower: 10
|
||||||
|
channel: 161
|
||||||
|
width: 20
|
||||||
|
mlink: 1500
|
||||||
|
broadcast:
|
||||||
|
mcs_index: 2
|
||||||
|
tun_index: 1
|
||||||
|
fec_k: 8
|
||||||
|
fec_n: 12
|
||||||
|
stbc: 0
|
||||||
|
ldpc: 0
|
||||||
|
link_id: 7669206
|
||||||
|
telemetry:
|
||||||
|
router: msposd
|
||||||
|
serial: ttyS2
|
||||||
|
osd_fps: 20
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
CHANNEL="${1:-}"
|
||||||
|
VALUE="${2:-}"
|
||||||
|
|
||||||
|
# CH6 is the GX12 WFB knob. Betaflight exposes it as 1000..2000 PWM.
|
||||||
|
[ "$CHANNEL" = "6" ] || exit 0
|
||||||
|
|
||||||
|
case "$VALUE" in
|
||||||
|
''|*[!0-9]*) exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# First 5% is an explicit OFF detent. Above it WFB starts at 5% and the
|
||||||
|
# remaining travel maps continuously to 100%. This is a UI-range guard, not a
|
||||||
|
# regulatory EIRP cap.
|
||||||
|
if [ "$VALUE" -le 1050 ]; then
|
||||||
|
rm -f /run/wfb-power
|
||||||
|
logger -t channels "CH6=$VALUE -> management"
|
||||||
|
exec /usr/bin/link-mode management
|
||||||
|
fi
|
||||||
|
|
||||||
|
POWER=$((5 + (VALUE - 1051) * 95 / 949))
|
||||||
|
[ "$POWER" -gt 100 ] && POWER=100
|
||||||
|
logger -t channels "CH6=$VALUE -> WFB txpower=$POWER"
|
||||||
|
exec /usr/bin/wfb-power "$POWER"
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
LOCK=/run/link-mode.lock
|
||||||
|
STATE=/run/link-mode.state
|
||||||
|
|
||||||
|
log() {
|
||||||
|
logger -t link-mode "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! mkdir "$LOCK" 2>/dev/null; then
|
||||||
|
log "another transition is in progress; ignoring ${1:-}"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
rmdir "$LOCK" 2>/dev/null || true
|
||||||
|
}
|
||||||
|
|
||||||
|
trap cleanup EXIT HUP INT TERM
|
||||||
|
|
||||||
|
wfb_active() {
|
||||||
|
pidof wfb_tx wfb_rx wfb_tun wifilink >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
preflight)
|
||||||
|
if wfb_active; then
|
||||||
|
echo wfb >"$STATE"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "management -> WFB"
|
||||||
|
ifdown wlan0 >/dev/null 2>&1 || true
|
||||||
|
killall -q wpa_supplicant 2>/dev/null || true
|
||||||
|
ip link set wlan0 up
|
||||||
|
|
||||||
|
if /usr/bin/wifibroadcast start && wfb_active; then
|
||||||
|
echo wfb >"$STATE"
|
||||||
|
log "WFB is active"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "WFB start failed"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
management)
|
||||||
|
if wfb_active; then
|
||||||
|
log "WFB -> management"
|
||||||
|
/usr/bin/wifibroadcast stop
|
||||||
|
killall -q wifilink 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
/usr/bin/mgmt-net --force
|
||||||
|
echo management >"$STATE"
|
||||||
|
log "management path restored"
|
||||||
|
/etc/init.d/S97link-monitor start
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {preflight|management}" >&2
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
STATE=/run/mgmt-net.state
|
||||||
|
LINK_LOCK=/run/link-mode.lock
|
||||||
|
FORCE="${1:-}"
|
||||||
|
|
||||||
|
[ -e "$LINK_LOCK" ] && [ "$FORCE" != "--force" ] && exit 0
|
||||||
|
|
||||||
|
eth_standby() {
|
||||||
|
ifdown eth0 2>/dev/null || true
|
||||||
|
ifup eth0
|
||||||
|
ip addr flush dev eth0
|
||||||
|
}
|
||||||
|
|
||||||
|
carrier=0
|
||||||
|
if [ -r /sys/class/net/eth0/carrier ]; then
|
||||||
|
carrier=$(cat /sys/class/net/eth0/carrier 2>/dev/null || echo 0)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if pidof wfb_tx wfb_rx wfb_tun wifilink >/dev/null; then
|
||||||
|
wfb_active=1
|
||||||
|
else
|
||||||
|
wfb_active=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$carrier" = "1" ]; then
|
||||||
|
wanted=ethernet
|
||||||
|
elif [ "$wfb_active" = "1" ]; then
|
||||||
|
wanted=wfb
|
||||||
|
else
|
||||||
|
wanted=wifi
|
||||||
|
fi
|
||||||
|
|
||||||
|
current=$(cat "$STATE" 2>/dev/null || true)
|
||||||
|
[ "$wanted" = "$current" ] && [ "$FORCE" != "--force" ] && exit 0
|
||||||
|
|
||||||
|
case "$wanted" in
|
||||||
|
ethernet)
|
||||||
|
[ "$wfb_active" = "0" ] && ifdown wlan0 2>/dev/null || true
|
||||||
|
ifdown eth0 2>/dev/null || true
|
||||||
|
ifup eth0
|
||||||
|
;;
|
||||||
|
|
||||||
|
wifi)
|
||||||
|
eth_standby
|
||||||
|
ifdown wlan0 2>/dev/null || true
|
||||||
|
ip link set wlan0 down
|
||||||
|
iw dev wlan0 set type managed
|
||||||
|
ip link set wlan0 up
|
||||||
|
ifup wlan0
|
||||||
|
;;
|
||||||
|
|
||||||
|
wfb)
|
||||||
|
eth_standby
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo "$wanted" >"$STATE"
|
||||||
|
logger -t mgmt-net "active path: $wanted"
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
POWER="${1:-}"
|
||||||
|
LOCK=/run/wfb-power.lock
|
||||||
|
STATE=/run/wfb-power
|
||||||
|
|
||||||
|
case "$POWER" in
|
||||||
|
''|*[!0-9]*) exit 2 ;;
|
||||||
|
esac
|
||||||
|
[ "$POWER" -ge 5 ] && [ "$POWER" -le 100 ] || exit 2
|
||||||
|
|
||||||
|
# The runtime state is tmpfs. Do not rewrite /etc/wfb.yaml while a knob moves.
|
||||||
|
printf '%s\n' "$POWER" >"$STATE"
|
||||||
|
|
||||||
|
if ! mkdir "$LOCK" 2>/dev/null; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
trap 'rmdir "$LOCK" 2>/dev/null || true' EXIT HUP INT TERM
|
||||||
|
|
||||||
|
if pidof wfb_tx wfb_rx wfb_tun wifilink >/dev/null; then
|
||||||
|
# RTL8812EU accepts 0..3150 mBm driver units; map the user-facing 0..100
|
||||||
|
# scalar over that complete hardware-supported range.
|
||||||
|
iw wlan0 set txpower fixed $((POWER * 3150 / 100))
|
||||||
|
logger -t wfb-power "runtime txpower=$POWER"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
logger -t wfb-power "txpower=$POWER -> WFB preflight"
|
||||||
|
/usr/bin/link-mode preflight
|
||||||
+202
@@ -0,0 +1,202 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
wfb_key=/etc/drone.key
|
||||||
|
wfb_cfg=/etc/wfb.yaml
|
||||||
|
wfb_dev=wlan0
|
||||||
|
|
||||||
|
echo_log() {
|
||||||
|
echo "$1" | logger -s -t wifibroadcast
|
||||||
|
}
|
||||||
|
|
||||||
|
wfb_yaml() {
|
||||||
|
if [ -e "$1" ]; then
|
||||||
|
while IFS=: read -r key value; do
|
||||||
|
key=$(eval echo "$key")
|
||||||
|
value=$(eval echo "$value")
|
||||||
|
export "$key=$value"
|
||||||
|
done < "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_config() {
|
||||||
|
wfb_yaml /rom"$wfb_cfg"
|
||||||
|
wfb_yaml "$wfb_cfg"
|
||||||
|
if [ -r /run/wfb-power ]; then
|
||||||
|
runtime_txpower=$(cat /run/wfb-power)
|
||||||
|
case "$runtime_txpower" in
|
||||||
|
[5-9]|[1-9][0-9]|100) txpower="$runtime_txpower" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
[ ! -e "$wfb_key" ] && wfb_key=/rom"$wfb_key"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_modules() {
|
||||||
|
for card in $(lsusb | awk '{print $6}' | uniq); do
|
||||||
|
case "$card" in
|
||||||
|
"0bda:8812" | "0bda:881a" | "0b05:17d2" | "2357:0101" | "2604:0012")
|
||||||
|
driver=88XXau
|
||||||
|
;;
|
||||||
|
|
||||||
|
"0bda:a81a")
|
||||||
|
driver=8812eu
|
||||||
|
;;
|
||||||
|
|
||||||
|
"0bda:f72b" | "0bda:b733")
|
||||||
|
driver=8733bu
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$driver" ]; then
|
||||||
|
echo_log "Wireless module not detected!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo_log "Detected driver: $driver"
|
||||||
|
[ -e /sys/class/net/"$wfb_dev" ] && return
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
if [ "$driver" != "88XXau" ]; then
|
||||||
|
opt1="rtw_tx_pwr_by_rate=0"
|
||||||
|
opt2="rtw_tx_pwr_lmt_enable=0"
|
||||||
|
fi
|
||||||
|
|
||||||
|
modprobe "$driver" "$opt1" "$opt2"
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
if ! ifconfig "$wfb_dev" up; then
|
||||||
|
echo_log "Wireless driver not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_mlink() {
|
||||||
|
ifconfig "$wfb_dev" mtu "$mlink"
|
||||||
|
|
||||||
|
nalu=$((mlink - 100))
|
||||||
|
if [ "$(cli -g .outgoing.naluSize)" != "$nalu" ]; then
|
||||||
|
cli -s .outgoing.naluSize "$nalu"
|
||||||
|
killall -1 majestic
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
load_interface() {
|
||||||
|
iw "$wfb_dev" set monitor none
|
||||||
|
|
||||||
|
[ "$width" = "40" ] && wfb_width=HT40+ || wfb_width=HT20
|
||||||
|
iw "$wfb_dev" set channel "$channel" "$wfb_width"
|
||||||
|
iw reg set 00
|
||||||
|
|
||||||
|
[ "$driver" = "88XXau" ] && wfb_power=$((txpower * -100)) || wfb_power=$((txpower * 3150 / 100))
|
||||||
|
iw "$wfb_dev" set txpower fixed "$wfb_power"
|
||||||
|
}
|
||||||
|
|
||||||
|
load_wfb() {
|
||||||
|
wfb_rx -K "$wfb_key" -i "$link_id" -p "$1" -u "$3" "$wfb_dev" &> /dev/null &
|
||||||
|
wfb_tx -K "$wfb_key" -M "$tun_index" -B "$width" -k "$fec_k" -n "$fec_n" \
|
||||||
|
-S "$stbc" -L "$ldpc" -i "$link_id" -p "$2" -u "$4" "$wfb_dev" &> /dev/null &
|
||||||
|
}
|
||||||
|
|
||||||
|
start_broadcast() {
|
||||||
|
echo_log "Starting wfb_tx"
|
||||||
|
wfb_tx -K "$wfb_key" -M "$mcs_index" -B "$width" -k "$fec_k" -n "$fec_n" -U rtp_local \
|
||||||
|
-S "$stbc" -L "$ldpc" -i "$link_id" -C 8000 "$wfb_dev" &> /dev/null &
|
||||||
|
}
|
||||||
|
|
||||||
|
start_tunnel() {
|
||||||
|
echo_log "Starting wfb_tun"
|
||||||
|
load_wfb 160 32 5800 5801
|
||||||
|
wfb_tun -a 10.5.0.10/24 > /dev/null &
|
||||||
|
}
|
||||||
|
|
||||||
|
start_telemetry() {
|
||||||
|
chipset=$(ipcinfo -c)
|
||||||
|
[ "$chipset" = "ssc33x" ] && devmem 0x1F207890 16 0x8
|
||||||
|
|
||||||
|
port_rx=14550
|
||||||
|
port_tx=14551
|
||||||
|
|
||||||
|
echo_log "Starting $router"
|
||||||
|
load_wfb 144 16 "$port_rx" "$port_tx"
|
||||||
|
|
||||||
|
if [ "$router" = "mavfwd" ]; then
|
||||||
|
mavfwd -b 115200 -c 8 -p 100 -a 15 -t -m /dev/"$serial" \
|
||||||
|
-o 127.0.0.1:"$port_tx" -i 127.0.0.1:"$port_rx" > /dev/null &
|
||||||
|
else
|
||||||
|
if [ "$router" = "msposd" ]; then
|
||||||
|
size=$(curl -s localhost/api/v1/config.json | jsonfilter -qe "@.video0.size")
|
||||||
|
fi
|
||||||
|
if ! pidof msposd >/dev/null; then
|
||||||
|
msposd -b 115200 -c 8 -c 6 -p 500 -w 1000 --mspvtx -r "$osd_fps" -m /dev/"$serial" \
|
||||||
|
-o 127.0.0.1:"$port_tx" -z "$size" > /dev/null &
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
video_settings() {
|
||||||
|
sensor=$(ipcinfo -s)
|
||||||
|
cli -s .isp.sensorConfig /etc/sensors/"$sensor"_infinity6e.bin
|
||||||
|
cli -s .isp.exposure 5
|
||||||
|
cli -s .video0.fps 60
|
||||||
|
cli -s .video0.size 1280x720
|
||||||
|
cli -s .video0.bitrate 4096
|
||||||
|
cli -s .video0.codec h264
|
||||||
|
cli -s .video0.rcMode cbr
|
||||||
|
cli -s .video0.gopSize 0.2
|
||||||
|
cli -s .outgoing.enabled true
|
||||||
|
cli -s .outgoing.wfb true
|
||||||
|
cli -s .fpv.enabled true
|
||||||
|
cli -s .fpv.noiseLevel 1
|
||||||
|
cli -s .records.split 1
|
||||||
|
cli -s .records.notime true
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
load_config
|
||||||
|
load_modules
|
||||||
|
load_mlink
|
||||||
|
load_interface
|
||||||
|
|
||||||
|
if [ ! -e /etc/system.ok ]; then
|
||||||
|
video_settings
|
||||||
|
touch /etc/system.ok
|
||||||
|
# killall -1 majestic
|
||||||
|
reboot
|
||||||
|
fi
|
||||||
|
|
||||||
|
stop
|
||||||
|
start_broadcast
|
||||||
|
start_tunnel
|
||||||
|
start_telemetry
|
||||||
|
wifilink 20 &
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
for process in wfb_rx wfb_tx wfb_tun mavfwd; do
|
||||||
|
if [ -n "$(pidof $process)" ]; then
|
||||||
|
echo_log "Stopping $process"
|
||||||
|
killall -q "$process"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start|stop)
|
||||||
|
$1
|
||||||
|
;;
|
||||||
|
|
||||||
|
reset)
|
||||||
|
cp -f /rom"$wfb_cfg" "$wfb_cfg"
|
||||||
|
cp -f /rom/etc/majestic.yaml /etc/majestic.yaml
|
||||||
|
video_settings
|
||||||
|
;;
|
||||||
|
|
||||||
|
cli)
|
||||||
|
shift
|
||||||
|
yaml-cli -i "$wfb_cfg" "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|reset|cli}"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Set custom upgrade url
|
# Set the reproducible Piksar HiLink firmware release channel.
|
||||||
fw_setenv upgrade 'https://github.com/OpenIPC/builder/releases/download/latest/ssc338q_fpv_openipc-urllc-aio-nor.tgz'
|
fw_setenv upgrade 'https://git.piksar.eu/piotr/openipc-builder/releases/download/latest/ssc338q_fpv_openipc-urllc-aio-nor.tgz'
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -14,3 +14,8 @@
|
|||||||
/lib/modules/4.9.84/sigmastar/sensor_os04c10_mipi.ko
|
/lib/modules/4.9.84/sigmastar/sensor_os04c10_mipi.ko
|
||||||
/lib/modules/4.9.84/sigmastar/sensor_sc501ai_mipi.ko
|
/lib/modules/4.9.84/sigmastar/sensor_sc501ai_mipi.ko
|
||||||
/lib/modules/4.9.84/sigmastar/sensor_sc8235_mipi.ko
|
/lib/modules/4.9.84/sigmastar/sensor_sc8235_mipi.ko
|
||||||
|
#
|
||||||
|
# HiLink's radio is USB 0bda:a81a and loads 8812eu. The legacy 88XXau
|
||||||
|
# module targets other adapters and is 1.4 MiB, which exceeds the 8 MiB
|
||||||
|
# rootfs budget without serving this fixed hardware profile.
|
||||||
|
/lib/modules/4.9.84/extra/88XXau.ko
|
||||||
|
|||||||
@@ -0,0 +1,455 @@
|
|||||||
|
diff --git a/osd.c b/osd.c
|
||||||
|
index a8b756e..7e5ca2a 100644
|
||||||
|
--- a/osd.c
|
||||||
|
+++ b/osd.c
|
||||||
|
@@ -959,48 +959,37 @@ static void rx_msp_callback(msp_msg_t *msp_message) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- case MSP_GET_VTX_CONFIG: {
|
||||||
|
- if (vtxInitDone) {
|
||||||
|
- mspVtxConfigStruct *in_mspVtxConfigStruct = (mspVtxConfigStruct *)msp_message->payload;
|
||||||
|
- uint16_t frequency =
|
||||||
|
- (in_mspVtxConfigStruct->freqMSB << 8) | in_mspVtxConfigStruct->freqLSB;
|
||||||
|
+ case MSP_SET_VTX_CONFIG:
|
||||||
|
+ // FC-side desired settings are read-only for this VTX. The next
|
||||||
|
+ // MSP_VTX_CONFIG reply will re-advertise the actual WFB runtime.
|
||||||
|
+ break;
|
||||||
|
|
||||||
|
- double current_frequency =
|
||||||
|
- read_current_freq_from_interface(read_setting("/etc/wfb.conf", "wlan"));
|
||||||
|
+ case MSP_GET_VTX_CONFIG: {
|
||||||
|
+ if (msp_message->size < 15) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (verbose)
|
||||||
|
- printf("mspVTX Band: %i, Channel: %i, wanted Frequency: %u, set "
|
||||||
|
- "Frequency: %.0f\n",
|
||||||
|
- in_mspVtxConfigStruct->band, in_mspVtxConfigStruct->channel, frequency,
|
||||||
|
- current_frequency);
|
||||||
|
-
|
||||||
|
- if (frequency != (uint16_t)current_frequency) {
|
||||||
|
- int channel = 0;
|
||||||
|
- for (int i = 0; i < MAX_ENTRIES; i++) {
|
||||||
|
- if (fc_list[i].frequency == frequency)
|
||||||
|
- channel = fc_list[i].channel;
|
||||||
|
- }
|
||||||
|
- if (channel > 0) {
|
||||||
|
- if (verbose)
|
||||||
|
- printf("mspVTX executing channel change to channel "
|
||||||
|
- "%d\n",
|
||||||
|
- channel);
|
||||||
|
-
|
||||||
|
- set_frequency(read_setting("/etc/wfb.conf", "wlan"), channel);
|
||||||
|
-
|
||||||
|
- // store new channel to wfb.conf
|
||||||
|
- char cha_str[32];
|
||||||
|
- sprintf(cha_str, "%i", channel);
|
||||||
|
- write_setting("/etc/wfb.conf", "channel", cha_str);
|
||||||
|
- } else {
|
||||||
|
- printf("Never change to channel 0, we should not reach "
|
||||||
|
- "here, check "
|
||||||
|
- "vtx table in your fc\n");
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ mspVtxConfigStruct *fc_vtx = (mspVtxConfigStruct *)msp_message->payload;
|
||||||
|
+ bool table_ready = fc_vtx->vtxTableAvailable &&
|
||||||
|
+ fc_vtx->bands == BAND_COUNT &&
|
||||||
|
+ fc_vtx->channels == CHANNEL_COUNT &&
|
||||||
|
+ fc_vtx->powerLevels == NUM_POWER_LEVELS;
|
||||||
|
+
|
||||||
|
+ // This is an actual FC reply to our periodic MSP_VTX_CONFIG request.
|
||||||
|
+ // Keep publishing the true local WFB configuration. If the FC reset or
|
||||||
|
+ // discarded its table, rebuild it here instead of depending on boot order.
|
||||||
|
+ if (table_ready) {
|
||||||
|
+ msp_send_vtx_runtime_config(serial_fd);
|
||||||
|
} else {
|
||||||
|
- if (verbose)
|
||||||
|
- printf("vtxInitDone not finished, should never happen\n");
|
||||||
|
+ msp_set_vtx_config(serial_fd);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (verbose) {
|
||||||
|
+ uint16_t fc_frequency =
|
||||||
|
+ (fc_vtx->freqMSB << 8) | fc_vtx->freqLSB;
|
||||||
|
+ printf("mspVTX: FC %u MHz, table %u/%u/%u; local WFB %d MHz\n",
|
||||||
|
+ fc_frequency, fc_vtx->bands, fc_vtx->channels, fc_vtx->powerLevels,
|
||||||
|
+ read_wfb_frequency());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
diff --git a/osd/msp/msp.c b/osd/msp/msp.c
|
||||||
|
index b1a538c..d834780 100644
|
||||||
|
--- a/osd/msp/msp.c
|
||||||
|
+++ b/osd/msp/msp.c
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
+#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern bool verbose;
|
||||||
|
@@ -33,12 +34,11 @@ uint16_t channelFreqTable[FREQ_TABLE_SIZE] = {
|
||||||
|
5925 // WLAN CHANNEL: 132, 140, 144, 153, 161, 169, 177, 185
|
||||||
|
};
|
||||||
|
|
||||||
|
-uint8_t saPowerLevelsLut[NUM_POWER_LEVELS] = {20, 25, 30, 35, 45, 50, 55, 58};
|
||||||
|
+uint8_t saPowerLevelsLut[NUM_POWER_LEVELS] = {0, 10, 25, 40, 55, 70, 85, 100};
|
||||||
|
|
||||||
|
-uint8_t saPowerLevelsLabel[NUM_POWER_LEVELS * POWER_LEVEL_LABEL_LENGTH] = {'2', '0', ' ', '2', '5',
|
||||||
|
- ' ', '3', '0', ' ', '3', '5', ' ', '4', '5', ' ', '5', '0', ' ', '5', '5', ' ', '5', '8', ' '};
|
||||||
|
-
|
||||||
|
-int frequency = 0;
|
||||||
|
+uint8_t saPowerLevelsLabel[NUM_POWER_LEVELS * POWER_LEVEL_LABEL_LENGTH] = {
|
||||||
|
+ '0', ' ', ' ', '1', '0', ' ', '2', '5', ' ', '4', '0', ' ',
|
||||||
|
+ '5', '5', ' ', '7', '0', ' ', '8', '5', ' ', '1', '0', '0'};
|
||||||
|
|
||||||
|
uint16_t msp_data_from_msg(uint8_t message_buffer[], msp_msg_t *msg) {
|
||||||
|
// return size
|
||||||
|
@@ -46,50 +46,103 @@ uint16_t msp_data_from_msg(uint8_t message_buffer[], msp_msg_t *msg) {
|
||||||
|
return msg->size + 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
-void wipeVtxTable(int serial_fd, int band, int channel) {
|
||||||
|
-
|
||||||
|
- // lets first wipe all
|
||||||
|
- uint8_t payload[15];
|
||||||
|
- payload[0] = 0; // idx LSB
|
||||||
|
- payload[1] = 0; // idx MSB
|
||||||
|
- payload[2] = 0; // power
|
||||||
|
- payload[3] = 0; // pitmode
|
||||||
|
- payload[4] = 0; // lowPowerDisarm
|
||||||
|
- payload[5] = 0; // pitModeFreq LSB
|
||||||
|
- payload[6] = 0; // pitModeFreq MSB
|
||||||
|
- payload[7] = 0; // newBand - WLAN Channel
|
||||||
|
- payload[8] = 0; // newChannel - 161
|
||||||
|
- payload[9] = 0; // newFreq LSB
|
||||||
|
- payload[10] = 0; // newFreq MSB
|
||||||
|
- payload[11] = 0; // newBandCount
|
||||||
|
- payload[12] = 0; // newChannelCount
|
||||||
|
- payload[13] = 0; // newPowerCount
|
||||||
|
- payload[14] = 1; // vtxtable should be cleared
|
||||||
|
+static void write_msp_packet(int serial_fd, const uint8_t *buffer, size_t size) {
|
||||||
|
+ ssize_t written = write(serial_fd, buffer, size);
|
||||||
|
+ if (written != (ssize_t)size) {
|
||||||
|
+ fprintf(stderr, "mspVTX: short serial write (%zd/%zu)\n", written, size);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- uint8_t buffer[256];
|
||||||
|
+ // Betaflight's MSP parser is also carrying DisplayPort traffic on this
|
||||||
|
+ // UART. Drain and pace table frames so a cold boot cannot overrun its
|
||||||
|
+ // receive path before it has processed the preceding configuration frame.
|
||||||
|
+ tcdrain(serial_fd);
|
||||||
|
+ usleep(20 * 1000);
|
||||||
|
+}
|
||||||
|
|
||||||
|
- construct_msp_command(buffer, MSP_SET_VTX_CONFIG, payload, sizeof(payload), MSP_OUTBOUND);
|
||||||
|
- write(serial_fd, &buffer, sizeof(buffer));
|
||||||
|
-
|
||||||
|
- // now prepare the table
|
||||||
|
- payload[0] = 0; // idx LSB
|
||||||
|
- payload[1] = 0; // idx MSB
|
||||||
|
- payload[2] = 7; // 55, default wfb-ng
|
||||||
|
- payload[3] = 0; // pitmode
|
||||||
|
- payload[4] = 0; // lowPowerDisarm
|
||||||
|
- payload[5] = 0; // pitModeFreq LSB
|
||||||
|
- payload[6] = 0; // pitModeFreq MSB
|
||||||
|
- payload[7] = band; // newBand - WLAN Channel
|
||||||
|
- payload[8] = channel; // newChannel - 161
|
||||||
|
- payload[9] = 0; // newFreq LSB
|
||||||
|
- payload[10] = 0; // newFreq MSB
|
||||||
|
- payload[11] = BAND_COUNT; // newBandCount
|
||||||
|
- payload[12] = CHANNEL_COUNT; // newChannelCount
|
||||||
|
- payload[13] = NUM_POWER_LEVELS; // newPowerCount
|
||||||
|
- payload[14] = 0; // vtxtable should be cleared
|
||||||
|
+static bool wfb_runtime_active(void) {
|
||||||
|
+ return system("pidof wfb_tx wfb_rx wfb_tun wifilink >/dev/null 2>&1") == 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static uint8_t power_index_for_txpower(int txpower) {
|
||||||
|
+ uint8_t best = 0;
|
||||||
|
+ int smallest_delta = 101;
|
||||||
|
+
|
||||||
|
+ for (uint8_t i = 0; i < NUM_POWER_LEVELS; i++) {
|
||||||
|
+ int delta = abs(txpower - saPowerLevelsLut[i]);
|
||||||
|
+ if (delta < smallest_delta) {
|
||||||
|
+ best = i;
|
||||||
|
+ smallest_delta = delta;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return best + 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int get_wfb_vtx_config(int *band, int *channel, int *configured_frequency,
|
||||||
|
+ uint8_t *power_index, bool *pit_mode) {
|
||||||
|
+ *configured_frequency = read_wfb_frequency();
|
||||||
|
+ if (*configured_frequency < 0) {
|
||||||
|
+ fprintf(stderr, "mspVTX: cannot read /etc/wfb.yaml channel\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ int txpower = read_wfb_txpower();
|
||||||
|
+ if (txpower < 0) {
|
||||||
|
+ fprintf(stderr, "mspVTX: cannot read /etc/wfb.yaml txpower\n");
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+ bool active = wfb_runtime_active();
|
||||||
|
+ *pit_mode = !active;
|
||||||
|
+ if (!active) {
|
||||||
|
+ txpower = 0;
|
||||||
|
+ }
|
||||||
|
+ *power_index = power_index_for_txpower(txpower);
|
||||||
|
+
|
||||||
|
+ *band = 1;
|
||||||
|
+ *channel = 1;
|
||||||
|
+ for (int index = 0; index < FREQ_TABLE_SIZE; index++) {
|
||||||
|
+ if (channelFreqTable[index] == *configured_frequency) {
|
||||||
|
+ *band = index / CHANNEL_COUNT + 1;
|
||||||
|
+ *channel = index % CHANNEL_COUNT + 1;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "mspVTX: %d MHz is absent from the VTX table\n", *configured_frequency);
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void send_vtx_config(int serial_fd, int band, int channel, int configured_frequency,
|
||||||
|
+ uint8_t power_index, bool pit_mode, bool clear_table) {
|
||||||
|
+ uint8_t payload[15] = {
|
||||||
|
+ configured_frequency & 0xFF,
|
||||||
|
+ (configured_frequency >> 8) & 0xFF,
|
||||||
|
+ power_index, // nearest configured 0..100 WFB txpower table entry
|
||||||
|
+ pit_mode, // management standby is represented as VTX pit mode
|
||||||
|
+ 0, // low power when disarmed
|
||||||
|
+ 0, 0, // pit frequency
|
||||||
|
+ band,
|
||||||
|
+ channel,
|
||||||
|
+ configured_frequency & 0xFF,
|
||||||
|
+ (configured_frequency >> 8) & 0xFF,
|
||||||
|
+ BAND_COUNT,
|
||||||
|
+ CHANNEL_COUNT,
|
||||||
|
+ NUM_POWER_LEVELS,
|
||||||
|
+ clear_table ? 1 : 0,
|
||||||
|
+ };
|
||||||
|
+ uint8_t buffer[21];
|
||||||
|
|
||||||
|
construct_msp_command(buffer, MSP_SET_VTX_CONFIG, payload, sizeof(payload), MSP_OUTBOUND);
|
||||||
|
- write(serial_fd, &buffer, sizeof(buffer));
|
||||||
|
+ write_msp_packet(serial_fd, buffer, sizeof(payload) + 6);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void wipeVtxTable(int serial_fd, int band, int channel, int configured_frequency,
|
||||||
|
+ uint8_t power_index, bool pit_mode) {
|
||||||
|
+ // First tell Betaflight to discard any stale table, then publish the
|
||||||
|
+ // configured WFB frequency and the table dimensions.
|
||||||
|
+ send_vtx_config(serial_fd, band, channel, configured_frequency, power_index, pit_mode, true);
|
||||||
|
+ send_vtx_config(serial_fd, band, channel, configured_frequency, power_index, pit_mode, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVtxTableBand(int serial_fd, uint8_t band) {
|
||||||
|
@@ -119,7 +172,7 @@ void setVtxTableBand(int serial_fd, uint8_t band) {
|
||||||
|
}
|
||||||
|
|
||||||
|
construct_msp_command(buffer, MSP_SET_VTXTABLE_BAND, payload2, sizeof(payload2), MSP_OUTBOUND);
|
||||||
|
- write(serial_fd, &buffer, sizeof(buffer));
|
||||||
|
+ write_msp_packet(serial_fd, buffer, sizeof(payload2) + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVtxTablePowerLevel(int serial_fd, uint8_t idx) {
|
||||||
|
@@ -139,31 +192,26 @@ void setVtxTablePowerLevel(int serial_fd, uint8_t idx) {
|
||||||
|
|
||||||
|
construct_msp_command(
|
||||||
|
buffer, MSP_SET_VTXTABLE_POWERLEVEL, payload2, sizeof(payload2), MSP_OUTBOUND);
|
||||||
|
- write(serial_fd, &buffer, sizeof(buffer));
|
||||||
|
+ write_msp_packet(serial_fd, buffer, sizeof(payload2) + 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void msp_set_vtx_config(int serial_fd) {
|
||||||
|
+ int band;
|
||||||
|
+ int channel;
|
||||||
|
+ int configured_frequency;
|
||||||
|
+ uint8_t power_index;
|
||||||
|
+ bool pit_mode;
|
||||||
|
+
|
||||||
|
+ if (get_wfb_vtx_config(&band, &channel, &configured_frequency, &power_index, &pit_mode) != 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- // mspVTX read current frequency setting
|
||||||
|
- query_interface_for_available_frequencies();
|
||||||
|
-
|
||||||
|
- frequency = read_current_freq_from_interface(read_setting("/etc/wfb.conf", "wlan"));
|
||||||
|
-
|
||||||
|
- int band = 6;
|
||||||
|
- int channel = 3;
|
||||||
|
- for (int index = 0; index < FREQ_TABLE_SIZE; index++) {
|
||||||
|
- if (channelFreqTable[index] == frequency) {
|
||||||
|
- // Determine band and channel using division and modulo
|
||||||
|
- band = index / 8 + 1; // Which band (integer division)
|
||||||
|
- channel = (index % 8) + 1; // Channel within the band (modulo)
|
||||||
|
-
|
||||||
|
- if (verbose)
|
||||||
|
- printf("Frequency %d found in band %i, channel %d\n", frequency, band, channel);
|
||||||
|
- break; // Exit after finding the frequency
|
||||||
|
- }
|
||||||
|
+ if (verbose) {
|
||||||
|
+ printf("mspVTX table: %d MHz, band %d, channel %d\n",
|
||||||
|
+ configured_frequency, band, channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
- wipeVtxTable(serial_fd, band, channel);
|
||||||
|
+ wipeVtxTable(serial_fd, band, channel, configured_frequency, power_index, pit_mode);
|
||||||
|
|
||||||
|
for (int i = 1; i <= BAND_COUNT; i++) {
|
||||||
|
setVtxTableBand(serial_fd, i);
|
||||||
|
@@ -174,6 +222,20 @@ void msp_set_vtx_config(int serial_fd) {
|
||||||
|
vtxInitDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void msp_send_vtx_runtime_config(int serial_fd) {
|
||||||
|
+ int band;
|
||||||
|
+ int channel;
|
||||||
|
+ int configured_frequency;
|
||||||
|
+ uint8_t power_index;
|
||||||
|
+ bool pit_mode;
|
||||||
|
+
|
||||||
|
+ if (get_wfb_vtx_config(&band, &channel, &configured_frequency, &power_index, &pit_mode) != 0) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ send_vtx_config(serial_fd, band, channel, configured_frequency, power_index, pit_mode, false);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
msp_error_e construct_msp_command(uint8_t message_buffer[], uint8_t command, uint8_t payload[],
|
||||||
|
uint8_t size, msp_direction_e direction) {
|
||||||
|
uint8_t checksum;
|
||||||
|
diff --git a/osd/msp/msp.h b/osd/msp/msp.h
|
||||||
|
index 3e60a31..1fe1c28 100644
|
||||||
|
--- a/osd/msp/msp.h
|
||||||
|
+++ b/osd/msp/msp.h
|
||||||
|
@@ -40,10 +40,10 @@
|
||||||
|
// wfb-ng list
|
||||||
|
|
||||||
|
#define CHANNEL_COUNT 8
|
||||||
|
-#define BAND_COUNT 8
|
||||||
|
+#define BAND_COUNT 7
|
||||||
|
#define IS_FACTORY_BAND 0
|
||||||
|
-#define FREQ_TABLE_SIZE 64
|
||||||
|
-#define FREQ_LABEL_SIZE 64
|
||||||
|
+#define FREQ_TABLE_SIZE 56
|
||||||
|
+#define FREQ_LABEL_SIZE 56
|
||||||
|
|
||||||
|
#define MSP_REBOOT 68 // in message reboot settings
|
||||||
|
|
||||||
|
@@ -83,3 +83,5 @@ msp_error_e construct_msp_command(uint8_t message_buffer[], uint8_t command, uin
|
||||||
|
uint8_t size, msp_direction_e direction);
|
||||||
|
msp_error_e msp_process_data(msp_state_t *msp_state, uint8_t dat);
|
||||||
|
void msp_set_vtx_config(int serial_fd);
|
||||||
|
+// Advertise the actual local WFB configuration without resetting the FC table.
|
||||||
|
+void msp_send_vtx_runtime_config(int serial_fd);
|
||||||
|
diff --git a/osd/util/interface.c b/osd/util/interface.c
|
||||||
|
index 089fdc2..a783431 100644
|
||||||
|
--- a/osd/util/interface.c
|
||||||
|
+++ b/osd/util/interface.c
|
||||||
|
@@ -153,3 +153,81 @@ void set_frequency(char *interface, int channel) {
|
||||||
|
printf("Failed to set channel on %s\n", interface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int read_wfb_frequency(void) {
|
||||||
|
+ FILE *fp = fopen("/etc/wfb.yaml", "r");
|
||||||
|
+ char buffer[256];
|
||||||
|
+ int in_wireless = 0;
|
||||||
|
+ int channel = -1;
|
||||||
|
+
|
||||||
|
+ if (fp == NULL) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
||||||
|
+ if (strncmp(buffer, "wireless:", 9) == 0) {
|
||||||
|
+ in_wireless = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (in_wireless && buffer[0] != ' ' && buffer[0] != ' ' &&
|
||||||
|
+ buffer[0] != '\n') {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (in_wireless && sscanf(buffer, " channel: %d", &channel) == 1) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fclose(fp);
|
||||||
|
+
|
||||||
|
+ if (channel >= 1 && channel <= 14) {
|
||||||
|
+ return 2407 + channel * 5;
|
||||||
|
+ }
|
||||||
|
+ if (channel > 14 && channel <= 196) {
|
||||||
|
+ return 5000 + channel * 5;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int read_wfb_txpower(void) {
|
||||||
|
+ FILE *fp = fopen("/run/wfb-power", "r");
|
||||||
|
+ int txpower = -1;
|
||||||
|
+
|
||||||
|
+ // CH6 knob state wins while WFB is active; it is intentionally kept in
|
||||||
|
+ // tmpfs so power changes do not wear the overlay flash.
|
||||||
|
+ if (fp != NULL) {
|
||||||
|
+ if (fscanf(fp, "%d", &txpower) == 1 && txpower >= 0 && txpower <= 100) {
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return txpower;
|
||||||
|
+ }
|
||||||
|
+ fclose(fp);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fp = fopen("/etc/wfb.yaml", "r");
|
||||||
|
+ char buffer[256];
|
||||||
|
+ int in_wireless = 0;
|
||||||
|
+
|
||||||
|
+ if (fp == NULL) {
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while (fgets(buffer, sizeof(buffer), fp) != NULL) {
|
||||||
|
+ if (strncmp(buffer, "wireless:", 9) == 0) {
|
||||||
|
+ in_wireless = 1;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ if (in_wireless && buffer[0] != ' ' && buffer[0] != ' ' &&
|
||||||
|
+ buffer[0] != '\n') {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (in_wireless && sscanf(buffer, " txpower: %d", &txpower) == 1) {
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ fclose(fp);
|
||||||
|
+ return txpower >= 0 && txpower <= 100 ? txpower : -1;
|
||||||
|
+}
|
||||||
|
diff --git a/osd/util/interface.h b/osd/util/interface.h
|
||||||
|
index 983971d..854c9e7 100644
|
||||||
|
--- a/osd/util/interface.h
|
||||||
|
+++ b/osd/util/interface.h
|
||||||
|
@@ -22,3 +22,10 @@ int query_interface_for_available_frequencies();
|
||||||
|
void set_frequency(char *interface, int channel);
|
||||||
|
|
||||||
|
int read_current_freq_from_interface(char *interface);
|
||||||
|
+
|
||||||
|
+// Read WiFiLink/OpenIPC WFB channel from the YAML runtime configuration.
|
||||||
|
+// Returns the centre frequency in MHz, or -1 when no valid channel is present.
|
||||||
|
+int read_wfb_frequency(void);
|
||||||
|
+
|
||||||
|
+// Read the configured WFB txpower scalar (0..100 convention used by this profile).
|
||||||
|
+int read_wfb_txpower(void);
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# msposd — pinned upstream plus HiLink WiFiLink mspVTX compatibility patch
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
MSPOSD_SITE = $(call github,openipc,msposd,$(MSPOSD_VERSION))
|
||||||
|
MSPOSD_VERSION = ad0175ce01c4e09b3eb4223fd683735f9df22715
|
||||||
|
MSPOSD_DEPENDENCIES = libevent-openipc
|
||||||
|
|
||||||
|
ifeq ($(OPENIPC_SOC_FAMILY),gk7205v200)
|
||||||
|
MSPOSD_FAMILY = goke
|
||||||
|
MSPOSD_OSDRV = $(GOKE_OSDRV_GK7205V200_PKGDIR)
|
||||||
|
else ifeq ($(OPENIPC_SOC_FAMILY),hi3516ev200)
|
||||||
|
MSPOSD_FAMILY = hisi
|
||||||
|
MSPOSD_OSDRV = $(HISILICON_OSDRV_HI3516EV200_PKGDIR)
|
||||||
|
else ifeq ($(OPENIPC_SOC_FAMILY),infinity6b0)
|
||||||
|
MSPOSD_FAMILY = star6b0
|
||||||
|
MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6B0_PKGDIR)
|
||||||
|
else ifeq ($(OPENIPC_SOC_FAMILY),infinity6c)
|
||||||
|
MSPOSD_FAMILY = star6c
|
||||||
|
MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6C_PKGDIR)
|
||||||
|
else
|
||||||
|
MSPOSD_FAMILY = star6e
|
||||||
|
MSPOSD_OSDRV = $(SIGMASTAR_OSDRV_INFINITY6E_PKGDIR)
|
||||||
|
endif
|
||||||
|
|
||||||
|
define MSPOSD_BUILD_CMDS
|
||||||
|
$(MAKE) CC=$(TARGET_CC) TOOLCHAIN=$(STAGING_DIR) DRV=$(MSPOSD_OSDRV)/files/lib $(MSPOSD_FAMILY) OUTPUT=$(@D)/msposd -C $(@D)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define MSPOSD_INSTALL_TARGET_CMDS
|
||||||
|
$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/bin
|
||||||
|
$(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(@D)/msposd
|
||||||
|
$(INSTALL) -m 755 -t $(TARGET_DIR)/usr/bin $(@D)/safeboot.sh
|
||||||
|
|
||||||
|
$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/share/fonts
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_inav.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_inav_hd.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_btfl.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_btfl_hd.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_ardu.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/share/fonts $(@D)/fonts/font_ardu_hd.png
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/etc $(@D)/vtxmenu.ini
|
||||||
|
endef
|
||||||
|
|
||||||
|
define MSPOSD_INSTALL_LIBRARIES
|
||||||
|
$(INSTALL) -m 755 -d $(TARGET_DIR)/usr/lib
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libcam_os_wrapper.so
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libmi_rgn.so
|
||||||
|
$(INSTALL) -m 644 -t $(TARGET_DIR)/usr/lib $(MSPOSD_OSDRV)/files/lib/libmi_sys.so
|
||||||
|
endef
|
||||||
|
|
||||||
|
ifeq ($(OPENIPC_SOC_VENDOR),sigmastar)
|
||||||
|
MSPOSD_POST_INSTALL_TARGET_HOOKS += MSPOSD_INSTALL_LIBRARIES
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(eval $(generic-package))
|
||||||
Reference in New Issue
Block a user