<!-- SPDX-FileCopyrightText: Copyright 2026 Jetperch LLC
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->

<a id="program"></a>

# Program

Device firmware and gateware programming.

<a id="module-pyjoulescope_driver.program"></a>

Handle device programming for firmware and gateware.

For finer control on updating, use the jsdrv example application.  For example:

jsdrv reset update1 && jsdrv mem_erase c/upd2 && jsdrv mem_write c/upd2 “C:/joulescope/js220/images/ctrl_release/updater2/js220_ctrl_updater2_1_0_1.img” && jsdrv reset update2
jsdrv reset update2 && jsdrv mem_erase c/upd1 && jsdrv mem_write c/upd1 “C:/joulescope/js220/images/ctrl_release/updater1/js220_ctrl_updater1_1_0_1.img” && jsdrv reset update1
jsdrv reset update1 && jsdrv mem_erase c/app && jsdrv mem_write c/app “C:/joulescope/js220/images/ctrl_release/app/js220_ctrl_app_1_0_1.img” && jsdrv reset app
jsdrv reset update1 && jsdrv mem_erase s/app1 && jsdrv mem_write s/app1 “C:/joulescope/js220/images/fpga_release/js220_fpga_1_0_1.img” && jsdrv reset app

### pyjoulescope_driver.program.release_program(driver: [Driver](https://docs.joulescope.com/en/software/joulescope_driver/driver.md#pyjoulescope_driver.Driver), device_path: str, image: bytes, force_program=None, progress=None)

Program a device with an official release.

* **Parameters:**
  * **driver** – The driver instance.
  * **device_path** – The device path string for the target device.
  * **image** – The binary release image to program.  See
    `pyjoulescope_driver.release.release_get()`.
  * **force_program** – Force device programming for all segments.
    Normally, programming for segments with matching versions are skipped.
  * **progress** – An optional callable(completion: float, msg: str) callback.
    When provided, this function will be called to provide progress updates.
    \* completion: The completion status from 0.0 (not started) to 1.0 (done).
    \* msg: A user-meaningful status message.

<a id="module-pyjoulescope_driver.program_js320"></a>

JS320 firmware update via the in-driver fwup manager.

Mirrors the C definitions in
`include_private/jsdrv_prv/devices/js320/js320_fwup_mgr.h`.
The full update sequence runs in a worker thread inside the driver;
this module just publishes the request and watches the status topic.

### pyjoulescope_driver.program_js320.program_js320(driver: [Driver](https://docs.joulescope.com/en/software/joulescope_driver/driver.md#pyjoulescope_driver.Driver), device_path: str, package_path: str = None, flags: int = 0, progress=None, timeout: float = 600.0)

Program a JS320 device using the firmware update manager.

Publishes the request to `fwup/@/!add` and monitors the
per-worker `fwup/NNN/status` topic until the worker reports a
terminal `DONE` or `ERROR` state.

The driver must be initialized but the device must NOT already be
open: the worker opens the device internally in raw mode.

* **Parameters:**
  * **driver** – The driver instance.
  * **device_path** – The target device path (e.g., `u/js320/8w2a`).
  * **package_path** – The path to the manufacturing ZIP package.
    `None` (default) uses the firmware embedded in the driver build.
  * **flags** – Bitmask of `FWUP_FLAG_SKIP_*` flags.
  * **progress** – An optional callable(completion: float, msg: str).
  * **timeout** – Maximum total time to wait, in seconds.
* **Raises:**
  * **RuntimeError** – If the firmware update fails.
  * **TimeoutError** – If the firmware update does not complete in time.
