flipperzero 0.15.0

Rust for Flipper Zero
Documentation
//! Example of communicating with a [DS3231] Real-Time Clock.
//!
//! [DS3231]: https://www.analog.com/media/en/technical-documentation/data-sheets/DS3231.pdf

#![no_main]
#![no_std]

// Required for panic handler
extern crate flipperzero_rt;

// Required for allocator
#[cfg(feature = "alloc")]
extern crate flipperzero_alloc;

use core::ffi::CStr;

use flipperzero::{error, furi::time::FuriDuration, gpio::i2c, println};
use flipperzero_rt::{entry, manifest};
use ufmt::derive::uDebug;

manifest!(name = "I2C DS3231 Example");
entry!(main);

#[derive(Debug, uDebug)]
enum Hour {
    F12 { hour: u8, pm: bool },
    F24(u8),
}

#[derive(Debug, uDebug)]
struct RtcTime {
    year: u8,
    month: u8,
    date: u8,
    day: u8,
    hour: Hour,
    minutes: u8,
    seconds: u8,
}

impl RtcTime {
    fn parse(data: [u8; 7]) -> Self {
        let unbcd = |b: u8| 10 * (b >> 4) + (b & 0x0F);

        const FORMAT_12HR: u8 = 0b0100_0000;

        Self {
            year: unbcd(data[6]),
            month: unbcd(data[5] & 0x1F),
            date: unbcd(data[4] & 0x3F),
            day: data[3] & 0x07,
            hour: if data[2] & FORMAT_12HR != 0 {
                Hour::F12 {
                    hour: unbcd(data[2] & 0x1F),
                    pm: data[2] & 0b0010_0000 != 0,
                }
            } else {
                Hour::F24(unbcd(data[2] & 0x3F))
            },
            minutes: unbcd(data[1] & 0x7F),
            seconds: unbcd(data[0] & 0x7F),
        }
    }
}

fn main(_args: Option<&CStr>) -> i32 {
    let mut bus = i2c::Bus::EXTERNAL.acquire();
    let rtc = i2c::DeviceAddress::new(0x68);
    let timeout = FuriDuration::from_millis(50);

    if bus.is_device_ready(rtc, timeout) {
        let mut data = [0; 7];
        if bus.read_exact(rtc, 0x00, &mut data, timeout).is_ok() {
            println!("Time: {:?}", RtcTime::parse(data));
        } else {
            error!("Could not read from DS3231");
        }
    } else {
        error!("DS3231 is not connected and ready");
    }

    0
}