 have fascists on one side and communists on the other. This is not more hyperbole from me. There are pictures of the red and gold flags from the Soviet Union being bandied about at the protests. While we’re not at the ‘running gun battles in the streets’ level of violence, but these protests are getting rather hairy on average. There’s been at least one notable death and several injuries. I don’t see it calming down any time in the future.
What of the economy? Oy vey…while the Chinese trade war isn’t doing us any favors, we’re not in a recession…yet. From what I’ve glanced at, 2020 could be the year that kicks off a recession, and that might give other interested people the impetus needed to toss their hat in the ring. While we’re not having to pay the murderous reparations that Germany had to do, which was a contributing factor to the rise of the Nazi party, but our national debt continues to soar with no end in sight. Unless the Trump administration does something soon, I don’t think his chances of retaining the Presidency will be very high.
So – what do we do? How can we put our time and knowledge to work for us, rather than waiting what seems to be the inevitable?
For Jesus’ sake – everyone needs to take a step back and breathe. While I don’t believe that most of the foment is engineered by those in power on either side of the aisle, I certainly am sure that no one is letting this crisis go to waste. I think it’s the ones who are very vocal and easily agitated who are steering the national conversations right for the icebergs. Facebook, news media and political organizations on both left and right are profiting from these fights with either cash or attention (which they can turn into cash). The more wound up we are, the less likely we’re going to examine the situation more critically.
Are we doomed? No. We have a lot of hindsight and history to guide us if we choose to examine it. I would like to think that at some point, we as a nation are going to step back from the brink.
<gh_stars>10-100
//! I2C [`Config`] definition and implementation

use super::{I2c, InactiveTimeout, PadSet, Registers};
use crate::{
    pac::sercom0::i2cm::ctrla::MODE_A,
    sercom::*,
    time::Hertz,
    typelevel::{Is, Sealed},
};

//=============================================================================
// Config
//=============================================================================

/// A configurable, disabled I2C peripheral
///
/// This `struct` represents a configurable I2C peripheral in its disabled
/// state. It is generic over the set of [`Pads`].
/// Upon creation, the [`Config`] takes ownership of the
/// [`Sercom`] and resets it, returning it configured as an I2C peripheral
/// with a default configuration in Master mode.
///
/// [`Config`] uses a builder-pattern API to configure the peripheral,
/// culminating in a call to [`enable`], which consumes the [`Config`] and
/// returns an enabled [`I2c`].
///
/// [`enable`]: Config::enable
/// [`Pads`]: super::Pads
pub struct Config<P>
where
    P: PadSet,
{
    pub(super) registers: Registers<P::Sercom>,
    pads: P,
    freq: Hertz,
}

impl<P: PadSet> Config<P> {
    /// Create a new [`Config`] in the default configuration.
    #[inline]
    fn default(sercom: P::Sercom, pads: P, freq: impl Into<Hertz>) -> Self {
        let mut registers = Registers::new(sercom);
        registers.swrst();
        registers.set_op_mode(MODE_A::I2C_MASTER);
        Self {
            registers,
            pads,
            freq: freq.into(),
        }
    }

    /// Create a new [`Config`] in the default configuration
    ///
    /// This function will enable the corresponding APB clock, reset the
    /// [`Sercom`] peripheral, and return a [`Config`] in the default
    /// configuration. The only available operating mode is currently Master.
    ///
    /// Note that [`Config`] takes ownership of both the
    /// PAC [`Sercom`] struct as well as the [`Pads`](super::Pads).
    ///
    /// Users must configure GCLK manually. The `freq` parameter represents the
    /// GCLK frequency for this [`Sercom`] instance.
    #[inline]
    pub fn new(
        apb_clk_ctrl: &APB_CLK_CTRL,
        mut sercom: P::Sercom,
        pads: P,
        freq: impl Into<Hertz>,
    ) -> Self {
        sercom.enable_apb_clock(apb_clk_ctrl);
        Self::default(sercom, pads, freq)
    }
}

impl<P: PadSet> Config<P> {
    /// Obtain a reference to the PAC `SERCOM` struct
    ///
    /// # Safety
    ///
    /// Directly accessing the `SERCOM` could break the invariants of the
    /// type-level tracking in this module, so it is unsafe.
    #[inline]
    pub unsafe fn sercom(&self) -> &P::Sercom {
        &self.registers.sercom
    }

    /// Trigger the [`Sercom`]'s SWRST and return a [`Config`] in the
    /// default configuration.
    #[inline]
    pub fn reset(self) -> Config<P> {
        Config::default(self.registers.sercom, self.pads, self.freq)
    }

    /// Consume the [`Config`], reset the peripheral, and return the [`Sercom`]
    /// and [`Pads`](super::Pads)
    #[inline]
    pub fn free(mut self) -> (P::Sercom, P) {
        self.registers.swrst();
        (self.registers.free(), self.pads)
    }

    /// Run in standby mode (builder pattern version)
    ///
    /// When set, the I2C peripheral will run in standby mode. See the
    /// datasheet for more details.
    #[inline]
    pub fn run_in_standby(mut self, set: bool) -> Self {
        self.set_run_in_standby(set);
        self
    }

    /// Run in standby mode (setter version)
    ///
    /// When set, the I2C peripheral will run in standby mode. See the
    /// datasheet for more details.
    #[inline]
    pub fn set_run_in_standby(&mut self, set: bool) {
        self.registers.set_run_in_standby(set);
    }

    /// Get the current run in standby mode
    #[inline]
    pub fn get_run_in_standby(&self) -> bool {
        self.registers.get_run_in_standby()
    }

    /// Set the baud rate (builder pattern version)
    ///
    /// This function will calculate the best BAUD register setting based on the
    /// stored GCLK frequency and desired baud rate. The maximum baud rate is
    /// GCLK frequency/10. Values outside this range will saturate at
    /// the maximum supported baud rate.
    ///
    /// Note that 3x oversampling is not supported.
    #[inline]
    pub fn baud(mut self, baud: impl Into<Hertz>) -> Self {
        self.set_baud(baud);
        self
    }

    /// Set the baud rate (setter version)
    ///
    /// This function will calculate the best BAUD register setting based on the
    /// stored GCLK frequency and desired baud rate. The maximum baud rate is
    /// GCLK frequency/10. Values outside this range will saturate at
    /// the maximum supported baud rate.
    #[inline]
    pub fn set_baud(&mut self, baud: impl Into<Hertz>) {
        self.registers.set_baud(self.freq, baud);
    }

    /// Get the contents of the `BAUD` register and the current baud mode. Note
    /// that only the CONTENTS of `BAUD` are returned, and not the actual baud
    /// rate. Refer to the datasheet to convert the `BAUD` register contents
    /// into a baud rate.
    #[inline]
    pub fn get_baud(&self) -> u32 {
        self.