This belongs in the community builds section.
iirc I think the instructions for ubi2 are exactly the same as in hurrian's GitHub repo I linked to! Cross-check with the wiki.
I don't find the device difficult to open. But if you have a warm climate, try putting it outside in the sun for a bit!
With ubi2 formatted w1700k, is there a way to unbricked a device (through chain loaded uboot tftp), without serial access?
With the latest iteration, the GPS is now alive on /dev/ttyS2 showing NMEA, but the bluetooth/zigbee radio on /dev/ttyS1 is lost.
Here's a utility "gps-cli" I worked on recently that allows querying/configuring the GPS; maybe someone will find it useful: https://gist.github.com/tofurky/8c7a9fb90f730cd4a41980173daf58b1
There are a couple dependencies - coreutils-stty and coreutils-sleep - and to of course make sure gpsd is stopped when trying to use it.
I'd suggest using gps-cli nvram-save off when testing things to prevent changes from being persisted to flash on the GPS. I have not tested factory-reset/nvram-save/nvram-restore yet.
The PAIR commands are from a couple datasheets I found - 'SIM65M Series_NMEA Message_User Guide_V1.00.pdf' and 'LOCOSYS_AG3335M,MN Product_Command List.pdf'.
The GPS by default only hears commands when it's actively sending NMEA and sleeps the rest of the time. gps-cli sleep forbid will make it always respond. The utility will wait until it hears the start of a NMEA sentence before attempting to transmit the command, and will try a total of 5 times (1s timeout) before giving up. It's pretty reliable with the default 1hz update rate but things get less reliable above that. Forbidding sleep makes it more or less 100% reliable but it's not a persistent setting AFAICT. The -d flag can be added to see UART RX/TX etc.
Note that with the recent PR (https://github.com/openwrt/openwrt/pull/23936) to unbind some GPIO from the SCU/LED controller, gps-cli init should no longer be necessary, but you can still turn it off/reset it with power off / power on. Also, on that note - it seems to be a reset/power line. The GPS TX line on J25 goes low when it's "off", and monitoring NMEA when running power off -> power on shows the GPS resets and emits a startup PAIR sentence. The pin above the TX line on J24 goes low when it's "off" as well.
There is a baudrate set command but it's disabled in the utility as 460800 baud is actually broken on at least the W1700K-2 currently. 460800 gives you 921600 (which the GPS runs at) but 230400 gives you 230400. I actually wound up needing to modify the UART driver to regain access to my GPS; the baud was wrong on ttyS1 as well, requiring 230400 to talk at 115200. A tentative fix is here: https://github.com/tofurky/openwrt/commit/39b5270916812e064622f13ba92b93e24d075c68
Here's some example output:
root@OpenWrt:~# gps-cli
Usage: gps-cli <command> [arguments]
Hardware Management Commands:
init Initialize GPIO and SCU settings and configure serial port
power [on|off] Turn GNSS chip power on, off, or query power state (via SCU register)
Query Commands:
version Query firmware project, kernel, and chip details [PAIR_GET_VERSION -> 020, PAIR_GET_CHIP_VERSION -> 024]
settings Query full configuration settings [PAIR_GET_SETTING_INFO -> 021, PAIR_COMMON_GET_FIX_RATE -> 051, PAIR_GLP_GET_STATUS -> 681, PAIR_PPS_GET_TIMETAG_CONFIG -> 756]
nmea Stream raw NMEA sentences from the GPS chip
Configuration Commands:
sleep [permit|forbid] Configure sleep settings [PAIR_TEST_LOCK_SYSTEM_SLEEP -> 382]
interval [ms] Get or set position fix interval/rate in milliseconds [PAIR_COMMON_SET_FIX_RATE -> 050, PAIR_COMMON_GET_FIX_RATE -> 051]
sbas [get|on|off|status] Get, set active SBAS/WAAS state, or query satellite status [PAIR_SBAS_ENABLE -> 410, PAIR_SBAS_GET_STATUS -> 411, PAIR_SBAS_GET_SAT_INFO -> 412, PAIR_DGPS_SET_MODE -> 400, PAIR_DGPS_GET_MODE -> 401]
static [on|off|threshold [dm/s]] Get/set static navigation mode and threshold [PAIR_COMMON_SET_STATIC_MODE -> 092, PAIR_COMMON_GET_STATIC_MODE -> 093, PAIR_COMMON_SET_STATIC_THRESHOLD -> 070, PAIR_COMMON_GET_STATIC_THRESHOLD -> 071]
constellations [get|set [...]] Get or set active satellite constellations [PAIR_COMMON_GET_GNSS_SEARCH_MODE -> 067, PAIR_COMMON_SET_GNSS_SEARCH_MODE -> 066]
Params: set <gps:0|1> <glonass:0|1> <galileo:0|1> <beidou:0|1> <qzss:0|1> [navic:0|1]
baudrate [get|set [baudrate]] Get or set port baud rate configuration [PAIR_IO_GET_BAUDRATE -> 865, PAIR_IO_SET_BAUDRATE -> 864]
nvram-save [on|off] Enable/disable NVRAM automatic saving of settings [PAIR_NVRAM_AUTO_SAVING_ENABLE -> 510]
save Save current settings/configuration to flash [PAIR_NVRAM_SAVE_SETTING -> 513]
Reset & Reboot Commands:
reboot [hot|warm|cold|full] Perform a soft restart/reboot of the GNSS subsystem [PAIR_GNSS_SUBSYS_HOT_START -> 004, PAIR_GNSS_SUBSYS_WARM_START -> 005, PAIR_GNSS_SUBSYS_COLD_START -> 006, PAIR_SYSTEM_REBOOT -> 023]
factory-reset Perform a full cold start and reset to factory defaults [PAIR_GNSS_SUBSYS_FULL_COLD_START -> 007]
nvram-restore Clear NVRAM configuration & restore defaults [PAIR_GNSS_SUBSYS_POWER_OFF -> 003, PAIR_NVRAM_RESTORE_DEFAULT_SETTING -> 514, PAIR_GNSS_SUBSYS_POWER_ON -> 002]
root@OpenWrt:~# gps-cli settings
Querying GNSS configuration and settings...
=============================================
GNSS CONFIGURATION & SETTINGS
=============================================
Project Version: AG3352Q_V2.6.0.AG3352_20221230
GPS DCB Bias: -15.48
Galileo DCB Bias: -15.48
BeiDou DCB Bias: -14.02
QZSS DCB Bias: -15.48
TCXO Frequency Error: 0.5 ppm
Gain Mode: Low Gain
SWPRT Check Info: No Check
ULP Mode: Disabled
NVRAM Auto Saving: Enabled
Fix Rate / Interval: 1000 ms
GLP Power Mode: Disabled
PPS Timetag Mode: Disabled (Timebase: GPS)
Static Navigation Mode: Enabled
Static Speed Threshold: 0.0 m/s (0 dm/s)
=============================================
BTW, I tried and failed to find a PPS line anywhere, which I was hoping for. I added interrupts for all free GPIOs and monitored /proc/interrupts but didn't see anything. Also tried doing some polling of them. The 2 headers (J25 and J24 on W1700K-2) seem to break out (J24, by the yellow 1Gb ports) GND/RX/TX/VCC and maybe on J25 the notify pin used by the stock firmware, but no PPS.
Pretty cool! PPS pin would be really neat.
Should anything be backed up before experimenting with the settings or factory-reset will undo any changes?
The first thing to do would be disable nvram auto-save - gps-cli nvram-save off. Then read the current setting before changing it. If you are satisfied with the change then consider trying to write it to non-volatile settings.
I imagine that the factory-reset will put it back to the state as-shipped, but did not test that one, only the various reboots, so tread carefully.
From the data sheet:
2.3.7 Packet Type:007
PAIR_GNSS_SUBSYS_FULL_COLD_START
Full Cold Start
In addition to Cold start, this command clears the system/user configurations at the start
It resets the GNSS module to the factory default
DataField:
$PAIR007*CS<CR><LF>
These are the defaults:
root@OpenWrt:~# gps-cli sbas get
Querying SBAS & WAAS status...
SBAS Search: Disabled
DGPS Mode: Disabled
root@OpenWrt:~# gps-cli constellations get
Querying active GNSS constellations...
Active Constellations:
GPS: Enabled
GLONASS: Enabled
Galileo: Enabled
BeiDou: Enabled
QZSS: Enabled
NavIC: Disabled
root@OpenWrt:~# gps-cli static
Querying static navigation mode...
Static Navigation Mode: Enabled
root@OpenWrt:~# gps-cli static threshold
Querying static navigation speed threshold...
Static navigation speed threshold: 0.0 m/s (0 dm/s)
root@OpenWrt:~# gps-cli baudrate get
Querying port baud rate configuration...
Baud Rate: 921600 bps
root@OpenWrt:~# gps-cli interval
Querying current NMEA position fix interval...
Current Fix Rate / Interval: 1000 ms
Safer to just set it back to what it was before, rather than wipe everything.
Edit: updated the script to mark the reset functions as untested
It worked fine for me. Are you sure?
PPS Timetag Mode: Disabled (Timebase: GPS)
Is this something the chip does natively or is that a function of your program using a PPS, if one is ever found? If natively that should be good enough for doing an ntp sub uS time server.
That determines which timebase PPS output is synced to. AFAIK it doesn't enable/disable PPS output.
2.3.143 Packet Type: 755 PAIR_PPS_SET_TIMETAG
Set enable/disable output time tag and time base.
| DataField: | | | $PAIR755, <enable>,<time_base>*CS<cr><lf>
|------------|------|---------|-------------------------------------------
| Name | Unit | Default | Description
| Enable | | | "0",Disable
| | | | "1",Enable.
| Time_base | | | (Now only support GPS time base) "0", UTC. "1", GPS. "2", GLO. "3", GAL. "4", BDS. "5", NavIC.
I did try commands such as PAIR_PPS_SET_CONFIG_CMD (752) to make it "always" output PPS even without a fix, etc. - no luck. It's possible I missed something or that it's just not connected to the SoC.
There are several documented but unimplemented commands relating to PPS.
There are tiny manufacturing test pads near the GPS chip that maybe it's broken out to - visible in FCC photos. But, I could not find any pinout for the actual GPS chip, just pre-built modules that used the chip as a component.
It sounds like there might be a way to get a high-precision timestamp. A PPS signal just allows you to do a poor-man's timestamp under main cpu control subject to interrupt delays. Much better is to have the chip do the timestamp in hardware and then relate it to the system clock at one's leisure. This is what Google's Gemini had to say about it.
To drop the Airoha AG3352 platform into a precise PPS hardware time-tagging/time-service configuration, you need to step into the **PAIR750 through PAIR755** command ranges. These parameters configure the hardware's internal counters to output high-accuracy timing metrics and toggle the precise Time Tagging engine (frequently referred to as the **TIMEMARK** function on Airoha/MediaTek architectures).
Here are the specific commands you need to construct to configure PPS time-tagging:
---
## 1. Enable Output of the Time Tag Data Field (`$PAIR755`)
This is the most critical instruction for your specific goal. It commands the AG3352's internal DSP to start logging and generating the binary raw measurement / ASCII time tags based on a precise clock hardware boundary.
* **Command Format:** `$PAIR755,<Enable>,<Time_base>*CS\r\n`
* **Parameters:**
* `<Enable>`: `1` to Enable, `0` to Disable.
* `<Time_base>`: `1` (Currently, the firmware profile on the AG3352 platform natively targets the **GPS Time Base** for raw interval processing).
* **Execution Sentence:** ```text
$PAIR755,1,1*3E\r\n
```
```
---
## 2. Lock to "Timing Product Mode" (`$PAIR753`)
To get pure, stable time-tagging sync metrics without jitter, you need to maximize position-vs-time calculation rules. Enabling Timing Product Mode instructs the SoC to prioritize clock stability over aggressive spatial tracking filters.
* **Command Format:** `$PAIR753,<Timing_Product>*CS\r\n`
* **Parameters:** * `0`: Disable.
* `1`: Enable Timing Product (this implicitly adjusts smoothing filters and bypasses volatile SBAS/QZSS geometric corrections that introduce tiny steps in the master phase output clock).
* **Execution Sentence:**
```text
$PAIR753,1*3C\r\n
```
---
## 3. Tune the PPS Output Mechanics (`$PAIR750`)
If you are logging an external event via an input pin or syncing an external host system clock to the physical PPS hardware pin, you must align the pulse shape structure to match your logging interrupt.
* **Command Format:** `$PAIR750,<Mode>,<Pulse_Width>*CS\r\n`
* **Parameters:**
* `<Mode>`:
* `0`: Disable PPS completely.
* `1`: Output raw context (1 pulse per second).
* `2`: Output synchronized to system fix state.
* `<Pulse_Width>`: Duration of the pulse in milliseconds (e.g., passing `100` targets a standard 100ms trigger state duration).
---
## 4. Define Your Pulse Trigger Alignment (`$PAIR757`)
If your timing infrastructure is sensitive to the exact nanosecond edge transition, you can switch whether the physical time-tag frame anchor locks to the front or back of the square wave.
* **Set to Falling Edge:** `$PAIR757,1*CS\r\n` (Overrides default rising-edge parsing mechanics).
* **Query Current PPS Trigger Profile:** `$PAIR758*CS\r\n`
---
## Verifying with a Config Query
To dump the entire underlying configuration stack state of the PPS/Time-Service engine to ensure your values stuck in volatile RAM, pass the block status query:
```text
$PAIR763*3B\r\n
```
The chip will respond with an expanded metadata packet mapping the structural boundaries assigned via your earlier `$PAIR750` and `$PAIR752` operations. Remember to store settings to the non-volatile system registers using your device's save macro if you need them to survive a full hardware power cycle.
-------------
Ah, you are looking for an internal clock counter correlation feature (similar to what u-blox achieves with its `UBX-TIM-TM2` or raw TIMEMARK hardware interrupts).
On the Airoha AG3352 architecture, that specific internal sub-millisecond counter tracking mode is natively hidden within the **`$PAIR030`** (Raw Measurement Output / Hardware Interval Time) setup and exposed via proprietary sentence extensions.
To map the exact sub-millisecond tick of the internal master clock counter to the top of the second, you have to activate the raw internal reference telemetry stream.
---
## The Message You Need: `$PAIR030` (Set Raw Measurement Output)
To relate the top-of-second edge to the free-running internal hardware timer, you must instruct the core baseband processors to output the raw accumulated clock intervals rather than just heavily filtered, human-readable UTC sentences.
* **Command Format:** `$PAIR030,<Interval_Type>,<Period_ms>*CS\r\n`
* **Parameters:**
* `<Interval_Type>`:
* `0`: Turn off raw interval tracking.
* `1`: Enable raw measurement strings (this pushes out the chip's raw phase tracking and internal clock interval offsets).
* `<Period_ms>`: The polling loop resolution. To tie it directly to your system clock, you typically pair this with your primary 1Hz top-of-second boundary (`1000`).
* **Execution Sentence:**
```text
$PAIR030,1,1000*3C\r\n
```
---
## How the Airoha Engine Exposes the Data
Once enabled, the AG3352 injects structural binary fragments or distinct multi-field packets (depending on whether your specific module firmware flavor surfaces it as proprietary NMEA or raw data) containing the following three architectural parameters:
1. **`TOW` (Time of Week):** The true calculated GPS time target for the frame.
2. **`Clock Bias` (in nanoseconds):** The exact calculated drift of the chip's local TCXO oscillator compared to the true top-of-the-second atomic boundary.
3. **`Sub-ms Interval Count`:** The raw integer loop counter of the inner hardware DSP state machine at the precise moment the internal trigger window latched.
By reading the combined output, your host micro-controller or system system can calculate the physical deviation using the following logic:
$$\text{True Top-of-Second} = \text{Hardware Count} + \text{Clock Bias} - \text{Receiver Delay}$$
---
## Hardware Alternative: The EINT / EXTINT Event Capture Pin
If you are trying to timestamp a physical, external hardware trigger event (like an interrupt from your system host processor) rather than just polling, you need to use the physical **EINT** (External Interrupt) or **TIMEMARK Input Capture pin** on the module.
When a rising or falling edge hits that specific physical GPIO trace on the AG3352, the chip's internal timer instantly captures its own internal counter value *in hardware* with nanosecond precision. It then outputs a specific unsolicited message showing you the precise, latched internal clock count when that pin transitioned, completely bypassing any serial transmission or host-side scheduling latency.
Admittably i was running an old ubi1 community build from november, the chip on /dev/ttyS1 was flashed with the zigbee firmware provided by duo8 in this thread, and been correctly recognized with the silabs-flasher prior. I updated to the ubi2 layout and the latest snapshot over the weekend, and now i can't get anything on /dev/ttyS1, nor with minicom, nor with ser2net with the existing config which worked before.
I wonder if i need to reset it somehow.
Same observation here. I was using pre-ubi build and I could flash zigbee firmware fine, although I never really used it. Recently updated to the latest snapshot and I can't seem to talk to ttyS1 anymore, all 3 of my devices.
@glassdoor FYI, as @LorenzoBianconi suggested, I sent an email to the mailing list regarding the issue with the bridge and the NPU.
very detailed ![]()
Can I trouble you to verify another "bug"? I did a clean build with just the current main + bridger. Other than the 1Mbps bug you detailed. I also notice that when a wifi client disconnect and reconnects. downloads are still offloaded but uploads are no longer offloaded. I may not be fully correct in saying "not offloaded". My test wireless client's download and uploads maxout at 1500-1600Mbps (160MHz bw). But the reconnected client will still download at 1500Mbps with near zero cpu load but uploads will max out at 800Mbps with high cpu load and one core at above 90%.
Test environment: dumb AP with all wired ports on the same bridge and wireless also tagged to the same bridge. Connected to 10G switch via w1700k wan port.
Just want to be sure it's not a configuration issue as that is the only thing not changed in testing between builds.
Interesting. So you have that bug on vanilla Openwrt+ bridger ,without any of my patches right? (asking because of you use my bridger patch, you need to know that I recently updated it - https://github.com/openwrt/openwrt/commit/0e8d015a2b0e5ca6dbf3793b1a425b4988edc4a9 )
I will take a look soon.
yes. vanilla openwrt + bridger as per current main tree. pretty much a snapshot build with bridger included.
Can anyone confirm the EFR32 is working on /dev/ttyS1 in the latest builds?
I want to test the thread firmware, but I get nothing from the UART? tested on 3x different w1700k. also, tried GND to Pin5, GND to RESET pin on boot - nothing works.
Tried universal-silabs-flasher and bt_host_uart_dfu under different conditions, hang or nothing detected.
@hurrian @duo8 @andrewjlamarche
I have followed all the thread with no success, some help would be greatly appreciated!
Hi All,
Long time openwrt user. First Post on these forums.
I have one of this these devices (Lumen W1700K) with HW version 2.1
Is this hardware version supported?
I have never used a wifi router that lacked normal (full?) OpenWRT support.
How do I get started with this device as a replacement for some aging home gear (Ubiquiti UniFi AC Pro)?
Very much looking forward to seeing W1700K support officially in OpenWRT.
Thank you very much.
T1F
