extern crate stm32f103xx; use ::i2c::{I2C, TransDir}; const DS3231_ADDR: u8 = 0b1101000; const DS3231_REG_SEC: u8 = 0x00; pub struct DS3231<'a> { i2c: I2C<'a> } pub struct Date { second: u8, minute: u8, hour: u8, day: u8, date: u8, month: u8, year: u8 } impl<'a> DS3231<'a> { pub fn new(i2c_reg: &'a stm32f103xx::i2c1::RegisterBlock) -> DS3231<'a> { DS3231{i2c: I2C::new(i2c_reg)} } fn bcd2dec(bcd: u8) -> u8 { (bcd >> 4) * 10 + (bcd & 0x0f) } fn dec2bcd(dec: u8) -> u8 { ((dec / 10) << 4) | (dec % 10) } pub fn read_fulldate(&self) -> Date { let mut buf: [u8; 7] = [0; 7]; let i2c = &self.i2c; i2c.conf_ack(true); /* enable ack */ i2c.start(true, true); /* start condition (for writing reg addr) */ i2c.send_addr(DS3231_ADDR, TransDir::TRANSMITTER, true); i2c.send(DS3231_REG_SEC, true); /* restart condition (for reading val from the reg addr) */ i2c.start(true, true); i2c.send_addr(DS3231_ADDR, TransDir::RECEIVER, true); for i in 0..6 { buf[i] = i2c.recv(true); } i2c.conf_ack(false); /* disable ack (send nack) */ buf[6] = i2c.recv(true); i2c.stop(true); Date{second: DS3231::bcd2dec(buf[0]), minute: DS3231::bcd2dec(buf[1]), hour: DS3231::bcd2dec(buf[2]), day: DS3231::bcd2dec(buf[3]), date: DS3231::bcd2dec(buf[4]), month: DS3231::bcd2dec(buf[5]), year: DS3231::bcd2dec(buf[6])} } pub fn write_fulldate(&self, date: &Date) { let i2c = &self.i2c; let buf: [u8; 7] = [DS3231::dec2bcd(date.second), DS3231::dec2bcd(date.minute), DS3231::dec2bcd(date.hour), DS3231::dec2bcd(date.day), DS3231::dec2bcd(date.date), DS3231::dec2bcd(date.month), DS3231::dec2bcd(date.year)]; i2c.conf_ack(true); i2c.start(true, true); /* start condition for writing */ i2c.send_addr(DS3231_ADDR, TransDir::TRANSMITTER, true); i2c.send(DS3231_REG_SEC, true); for i in 0..7 { i2c.send(buf[i], true); } i2c.stop(true); } }