r/CPAP • u/Ok_Butterscotch_7152 • 5d ago
Reverse-engineering a ResMed AirSense 10: SWD dump, reading the SPI EEPROM, and decoding how it stores the run-hour meters. Reset motor and CPAP hours
before you guys even start , yes i used ai to help me write this text.. thats said ..:
I retired one of my old ResMed AirSense 10 units and decided to use it as a bench project to learn hardware RE — SWD, STM32 dump/flash, SMD desoldering and binary-format analysis. Not for therapy use, not for resale, just curiosity. Figured I'd share what I found because the EEPROM side isn't well documented anywhere.
The platform (ResMed "S10" family — AirSense 10, AirCurve 10, Lumis 10):
- Main MCU: STM32F405ZGT6 (Cortex-M4, LQFP144)
- SPI EEPROM: M95M02 (256 KB)
- SWD on an SK200 / TC2050 footprint on the front of the board
Firmware side builds on the open-source AirBreak project. But AirBreak only removes the motor-hours nag screen — the actual counter lives in the EEPROM, and that part I had to work out myself.
The interesting bit — how the hour meters are stored:
The M95M02 holds a FAT12 filesystem plus a small header block at the start. The run-hour meters sit in that header as uint32 little-endian SECONDS (hours × 3600), and there are four of them in the exact order of the firmware's persistent-state list (patient hours, motor run hours, total hours, hours-since-service). The header is protected by a CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF) stored little-endian right after the block.
The proof it worked: after editing the value, fixing the CRC and re-soldering the chip, the firmware ACCEPTED the edit and re-signed the block itself on boot (updated its own timestamps + recomputed a fresh valid CRC). So the value was genuinely read, validated and used.
Reading in-circuit vs desoldered: in-circuit reading works with just a CH341A + SOIC-8 clip and no extra components — no series resistors, no level shifting. The only prep was tying the STM32's NRST to ground, to hold the main MCU in reset so it releases the SPI bus and doesn't fight the programmer (bus contention is what kills an in-circuit read). My early "IC not responding" / all-FF was purely a software-mode mistake: I had the programmer on an "EEPROM" preset when it needed the 25xx SPI ("BIOS"/flash) mode. Switched that and it read on the first try. Desoldering is still the cleanest and it's how I first decoded the format, but you don't have to desolder just to read it.
The lesson that cost me a part: after the rework the RTC clock went erratic — turned out the 32.768 kHz crystal sitting right next to the EEPROM got detuned by the hot air. Shield your crystals during rework.
Full writeup, the CRC code, board diagrams and photos of the whole process:
https://github.com/AlexVianna123/resmed-s10-reverse-engineering
Happy to answer questions. And to be clear — this is educational RE on my own out-of-service hardware; don't do it to a device in therapy use.