Framework

FM1Kit

Install firmware on the M-VAVE FM-1 over USB-MIDI, from iOS and macOS.

Overview

FM1Kit speaks the FM-1's update protocol. It reads .fwsc firmware packages, finds the device, answers its read requests while it stages and writes the new firmware, and checks the device reports the new firmware afterwards. It can also finish an update that was cut off, or one started from USB recovery mode.

It sticks to the device: finding and downloading firmwares is left to your app. FM-SWITCH is built on it.

ImportantFM1Kit has been tested on one FM-1 so far, from both a Mac and an iPhone. It isn't affiliated with M-VAVE, and installing custom firmware is at your own risk.

Install the package

Add FM1Kit with Swift Package Manager. Until 1.0, minor versions may change the API, so take 0.2.x fixes but not 0.3.0.

.package(url: "https://github.com/ocean/FM1Kit.git", .upToNextMinor(from: "0.2.0")),

Install a firmware

Read the package, check what installing it would do, then install it and follow its progress. Switching to a different firmware can erase the FM-1's projects and samples, so it needs confirming.

import FM1Kit

let package = try FwscPackage(data: Data(contentsOf: fileURL))
let updater = FM1Updater(transport: try CoreMIDITransport(clientName: "My App"))

let check = try await updater.check(package)
let confirmed = check.kind != .switchingFirmware || askToSwitch(from: check.device)

try await updater.install(package, options: InstallOptions(confirmsSwitchingFirmware: confirmed)) { event in
    switch event {
    case .writing(let fraction, _): print("Writing \(Int(fraction * 100))%")
    case .finished(let identity): print("Now running \(identity)")
    default: break
    }
}

// Finish an update that was cut off, or one started in USB recovery mode.
if let identity = await updater.identify(), identity.isLoader {
    try await updater.resume(package)
}

Topics

Packages

Devices

Updating

Transports

fm1probe

A Mac command-line tool for checking a setup and watching an install closely. Only install and restore-voices write to the device, and only after you type YES.

swift run fm1probe ports                 # list MIDI ports
swift run fm1probe identify              # ask the FM-1 what it's running
swift run fm1probe inspect FILE.fwsc     # a package's identity, size and checksum
swift run fm1probe install FILE.fwsc     # install a firmware

Recovery

Whenever the FM-1 is in its update loader, whether from USB recovery mode (hold OCT− while switching it on, on firmwares that offer it) or an interrupted update, resume(_:events:) can install a firmware. Beyond that is the chip's ROM bootloader, which FM1Kit doesn't cover.

See also

Source, documentation and changelog on GitHub

FM-1-RE: the reverse-engineering notes the protocol is written from.