use bitflags::bitflags;
#[cfg(feature = "serde")]
use super::SerializeUbxPacketFields;
#[cfg(feature = "serde")]
use crate::serde::ser::SerializeMap;
use crate::{
error::ParserError, ubx_checksum, MemWriter, MemWriterError, UbxPacketCreator, UbxPacketMeta,
};
use ublox_derive::{ubx_extend, ubx_extend_bitflags, ubx_packet_recv_send};
#[ubx_packet_recv_send]
#[ubx(
class = 0x06,
id = 0x00,
fixed_payload_len = 20,
flags = "default_for_builder"
)]
struct CfgPrtI2c {
#[ubx(map_type = I2cPortId, may_fail)]
portid: u8,
reserved1: u8,
tx_ready: u16,
mode: u32,
reserved2: u32,
#[ubx(map_type = InProtoMask)]
in_proto_mask: u16,
#[ubx(map_type = OutProtoMask)]
out_proto_mask: u16,
flags: u16,
reserved3: u16,
}
#[derive(Default)]
#[ubx_extend]
#[ubx(from_unchecked, into_raw, rest_error)]
#[repr(u8)]
#[derive(Debug, Copy, Clone)]
pub enum I2cPortId {
#[default]
I2c = 0,
}
#[ubx_packet_recv_send]
#[ubx(class = 0x06, id = 0x00, fixed_payload_len = 20)]
struct CfgPrtUart {
#[ubx(map_type = UartPortId, may_fail)]
portid: u8,
reserved0: u8,
tx_ready: u16,
#[ubx(map_type = UartMode)]
mode: u32,
baud_rate: u32,
#[ubx(map_type = InProtoMask)]
in_proto_mask: u16,
#[ubx(map_type = OutProtoMask)]
out_proto_mask: u16,
flags: u16,
reserved5: u16,
}
#[ubx_extend]
#[ubx(from_unchecked, into_raw, rest_error)]
#[repr(u8)]
#[derive(Debug, Copy, Clone)]
pub enum UartPortId {
Uart1 = 1,
Uart2 = 2,
Usb = 3,
}
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct UartMode {
data_bits: DataBits,
parity: Parity,
stop_bits: StopBits,
}
impl UartMode {
pub const fn new(data_bits: DataBits, parity: Parity, stop_bits: StopBits) -> Self {
Self {
data_bits,
parity,
stop_bits,
}
}
const fn into_raw(self) -> u32 {
self.data_bits.into_raw() | self.parity.into_raw() | self.stop_bits.into_raw()
}
}
impl From<u32> for UartMode {
fn from(mode: u32) -> Self {
let data_bits = DataBits::from(mode);
let parity = Parity::from(mode);
let stop_bits = StopBits::from(mode);
Self {
data_bits,
parity,
stop_bits,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum DataBits {
Seven,
Eight,
}
impl DataBits {
const POSITION: u32 = 6;
const MASK: u32 = 0b11;
const fn into_raw(self) -> u32 {
(match self {
Self::Seven => 0b10,
Self::Eight => 0b11,
}) << Self::POSITION
}
}
impl From<u32> for DataBits {
fn from(mode: u32) -> Self {
match (mode >> Self::POSITION) & Self::MASK {
0b00 => unimplemented!("five data bits not supported by u-blox protocol specification"),
0b01 => unimplemented!("six data bits not supported by u-blox protocol specification"),
0b10 => Self::Seven,
0b11 => Self::Eight,
_ => unreachable!("DataBits value not supported by protocol specification"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Parity {
Even,
Odd,
None,
}
impl Parity {
const POSITION: u32 = 9;
const MASK: u32 = 0b111;
const fn into_raw(self) -> u32 {
(match self {
Self::Even => 0b000,
Self::Odd => 0b001,
Self::None => 0b100,
}) << Self::POSITION
}
}
impl From<u32> for Parity {
fn from(mode: u32) -> Self {
match (mode >> Self::POSITION) & Self::MASK {
0b000 => Self::Even,
0b001 => Self::Odd,
0b100 | 0b101 => Self::None,
0b010 | 0b011 | 0b110 | 0b111 => unimplemented!("reserved"),
_ => unreachable!("Parity value not supported by protocol specification"),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum StopBits {
One,
OneHalf,
Two,
Half,
}
impl StopBits {
const POSITION: u32 = 12;
const MASK: u32 = 0b11;
const fn into_raw(self) -> u32 {
(match self {
Self::One => 0b00,
Self::OneHalf => 0b01,
Self::Two => 0b10,
Self::Half => 0b11,
}) << Self::POSITION
}
}
impl From<u32> for StopBits {
fn from(mode: u32) -> Self {
match (mode >> Self::POSITION) & Self::MASK {
0b00 => Self::One,
0b01 => Self::OneHalf,
0b10 => Self::Two,
0b11 => Self::Half,
_ => unreachable!("StopBits value not supported by protocol specification"),
}
}
}
#[ubx_packet_recv_send]
#[ubx(
class = 0x06,
id = 0x00,
fixed_payload_len = 20,
flags = "default_for_builder"
)]
struct CfgPrtSpi {
#[ubx(map_type = SpiPortId, may_fail)]
portid: u8,
reserved0: u8,
tx_ready: u16,
mode: u32,
reserved3: u32,
#[ubx(map_type = InProtoMask)]
in_proto_mask: u16,
#[ubx(map_type = OutProtoMask)]
out_proto_mask: u16,
flags: u16,
reserved5: u16,
}
#[ubx_extend_bitflags]
#[ubx(from, into_raw, rest_reserved)]
bitflags! {
#[derive(Default, Debug, Clone, Copy)]
pub struct InProtoMask: u16 {
const UBLOX = 1;
const NMEA = 2;
const RTCM = 4;
const RTCM3 = 0x20;
}
}
#[ubx_extend_bitflags]
#[ubx(from, into_raw, rest_reserved)]
bitflags! {
#[derive(Default, Debug, Clone, Copy)]
pub struct OutProtoMask: u16 {
const UBLOX = 1;
const NMEA = 2;
const RTCM3 = 0x20;
}
}
#[derive(Default)]
#[ubx_extend]
#[ubx(from_unchecked, into_raw, rest_error)]
#[repr(u8)]
#[derive(Debug, Copy, Clone)]
pub enum SpiPortId {
#[default]
Spi = 4,
}