# WF100DPZ API Reference

This document describes the public API in `src/WF100DPZ.h`.

## Scope

This library currently targets the **WF100DPZ 2BG** (2 bar / 200 kPa) variant.
Conversion behavior and constants may differ on other SKUs.

# Initialization

## Constructors
The library supports a variety of constructors with varying complexity.

- `WF100DPZ(int pinCsb, int pinSda, int pinClk)` Pin mapping with default configuration.

- `WF100DPZ(int pinCsb, int pinSda, int pinClk, const Config& cfg)` Pin mapping with added configuration parameters

## Initializer
The library is initialized by running `begin()`. Optionally, an `end()` method is provided for safe termination.

- `bool begin(StatusCode* status = nullptr)` Initializes backend, applies `sample_interval`, runs startup part-id validation (per policy), and primes sensor state with one combined conversion.

- `bool end(StatusCode* status = nullptr)`: Stops active non-blocking/continuous activity and returns the instance to an uninitialized state.

- `bool isInitialized() const`: Returns initializer state.

- `uint8_t readPartId(StatusCode* status = nullptr)`: Reads the sensor part ID register.

# Measurements

This library supports combinations of single-shot and continuous, and blocking and non-blocking measurements. Methods return data directly and may optionally report `StatusCode` via `StatusCode* status`.

## Basic Methods
Two basic methods are provided. These are blocking single-shot methods.

- `float readTemp()` Return the temperature in degrees Celsius.

- `float readPressure()` Returns the gauge pressure in kPa.

## Advanced Methods
### Blocking One-Shot
Blocking methods are what are typically provided by Arduino libraries. While running, all other code execution is blocked. In contrast to the basic methods, advanced methods take pointers and return status codes.


- `float readTemp(StatusCode* status = nullptr)` Returns temperature in Celsius (`NAN` on error).

- `float readPressure(StatusCode* status = nullptr)` Returns pressure in kPa (`NAN` on error).

- `Sample readCombined(StatusCode* status = nullptr)`

Additionally, a unified read method is available.

- `Sample read(Mode mode = Mode::Combined, StatusCode* status = nullptr)`

  Where the structure `Sample` includes: `mode`, `has_temp`, `has_pressure`, `temp_c`, `pressure_kpa`, `status_raw`, `error_code`, `elapsed_us`, `timestamp_ms`.

### Non-Blocking One-Shot
Non-blocking methods allow other code to be run while executing. However, they must be polled to determine when they are complete. Typically, a workflow looks like this:

1. `bool start(Mode mode = Mode::Combined, StatusCode* status = nullptr)` Starts a measurement. If a one-shot or continuous operation is already active, `start(...)` returns `false` and sets `Busy`.

2. `bool ready(StatusCode* status = nullptr)` Checks if the result is ready. Returns `true` when ready, `false` when not ready. If `status` is provided, non-`Ok` distinguishes errors.

3. `Sample getResult(StatusCode* status = nullptr)` Reads the completed result. On error, returns a default sample and sets non-`Ok` status.

4. Optionally, `void cancel()` aborts the current one-shot non-blocking request.


### Non-Blocking Continuous
Non-blocking continuous methods stream repeated measurements while allowing other code to run. Like one-shot non-blocking, completion must be polled before reading each sample. A typical workflow looks like this:

1. `bool startContinuous(Mode mode = Mode::Combined, StatusCode* status = nullptr)` starts a continuous stream.

2. `bool continuousReady(StatusCode* status = nullptr)` checks whether the next sample is ready. Returns `true` when ready, `false` when not ready. If `status` is provided, non-`Ok` distinguishes errors.

3. `Sample getContinuousResult(StatusCode* status = nullptr)` reads the next sample once ready.

4. Repeat steps 2 and 3 as long as you want to keep streaming.

5. `void stopContinuous()` stops the active continuous stream.

Continuous measurements can cause the sensor to heat up. By setting the `sample_interval` (default=`0`, max=`15`) sensor heating is reduced and sensor accuracy can improve. The sampling interval is roughly `44.3 ms * sample_interval`.

- `bool setSampleInterval(uint8_t interval, StatusCode* status = nullptr)`: Sets the continuous sample interval. Valid range is `0` to `15`.

- `uint8_t getSampleInterval() const`: Returns the currently applied sample interval.


# Status Codes
When a method is called with a non-null `StatusCode* status`, it writes one of these values.
Treat `Ok` as success; any non-`Ok` value means the call did not complete as requested and should be handled (or reported with `statusString(...)`).

- `Ok`: Operation completed successfully.
- `NotInitialized`: `begin()` has not completed successfully yet.
- `InvalidArgument`: One or more input arguments are invalid.
- `Busy`: Sensor is currently handling another operation.
- `Timeout`: Data was not ready before the timeout window.
- `TransportError`: Bus/protocol-level communication error was detected.
- `Unsupported`: Requested feature is not supported on this platform/backend.
- `InitFailed`: Initialization failed (for example, startup validation failed).
- `InternalError`: Unexpected internal failure not covered by other codes.

## Methods

- `StatusCode lastStatus() const` Returns the most recent status produced by this `WF100DPZ` instance.

- `const char* statusString() const` Returns a human-readable string for `lastStatus()`.

- `const char* statusString(StatusCode code) const` Returns a human-readable string for an explicit status value.

- `uint8_t readStatus(StatusCode* status = nullptr)` Returns the sensor `error_code` nibble.

# Configuration

## Measurement Modes

The library supports three measurement modes via `Mode`:

- `TempOnly` Runs a temperature conversion only.

- `PressureOnly` Runs a pressure conversion only. For best results, a temperature measurement should be completed at least once per second to keep pressure measurements accurate. This can be done automatically by enabling [`auto_refresh_temp`](#auto_refresh_temp).

- `Combined` Runs both temperature and pressure conversion together.

## Backends
The library contains two backends `BitBang` and `EspIdf3Wire`. Because the sensor uses a non-standard 3-wire SPI interface, only the bit-bang backend is available for Arduino which limits the SPI speed to ~2MHz. On ESP32, a modified 3-wire interface allows speeds up to ~20MHz (although speed as high as ~33MHz have been tested). There are minimal benefits to sample rates for higher clock speeds (+16% BitBang vs 20MHz EspIdf3Wire). The backend options are:

- `Auto`: Which prefers `EspIdf3Wire` when possible but falls back to `BitBang`
- `EspIdf3Wire`: Only on ESP32. Allows variable SPI clock speeds. Minimal sample rate improvement.
- `BitBang`: Fallback method available on all platforms.

## Configuration File

A config file `WF100DPZ::Config` can be provided to the constructor with the following fields:
- `backend` (default `Backend::Auto`): Backend type
- `spi_hz` (ESP32 only, default `20000000`): SPI clock speed
- `host` (ESP32 only, default `SPI2_HOST`): SPI host
- `sample_interval` (default `0x00`): Value between `0x00` and `0x0F`. Used by continuous sampling internals (internal sleep-periodic timing ~ `44.3 ms * sample_interval`).
- `startup`: See [`StartupPolicy`](#startuppolicy)
- `auto_refresh_temp`: See [`auto_refresh_temp`](#auto_refresh_temp)


### `auto_refresh_temp`
Automatically refreshes the temperature during [`PressureOnly`](#pressureonly) measurements.
- `enabled` (default `true`): Enables automatic temperature refresh. *Can result in inconsistent sample times.*
- `period_ms` (default `1000`): Refresh period, time between temperature measurements.

### `StartupPolicy`
- `require_valid_part_id` (default `true`): Whether to check for a valid part ID
- `part_id_retries` (default `3`): Number of times to check
- `retry_delay_ms` (default `15`): Time to wait between checks

## Methods

- `bool setConfig(const Config& cfg, StatusCode* status = nullptr)`: Replaces the current configuration after initialization. Cannot be called during non-blocking one-shot or continuous measurements.

- `Config getConfig() const`: Returns a copy of the current full configuration snapshot. After `begin()`, `config.backend` reflects the active backend selected by the core.


# Examples

- Basic startup and blocking read: `examples/QuickStart/QuickStart.ino`
- Config/policy tuning: `examples/AdvancedConfig/AdvancedConfig.ino`
- Non-blocking one-shot polling flow: `examples/NonBlockingRead/NonBlockingRead.ino`
- Non-blocking continuous polling flow: `examples/ContinuousRead/ContinuousRead.ino`
