Files
neowatch/src/rn4020/mod.rs

113 lines
3.3 KiB
Rust

use core::fmt::Write;
use hal::{
clock::Sercom0CoreClock,
//target_device::{NVIC, PM, SERCOM0},
pac::{PM, SERCOM0},
sercom::{RxpoTxpo, UART0Padout, UART0},
time::Hertz,
//prelude::_embedded_hal_serial_Read as Read,
//prelude::_embedded_hal_serial_Write as WriteHal,
};
#[allow(dead_code)]
#[derive(Clone, Copy)]
pub enum BaudRate {
BR2400,
BR9600,
BR19200,
BR38400,
BR115200,
BR230400,
BR460800,
BR921600,
}
impl Into<Hertz> for BaudRate {
fn into(self) -> Hertz {
match self {
BaudRate::BR2400 => Hertz(2400),
BaudRate::BR9600 => Hertz(9600),
BaudRate::BR19200 => Hertz(19200),
BaudRate::BR38400 => Hertz(38400),
BaudRate::BR115200 => Hertz(115200),
BaudRate::BR230400 => Hertz(230400),
BaudRate::BR460800 => Hertz(460800),
BaudRate::BR921600 => Hertz(921600),
}
}
}
pub struct RN4020<RX, TX> {
/// The reader/writer to the RN4020
link: UART0<RX, TX, (), ()>,
}
impl<RX, TX> RN4020<RX, TX> {
/// Create a new
pub fn new<T>(
clock: &Sercom0CoreClock,
baud_rate: BaudRate,
sercom: SERCOM0,
pm: &mut PM,
padout: T,
) -> Self
where
T: Into<UART0Padout<RX, TX, (), ()>>,
UART0Padout<RX, TX, (), ()>: RxpoTxpo,
{
let mut bl = RN4020 {
link: UART0::new(clock, baud_rate, sercom, pm, padout),
};
bl.set_baud_rate(baud_rate).unwrap();
bl
}
/// This command sets the serialized Bluetooth-friendly name of the device.
///
/// `name` is up to 15 alphanumeric characters.
/// This command automatically appends the last 2 bytes of the Bluetooth MAC
/// address to the name, which is useful for generating a custom name
/// with unique numbering.
///
/// Will panic if provided with an invalid string.
#[allow(dead_code)]
pub fn set_serialized_name(&mut self, name: &str) -> Result<(), ()> {
assert!(name.len() <= 15);
assert!(name.is_ascii());
self.link.write_str("S-,").map_err(|_| ())?;
for c in name.chars() {
assert!(c.is_alphanumeric());
self.link.write_char(c).map_err(|_| ())?;
}
self.link.write_char('\n').map_err(|_| ())?;
Ok(())
}
/// This command sets the baud rate of the UART communication.
fn set_baud_rate(&mut self, rate: BaudRate) -> Result<(), ()> {
// The input parameter is a single digit number in the range of 0 to 7,
// representing a baud rate from 2400 to 921K, as shown in Table 2 - 5.
// When the baud rate is set to 2400, there is no need to wake the
// RN4020 module by pulling WAKE_SW high for UART communication.
// TODO: Figure out how to change UART settings and make this method public
let cmd = match rate {
BaudRate::BR2400 => "SB,0\n",
BaudRate::BR9600 => "SB,1\n",
BaudRate::BR19200 => "SB,2\n",
BaudRate::BR38400 => "SB,3\n",
BaudRate::BR115200 => "SB,4\n",
BaudRate::BR230400 => "SB,5\n",
BaudRate::BR460800 => "SB,6\n",
BaudRate::BR921600 => "SB,7\n",
};
self.link.write_str(cmd).map_err(|_| ())?;
Ok(())
}
}