113 lines
3.3 KiB
Rust
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(())
|
|
}
|
|
}
|