Registers Module
We will create an enum to represent the registers of the DS1307 RTC:
#![allow(unused)]
fn main() {
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Register {
/// Seconds register (0x00) - BCD format 00-59, bit 7 = Clock Halt
Seconds = 0x00,
/// Minutes register (0x01) - BCD format 00-59
Minutes = 0x01,
/// Hours register (0x02) - BCD format, supports 12/24 hour mode
Hours = 0x02,
/// Day of week register (0x03) - 1-7 (Sunday=1)
Day = 0x03,
/// Date register (0x04) - BCD format 01-31
Date = 0x04,
/// Month register (0x05) - BCD format 01-12
Month = 0x05,
/// Year register (0x06) - BCD format 00-99 (2000-2099)
Year = 0x06,
/// Control register (0x07) - Square wave and output control
Control = 0x07,
}
}
We will create addr() method that allows to get the register address as a u8 value for I2C communication. We have marked it as const fn so it can be evaluated at compile time. Since we have marked the enum #[repr(u8)], we can just cast as u8 for the conversion.
#![allow(unused)]
fn main() {
impl Register {
pub const fn addr(self) -> u8 {
self as u8
}
}
}
We will define constants for the register bit flags that control various DS1307 features:
#![allow(unused)]
fn main() {
/// Seconds register (0x00) bit flags
pub const CH_BIT: u8 = 0b1000_0000; // Clock Halt
/// Control register (0x07) bit flags
/// Square Wave Enable
pub const SQWE_BIT: u8 = 0b0001_0000;
/// Output Level
pub const OUT_BIT: u8 = 0b1000_0000;
/// Rate Select mask
pub const RS_MASK: u8 = 0b0000_0011;
}
The Clock Halt bit (CH_BIT) in the seconds register stops the oscillator when set. The control register bits manage the square wave output: SQWE_BIT enables/disables the Square wave output, OUT_BIT sets the output level when square wave is disabled, and RS_MASK selects the square wave frequency.
We will also define constants for the NVRAM memory layout:
#![allow(unused)]
fn main() {
/// DS1307 NVRAM starts at register 0x08
pub const NVRAM_START: u8 = 0x08;
/// DS1307 has 56 bytes of NVRAM (0x08-0x3F)
pub const NVRAM_SIZE: u8 = 56;
/// 56 NVRAM + 1 address byte
pub const MAX_NVRAM_WRITE: usize = 57;
}
The Full code for the registers module(registers.rs)
#![allow(unused)]
fn main() {
//! DS1307 Registers
/// DS1307 Registers
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Register {
/// Seconds register (0x00) - BCD format 00-59, bit 7 = Clock Halt
Seconds = 0x00,
/// Minutes register (0x01) - BCD format 00-59
Minutes = 0x01,
/// Hours register (0x02) - BCD format, supports 12/24 hour mode
Hours = 0x02,
/// Day of week register (0x03) - 1-7 (Sunday=1)
Day = 0x03,
/// Date register (0x04) - BCD format 01-31
Date = 0x04,
/// Month register (0x05) - BCD format 01-12
Month = 0x05,
/// Year register (0x06) - BCD format 00-99 (2000-2099)
Year = 0x06,
/// Control register (0x07) - Square wave and output control
Control = 0x07,
}
impl Register {
/// Returns the raw 7-bit register address as `u8`.
pub const fn addr(self) -> u8 {
self as u8
}
}
/// Seconds register (0x00) bit flags
pub const CH_BIT: u8 = 0b1000_0000; // Clock Halt
/// Control register (0x07) bit flags
/// Square Wave Enable
pub const SQWE_BIT: u8 = 0b0001_0000;
/// Output Level
pub const OUT_BIT: u8 = 0b1000_0000;
/// Rate Select mask
pub const RS_MASK: u8 = 0b0000_0011;
/// DS1307 NVRAM starts at register 0x08
pub const NVRAM_START: u8 = 0x08;
/// DS1307 has 56 bytes of NVRAM (0x08-0x3F)
pub const NVRAM_SIZE: u8 = 56;
/// 56 NVRAM + 1 address byte
pub const MAX_NVRAM_WRITE: usize = 57;
}