hardware 0.0.9

A no_std bare-metal hardware abstraction layer — all port I/O, memory and swap allocations are guarded at runtime. Do not consider this dependency stable before x.1.x
Documentation
use core::sync::atomic::{AtomicU8, Ordering};

#[derive(Clone, Copy, PartialEq)]
pub enum PipelineStage {
    Idle,
    BlackLevel,
    Demosaic,
    WhiteBalance,
    ColorCorrection,
    GammaCorrection,
    NoiseReduction,
    Sharpening,
    Output,
}

static CURRENT_STAGE: AtomicU8 = AtomicU8::new(0);

fn stage_to_u8(s: PipelineStage) -> u8 {
    match s {
        PipelineStage::Idle => 0,
        PipelineStage::BlackLevel => 1,
        PipelineStage::Demosaic => 2,
        PipelineStage::WhiteBalance => 3,
        PipelineStage::ColorCorrection => 4,
        PipelineStage::GammaCorrection => 5,
        PipelineStage::NoiseReduction => 6,
        PipelineStage::Sharpening => 7,
        PipelineStage::Output => 8,
    }
}

fn u8_to_stage(v: u8) -> PipelineStage {
    match v {
        1 => PipelineStage::BlackLevel,
        2 => PipelineStage::Demosaic,
        3 => PipelineStage::WhiteBalance,
        4 => PipelineStage::ColorCorrection,
        5 => PipelineStage::GammaCorrection,
        6 => PipelineStage::NoiseReduction,
        7 => PipelineStage::Sharpening,
        8 => PipelineStage::Output,
        _ => PipelineStage::Idle,
    }
}

pub fn current_stage() -> PipelineStage {
    u8_to_stage(CURRENT_STAGE.load(Ordering::Acquire))
}

pub fn advance_stage() -> PipelineStage {
    let cur = CURRENT_STAGE.load(Ordering::Acquire);
    let next = if cur >= 8 { 0 } else { cur + 1 };
    CURRENT_STAGE.store(next, Ordering::Release);
    u8_to_stage(next)
}

pub fn reset_pipeline() {
    CURRENT_STAGE.store(0, Ordering::Release);
}

pub fn set_stage(stage: PipelineStage) {
    CURRENT_STAGE.store(stage_to_u8(stage), Ordering::Release);
}

pub fn is_processing() -> bool {
    let s = CURRENT_STAGE.load(Ordering::Acquire);
    s > 0 && s < 8
}