Skip to content

Instantly share code, notes, and snippets.

@djmcgill
Created March 9, 2017 13:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save djmcgill/91556f58d1aedff2adc7428a6443aac2 to your computer and use it in GitHub Desktop.
Save djmcgill/91556f58d1aedff2adc7428a6443aac2 to your computer and use it in GitHub Desktop.
Interesting Rust matching pattern
pub struct RtcMode2 {
pub CTRL: ReadWrite<u16>, // Offset: 0x00 (R/W 16) MODE2 Control
pub READREQ: ReadWrite<u16>, // Offset: 0x02 (R/W 16) Read Request
pub EVCTRL: ReadWrite<u16>, // Offset: 0x04 (R/W 16) MODE2 Event Control
pub INTENCLR: ReadWrite<u8>, // Offset: 0x06 (R/W 8) MODE2 Interrupt Enable Clear
pub INTENSET: ReadWrite<u8>, // Offset: 0x07 (R/W 8) MODE2 Interrupt Enable Set
pub INTFLAG: ReadWrite<u8>, // Offset: 0x08 (R/W 8) MODE2 Interrupt Flag Status and Clear
_reserved1: u8,
pub STATUS: ReadWrite<u8>, // Offset: 0x0A (R/W 8) Status
pub DBGCTRL: ReadWrite<u8>, // Offset: 0x0B (R/W 8) Debug Control
pub FREQCORR: ReadWrite<u8>, // Offset: 0x0C (R/W 8) Frequency Correction
_reserved2: [u8; 3],
pub CLOCK: ReadWrite<u32>, // Offset: 0x10 (R/W 32) MODE2 Clock Value
_reserved3: [u8; 4],
pub ALARM: ReadWrite<u32>, // Offset: 0x18 (R/W 32) MODE2_ALARM Alarm n Value
pub MASK: ReadWrite<u8>, // Offset: 0x22 (R/W 8) MODE2_ALARM Alarm n Mask
_reserved4: [u8; 3],
private: PhantomData<()>, // This type cannot be constructed.
}
impl RtcMode2 {
pub fn set_alarm(&mut self, alarm: RtcMode2Alarm) {
use self::RtcMode2Alarm::*;
if let OFF = alarm {
self.MASK.write(RTC_MODE2_MASK_SEL_OFF_VAL);
self.wait_for_sync();
return;
};
let mut bits = 0u32;
match alarm {
SS { second } |
MMSS { second, .. } |
HHMMSS { second, .. } |
DHHMMSS { second, .. } |
MMDDHHMMSS { second, .. } |
YYMMDDHHMMSS { second, .. } => {
if second >= (1 << 6) { panic!("{:?} is too large, maximum 6 bits", second); }
bits |= second as u32;
},
_ => {}
}
match alarm {
MMSS { minute, .. } |
HHMMSS { minute, .. } |
DHHMMSS { minute, .. } |
MMDDHHMMSS { minute, .. } |
YYMMDDHHMMSS { minute, .. } => {
if minute >= (1 << 6) { panic!("{:?} is too large, maximum 6 bits", minute); }
bits |= (minute as u32) << 6;
},
_ => {}
}
match alarm {
HHMMSS { hour, .. } |
DHHMMSS { hour, .. } |
MMDDHHMMSS { hour, .. } |
YYMMDDHHMMSS { hour, .. } => {
if hour >= (1 << 5) { panic!("{:?} is too large, maximum 5 bits", hour); }
bits |= (hour as u32) << 12;
},
_ => {}
}
match alarm {
DHHMMSS { day, .. } |
MMDDHHMMSS { day, .. } |
YYMMDDHHMMSS { day, .. } => {
if day >= (1 << 5) { panic!("{:?} is too large, maximum 5 bits", day); }
bits |= (day as u32) << 17;
},
_ => {}
}
match alarm {
MMDDHHMMSS { month, .. } |
YYMMDDHHMMSS { month, .. } => {
if month >= (1 << 4) { panic!("{:?} is too large, maximum 4 bits", month); }
bits |= (month as u32) << 22;
},
_ => {}
}
match alarm {
YYMMDDHHMMSS { year, .. } => {
if year >= (1 << 6) { panic!("{:?} is too large, maximum 6 bits", year); }
bits |= (year as u32) << 26;
},
_ => {}
}
self.ALARM.write(bits);
self.wait_for_sync();
let mask_val: u8 = match alarm {
SS {..} => RTC_MODE2_MASK_SEL_SS_VAL,
MMSS {..} => RTC_MODE2_MASK_SEL_MMSS_VAL,
HHMMSS {..} => RTC_MODE2_MASK_SEL_HHMMSS_VAL,
DHHMMSS {..} => RTC_MODE2_MASK_SEL_DDHHMMSS_VAL,
MMDDHHMMSS {..} => RTC_MODE2_MASK_SEL_MMDDHHMMSS_VAL,
YYMMDDHHMMSS {..} => RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_VAL,
OFF => unreachable!(),
};
self.MASK.write(mask_val);
self.wait_for_sync();
}
}
pub enum RtcMode2Alarm {
OFF, // Never
SS { // Every Minute
second: u8
},
MMSS { // Every Hour
minute: u8, second: u8
},
HHMMSS { // Every Day
hour: u8, minute: u8, second: u8
},
DHHMMSS { // Every Month
day: u8,
hour: u8, minute: u8, second: u8
},
MMDDHHMMSS { // Every Year
month: u8, day: u8,
hour: u8, minute: u8, second: u8
},
YYMMDDHHMMSS { // Once, on a specific date and a specific time
year: u8, month: u8, day: u8,
hour: u8, minute: u8, second: u8
},
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment