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 crate::modem::hw;
use crate::modem::signal;
use crate::modem::sim;
use core::sync::atomic::{AtomicU8, Ordering};

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

pub struct ModemDriver {
    pub base: usize,
    pub modem_id: u32,
}

pub fn probe(base: usize) -> ModemDriver {
    let id = hw::modem_id(base);
    DRIVER_STATE.store(1, Ordering::Release);
    ModemDriver { base, modem_id: id }
}

pub fn init(driver: &ModemDriver) -> bool {
    hw::reset(driver.base);
    hw::enable(driver.base);
    if hw::sim_present(driver.base) {
        sim::set_state(sim::SimState::Ready);
    } else {
        sim::set_state(sim::SimState::Absent);
    }
    let raw_signal = hw::read_signal_strength(driver.base);
    let rssi = signal::rssi_from_raw(raw_signal);
    signal::update_rssi(rssi);
    let cell = hw::read_cell_id(driver.base);
    signal::update_cell_id(cell);
    DRIVER_STATE.store(2, Ordering::Release);
    true
}

pub fn send_byte(driver: &ModemDriver, byte: u8) -> bool {
    if hw::tx_ready(driver.base) {
        hw::write_tx(driver.base, byte);
        true
    } else {
        false
    }
}

pub fn recv_byte(driver: &ModemDriver) -> Option<u8> {
    if hw::rx_available(driver.base) {
        Some(hw::read_rx(driver.base))
    } else {
        None
    }
}

pub fn shutdown(driver: &ModemDriver) {
    hw::disable(driver.base);
    DRIVER_STATE.store(0, Ordering::Release);
}

pub fn state() -> u8 {
    DRIVER_STATE.load(Ordering::Acquire)
}