npm.io
1.0.0 • Published 1 month ago

nrfutil-web

Licence
BSD-3-Clause
Version
1.0.0
Deps
1
Size
69 kB
Vulns
0
Weekly
0

nrfutil-web

Flash nRF52 firmware from the browser using Web Serial — no drivers, no desktop app required.

Live Demo

Features

  • Uses the browser's Web Serial API
  • Compatible with the Adafruit nRF52 bootloader DFU protocol
  • Accepts ZIP packages generated by adafruit-nrfutil directly
  • Supports Application, SoftDevice, Bootloader, and SD+BL updates
  • Progress callback support
  • TypeScript support with type definitions included
  • Single dependency: jszip

Requirements

  • A browser that supports Web Serial API (Chrome, Edge, etc.)
  • A DFU package in ZIP format generated by adafruit-nrfutil

Installation

pnpm add nrfutil-web
# or
npm install nrfutil-web

Usage

Basic usage
import { performDfu, enterDfuMode } from "nrfutil-web";

// 1. Connect to the application port
const appPort = await navigator.serial.requestPort();

// 2. Trigger DFU mode via 1200bps touch
await enterDfuMode(appPort);

// 3. Wait for the device to re-enumerate, then select the DFU port
const dfuPort = await navigator.serial.requestPort();

// 4. Fetch firmware and flash
const zipData = await fetch("/firmware.zip").then(r => r.arrayBuffer());

await performDfu(dfuPort, zipData, {
  onProgress: ({ percent, message }) => {
    console.log(`${percent}% - ${message}`);
  },
});
API Reference
performDfu(port, zipData, options?)

Performs the DFU firmware update.

Parameter Type Description
port SerialPortLike WebSerial port
zipData ArrayBuffer DFU package ZIP
options.onProgress ProgressCallback Progress callback
options.ackTimeout number ACK timeout in ms (default: 5000)
options.maxRetries number Max retries per packet (default: 3)
options.singleBank boolean Single bank mode (default: true)
enterDfuMode(port, waitTime?)

Sends a 1200bps touch to trigger DFU mode on the device.

Parameter Type Description
port SerialPortLike WebSerial port
waitTime number Wait time after touch in ms (default: 1500)
ProgressCallback
type ProgressCallback = (progress: {
  sent: number;    // Bytes sent so far
  total: number;   // Total bytes to send
  percent: number; // Progress (0100)
  message: string; // Current operation description
}) => void;
Advanced usage

Lower-level APIs are also available for advanced use cases.

import { DfuSerialTransport, parseDfuPackage } from "nrfutil-web";

// Parse the ZIP manually
const images = await parseDfuPackage(zipData);

// Operate the transport directly
const transport = new DfuSerialTransport(port, { ackTimeout: 10000 });
await transport.open();
await transport.sendPacket(payload);
await transport.close();

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Run tests
pnpm test

# Start demo page (examples/index.html)
pnpm dev

Architecture

src/
├── index.ts          # Public API
├── dfu.ts            # DFU main controller
├── transport.ts      # Serial transport (HCI / SLIP / ACK)
├── package.ts        # DFU ZIP package parser
├── dfu-protocol.ts   # Protocol constants and packet builders
├── hci.ts            # HCI packet handling
├── slip.ts           # SLIP encode / decode
└── crc16.ts          # CRC-16 calculation

License

BSD-3-Clause