Expand description
This is a platform agnostic Rust driver for the DS3231, DS3232 and DS3234
extremely accurate real-time clocks, based on the embedded-hal
traits.
This driver allows you to:
- Read and set date and time in 12-hour and 24-hour format. See:
datetime
. - Read and set date and time individual elements. For example, see:
year
. - Enable and disable the real-time clock. See:
enable
. - Read the busy status. See
busy
. - Read whether the oscillator is or has been stopped. See
has_been_stopped
. - Clear the has-been-stopped flag. See
clear_has_been_stopped_flag
. - Set and read the aging offset. See
set_aging_offset
. - Select the function of the INT/SQW output pin. See
use_int_sqw_output_as_interrupt
. - Alarms:
- Set alarms 1 and 2 with several matching policies. See
set_alarm1_day
. - Set alarms 1 and 2 for a time. See
set_alarm1_hms
. - Read whether alarms 1 or 2 have matched. See
has_alarm1_matched
. - Clear flag indicating that alarms 1 or 2 have matched. See
clear_alarm1_matched_flag
. - Enable and disable alarms 1 and 2 interrupt generation. See
enable_alarm1_interrupts
.
- Set alarms 1 and 2 with several matching policies. See
- Wave generation:
- Enable and disable the square-wave generation. See
enable_square_wave
. - Select the square-wave frequency. See
set_square_wave_frequency
. - Enable and disable the 32kHz output. See
enable_32khz_output
. - Enable and disable the 32kHz output when battery powered. See
enable_32khz_output_on_battery
.
- Enable and disable the square-wave generation. See
- Temperature conversion:
- Read the temperature. See
temperature
. - Force a temperature conversion and time compensation. See
convert_temperature
. - Set the temperature conversion rate. See
set_temperature_conversion_rate
. - Enable and disable the temperature conversions when battery-powered. See
enable_temperature_conversions_on_battery
.
- Read the temperature. See
§The devices
This driver is compatible with the DS3231 and DS3232 I2C devices and the DS3234 SPI device.
These devices are low-cost temperature-compensated crystal oscillator (TCXO) with a very accurate, temperature-compensated, integrated real-time clock (RTC) including 236/256 bytes of battery-backed SRAM, depending on the model.
§DS3231 and DS3232 details
The devices incorporate a battery input, and maintain accurate timekeeping when main power to the devices is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the devices as well as reduces the piece-part count in a manufacturing line. The devices are available in commercial and industrial temperature ranges, and are offered in a 16-pin, 300-mil SO package.
The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with an AM/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially through an I2C bidirectional bus.
A precision temperature-compensated voltage reference and comparator circuit monitors the status of VCC to detect power failures, to provide a reset output, and to automatically switch to the backup supply when necessary. Additionally, the RST pin is monitored as a pushbutton input for generating a μP reset.
§DS3234 details
The DS3234 incorporates a precision, temperature-compensated voltage reference and comparator circuit to monitor VCC. When VCC drops below the power-fail voltage (VPF), the device asserts the RST output and also disables read and write access to the part when VCC drops below both VPF and VBAT. The RST pin is monitored as a pushbutton input for generating a μP reset. The device switches to the backup supply input and maintains accurate timekeeping when main power to the device is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line. The DS3234 is available in commercial and industrial temperature ranges, and is offered in an industry-standard 300-mil, 20-pin SO package.
The DS3234 also integrates 256 bytes of battery-backed SRAM. In the event of main power loss, the contents of the memory are maintained by the power source connected to the V BAT pin. The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with AM/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially by an SPI bidirectional bus.
Datasheets:
§Usage examples (see also examples folder)
To use this driver, import this crate and an embedded_hal
implementation,
then instantiate the appropriate device.
In the following 3 examples an instance of the devices DS3231, DS3232 and
DS3234 will be created as an example. The rest of examples will use the
DS3231 as an example, except when using features specific to another IC,
for example, RAM access which is not available in the DS3231 device.
Please find additional examples using hardware in this repository: driver-examples
§Create a driver instance for the DS3231
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let rtc = Ds323x::new_ds3231(dev);
// do something...
// get the I2C device back
let dev = rtc.destroy_ds3231();
§Create a driver instance for the DS3232
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let rtc = Ds323x::new_ds3232(dev);
// do something...
// get the I2C device back
let dev = rtc.destroy_ds3232();
§Create a driver instance for the DS3234
use ds323x::Ds323x;
use embedded_hal_bus::spi::ExclusiveDevice;
use linux_embedded_hal::{Delay, SpidevBus, SysfsPin};
let spi = SpidevBus::open("/dev/spidev0.0").unwrap();
let chip_select = SysfsPin::new(25);
let dev = ExclusiveDevice::new(spi, chip_select, Delay).unwrap();
let rtc = Ds323x::new_ds3234(dev);
// do something...
// get the SPI device back
let dev = rtc.destroy_ds3234();
§Set the current date and time at once
use ds323x::{Ds323x, NaiveDate, DateTimeAccess};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let datetime = NaiveDate::from_ymd(2020, 5, 1).and_hms(19, 59, 58);
rtc.set_datetime(&datetime).unwrap();
§Get the current date and time at once
use ds323x::{Ds323x, DateTimeAccess};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let dt = rtc.datetime().unwrap();
println!("{}", dt);
// This will print something like: 2020-05-01 19:59:58
§Get the year
Similar methods exist for month, day, weekday, hours, minutes and seconds.
use ds323x::{Ds323x, Rtcc};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let year = rtc.year().unwrap();
println!("Year: {}", year);
§Set the year
Similar methods exist for month, day, weekday, hours, minutes and seconds.
use ds323x::{Ds323x, Rtcc};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
rtc.set_year(2018).unwrap();
§Enable/disable the device
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
rtc.disable().unwrap(); // stops the clock
let running = rtc.running().unwrap();
println!("Is running: {}", running); // will print false
rtc.enable().unwrap(); // set clock to run
println!("Is running: {}", running); // will print true
§Read the temperature
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let temperature = rtc.temperature().unwrap();
§Read busy status
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let busy = rtc.busy().unwrap();
§Enable the square-wave output with a frequency of 4.096Hz
use ds323x::{Ds323x, SqWFreq};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
rtc.set_square_wave_frequency(SqWFreq::_4_096Hz).unwrap();
// The same output pin can be used for interrupts or as square-wave output
rtc.use_int_sqw_output_as_square_wave().unwrap();
rtc.enable_square_wave().unwrap();
§Enable the 32kHz output except when on battery power
Additionally enabling the output depending on the power source is only available for the devices DS3232 and DS3234.
use ds323x::{Ds323x, SqWFreq};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3232(dev);
rtc.disable_32khz_output_on_battery().unwrap(); // only available for DS3232 and DS3234
rtc.enable_32khz_output().unwrap();
§Set the aging offset
use ds323x::Ds323x;
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
rtc.set_aging_offset(-15).unwrap();
§Set the temperature conversion rate to once every 128 seconds
This is only available for the devices DS3232 and DS3234.
use ds323x::{Ds323x, TempConvRate};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3232(dev);
rtc.set_temperature_conversion_rate(TempConvRate::_128s).unwrap();
§Set the Alarm1 to each week on a week day at a specific time
use ds323x::{Ds323x, Hours, WeekdayAlarm1, Alarm1Matching};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let alarm1 = WeekdayAlarm1 {
weekday: 1,
hour: Hours::H24(7),
minute: 2,
second: 15
};
rtc.set_alarm1_weekday(alarm1, Alarm1Matching::AllMatch).unwrap();
§Set the Alarm2 to each day at the same time and enable interrupts on output
The INT/SQW output pin will be set to 1 when it the alarm matches.
use ds323x::{Ds323x, Hours, DayAlarm2, Alarm2Matching};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let alarm2 = DayAlarm2 {
day: 1, // does not matter given the chosen matching
hour: Hours::AM(11),
minute: 2
};
rtc.set_alarm2_day(alarm2, Alarm2Matching::HoursAndMinutesMatch).unwrap();
rtc.use_int_sqw_output_as_interrupt().unwrap();
rtc.enable_alarm2_interrupts().unwrap();
§Set the Alarm1 to a specific time
use ds323x::{Ds323x, Hours, NaiveTime};
use linux_embedded_hal::I2cdev;
let dev = I2cdev::new("/dev/i2c-1").unwrap();
let mut rtc = Ds323x::new_ds3231(dev);
let time = NaiveTime::from_hms(19, 59, 58);
rtc.set_alarm1_hms(time).unwrap();
Modules§
Structs§
- DayAlarm1
- Parameters for setting Alarm1 on a day of the month
- DayAlarm2
- Parameters for setting Alarm2 on a day of the month
- Ds323x
- DS3231, DS3232 and DS3234 RTC driver
- Naive
Date - ISO 8601 calendar date without timezone. Allows for every proleptic Gregorian date from Jan 1, 262145 BCE to Dec 31, 262143 CE. Also supports the conversion from ISO 8601 ordinal and week date.
- Naive
Date Time - ISO 8601 combined date and time without timezone.
- Naive
Time - ISO 8601 time without timezone. Allows for the nanosecond precision and optional leap second representation.
- Weekday
Alarm1 - Parameters for setting Alarm1 on a weekday
- Weekday
Alarm2 - Parameters for setting Alarm2 on a weekday
Enums§
- Alarm1
Matching - Alarm1 trigger rate
- Alarm2
Matching - Alarm2 trigger rate
- Error
- All possible errors in this crate
- Hours
- Hours in either 12-hour (AM/PM) or 24-hour format
- SqWFreq
- Square-wave output frequency
- Temp
Conv Rate - Temperature conversion rate
Constants§
- SPI_
MODE_ 1 - SPI mode 1 (CPOL = 0, CPHA = 1)
- SPI_
MODE_ 3 - SPI mode 3 (CPOL = 1, CPHA = 1)
Traits§
- Date
Time Access - Real-Time Clock / Calendar DateTimeAccess trait to read/write a complete date/time.
- Datelike
- The common set of methods for date component.
- Rtcc
- Real-Time Clock / Calendar trait
- Timelike
- The common set of methods for time component.