summaryrefslogtreecommitdiff
path: root/src/ds3231.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ds3231.rs')
-rw-r--r--src/ds3231.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/ds3231.rs b/src/ds3231.rs
new file mode 100644
index 0000000..6ad75d8
--- /dev/null
+++ b/src/ds3231.rs
@@ -0,0 +1,77 @@
+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);
+ }
+}