1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::consts::*;
use std::fmt;
use std::sync::atomic::{self, AtomicU8};
const OP_MODE_MSG_ID_MIN: u8 = 0x20;
const OP_MODE_MSG_ID_MAX: u8 = 0xBF;
static MSG_ID: AtomicU8 = AtomicU8::new(OP_MODE_MSG_ID_MIN);
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum CommandType {
CmdOp = 0x00,
CmdBramWrite = 0x01,
CmdReadCpuVerLsb = 0x02,
CmdReadCpuVerMsb = 0x03,
CmdReadFpgaVerLsb = 0x04,
CmdReadFpgaVerMsb = 0x05,
CmdReadModSyncBase = 0x06,
CmdShiftModSyncBase = 0x07,
CmdNegSyncFirstSync0 = 0x08,
}
#[repr(packed)]
pub struct RxGlobalHeader {
pub msg_id: u8,
pub ctrl_flag: RxGlobalControlFlags,
pub command: CommandType,
mod_size: u8,
pub mod_data: [u8; MOD_FRAME_SIZE],
}
bitflags! {
pub struct RxGlobalControlFlags : u8 {
const NONE = 0;
const LOOP_BEGIN = 1;
const LOOP_END = 1 << 1;
const SILENT = 1 << 3;
const FORCE_FAN = 1 << 4;
const IS_SYNC_FIRST_SYNC_N = 1 << 5;
const MOD_SYNC_BASE_SHIFT = 1 << 6;
}
}
impl RxGlobalHeader {
pub fn new(ctrl_flag: RxGlobalControlFlags, data: &[u8]) -> RxGlobalHeader {
MSG_ID.fetch_add(1, atomic::Ordering::SeqCst);
MSG_ID.compare_and_swap(
OP_MODE_MSG_ID_MAX + 1,
OP_MODE_MSG_ID_MIN,
atomic::Ordering::SeqCst,
);
let mut data_array = [0x00; MOD_FRAME_SIZE];
data_array[..data.len()].clone_from_slice(&data[..]);
RxGlobalHeader {
msg_id: MSG_ID.load(atomic::Ordering::SeqCst),
ctrl_flag,
command: CommandType::CmdOp,
mod_size: data.len() as u8,
mod_data: data_array,
}
}
}
impl fmt::Debug for RxGlobalHeader {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
r"RxGlobalHeader {{
msg_id: {},
ctrl_flag: {:?},
command: {:?},
mod_size: {},
mod_data: {:?},
}}",
self.msg_id,
self.ctrl_flag,
self.command,
self.mod_size,
&self.mod_data[..],
)
}
}