Skip to content

fix: set ADS1262 MODE1 to SINC3 and correct FILTER bit shift in mode_1 - #15

Open
WhiteSong666 wants to merge 2 commits into
anyshake:masterfrom
WhiteSong666:master
Open

fix: set ADS1262 MODE1 to SINC3 and correct FILTER bit shift in mode_1#15
WhiteSong666 wants to merge 2 commits into
anyshake:masterfrom
WhiteSong666:master

Conversation

@WhiteSong666

@WhiteSong666 WhiteSong666 commented Aug 28, 2026

Copy link
Copy Markdown

Description

This PR fixes a latent ADC initialization defect, together with a related
one-bit shift bug in the MODE1 register driver. Both changes must land
together: the first fix calls the exact function broken by the second.

1. MODE1 is never written — ADC stays in FIR at an illegal data rate

peri_adc_init() (firmware/User/Src/peripheral.c:93) sets MODE0
(ONESHOT) and MODE2.DR = DR_4800, but never writes MODE1. MODE1 keeps
its reset value 0x80FILTER[2:0] = 100 = FIR (TI SBAS661C, §9.6.5).
Under FIR, the only legal data rates are 2.5/5/10/20 SPS (§9.6.6), so the
hardcoded 4800 SPS is invalid: a clean build from this repository leaves
the ADC running at ≤ 20 SPS (DRDY ≈ 50 ms) and cannot support the 250 SPS
output path. Shipped units work only because production firmware
configures MODE1 = SINC3 outside this repo (consistent with recorded
data: valid <10 Hz band-limited seismic signal, DRDY ≈ 0.2 ms).

Fix: explicitly program MODE1 = SINC3 (ADS1262_REG_MODE_1_FILTER_SINC3
= 0x02) in peri_adc_init() before writing MODE2. SINC3 balances stopband
rejection with bandwidth/latency, and keeps the existing fixed-ODR +
timer-gated-output design working exactly as intended — no DIP→DR wiring
required.

2. ads1262_reg_set_mode_1() writes FILTER one bit off

mode_1.c:15 uses (filter & 0x07) << 6, but FILTER occupies MODE1 bits
[7:5]; the clear mask ~(0x07 << 5) and the read path >> 5 both
correctly use bit 5, so the file is internally inconsistent. With << 6:

  • SINC2 (0x01) → 0x40 → SINC3
  • SINC3 (0x02) → 0x80 → FIR
  • SINC4 (0x03) → 0xC0 → undefined value
  • FIR (0x04) → 0x100, truncated to 0x00 → SINC1

The function has no callers today, which is why this stayed latent — but
without this correction the fix above would silently write FIR (0x80)
instead of SINC3, i.e. it would be a complete no-op.

Changes

  • firmware/User/Src/peripheral.cperi_adc_init(): program
    MODE1 = SINC3 via ads1262_reg_set_mode_1() before setting MODE2
  • firmware/User/Src/ads1262/regs/mode_1.c — correct the FILTER write
    shift from << 6 to << 5

Fixes #12

  • pull a topic/feature/bugfix branch (right side)
  • PR against the master branch, branch started off master
  • AnyShake Explorer firmware can be successfully built
  • no impact on AnyShake Observer / sync word (register-level fix, no protocol change)
  • continuous integration build not broken

Further comments

Verification on hardware: after flashing a clean build with both fixes,
the DRDY interval should measure ≈ 0.2 ms (SINC3 / 4800 SPS); before the
fix it is ≈ 50 ms.

In `peri_adc_init()`, the ADS1262 ADC was left at its power-on reset 
value for the MODE1 register (0x80, FIR filter mode). Subsequently 
setting MODE2.DR to 4800 SPS created an illegal register state, as 
FIR mode strictly limits data rates to a maximum of 20 SPS per the 
datasheet (§9.6.6).

Although practical testing showed the chip silently falling back to 
a SINC-like behavior, relying on this undocumented hardware state 
poses a severe robustness risk for future chip batches.

This commit explicitly calls `ads1262_reg_set_mode_1()` to select 
the SINC3 filter (`FILTER[2:0] = 010`) before configuring the data 
rate. This ensures the 4800 SPS setting is fully legal and compliant 
with the TI ADS1262 specifications.

Closes anyshake#12
The FILTER field of the MODE1 register occupies bits [7:5] (TI
SBAS661C, section 9.6.5). The write path shifted the 3-bit filter
value by 6 instead of 5, while the clear mask (~(0x07 << 5)) and
the read path (>> 5) both correctly address bit 5, so any value
written through ads1262_reg_set_mode_1() landed one bit off:

  SINC2 (0x01) -> 0x40 -> SINC3
  SINC3 (0x02) -> 0x80 -> FIR
  SINC4 (0x03) -> 0xC0 -> undefined value
  FIR   (0x04) -> 0x100, truncated to 0x00 -> SINC1

Only SINC1 (0x00) happened to produce the correct result. The
function has no callers yet, which is why the bug stayed latent;
it must be fixed before MODE1 is programmed to SINC3, otherwise
the hardcoded DR_4800 data rate remains invalid.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug - 初始化未配置 MODE1,ADC 保持在 FIR 模式 Bug - MODE1 never configured during initialization; ADC stays in FIR mode

1 participant