1mod word {
2 pub const VERICOMM_CLOCK_HIGH_DELAY: usize = 0;
3 pub const VERICOMM_CLOCK_LOW_DELAY: usize = 1;
4 pub const VERICOMM_MISC: usize = 2;
5 pub const MODE_AND_CHANNEL: usize = 3;
6 pub const FLASH_BEGIN_BLOCK: usize = 4;
7 pub const FLASH_BEGIN_CLUSTER: usize = 5;
8 pub const FLASH_READ_END_BLOCK: usize = 6;
9 pub const FLASH_READ_END_CLUSTER: usize = 7;
10 pub const LICENCE_AND_SECURITY_KEY: usize = 31;
11 pub const SMIMS_VERSION: usize = 32;
12 pub const FIFO_SIZE_WORDS: usize = 33;
13 pub const FLASH_TOTAL_BLOCK: usize = 34;
14 pub const FLASH_BLOCK_SIZE: usize = 35;
15 pub const FLASH_CLUSTER_SIZE: usize = 36;
16 pub const ABILITY_FLAGS: usize = 37;
17 pub const PROGRAM_STATE: usize = 48;
18 pub const CLOCK_STATE: usize = 49;
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct Config {
23 words: [u16; Self::WORD_COUNT],
24}
25
26impl Default for Config {
27 fn default() -> Self {
28 Self {
29 words: [0u16; Self::WORD_COUNT],
30 }
31 }
32}
33
34impl Config {
35 pub const WORD_COUNT: usize = 64;
36
37 pub fn new() -> Self {
38 Self::default()
39 }
40
41 pub fn from_words(words: [u16; Self::WORD_COUNT]) -> Self {
42 Self { words }
43 }
44
45 pub fn words(&self) -> &[u16; Self::WORD_COUNT] {
46 &self.words
47 }
48
49 pub fn vericomm_clock_high_delay(&self) -> u16 {
50 self.words[word::VERICOMM_CLOCK_HIGH_DELAY]
51 }
52
53 pub fn set_vericomm_clock_high_delay(&mut self, delay: u16) {
54 self.words[word::VERICOMM_CLOCK_HIGH_DELAY] = delay;
55 }
56
57 pub fn vericomm_clock_low_delay(&self) -> u16 {
58 self.words[word::VERICOMM_CLOCK_LOW_DELAY]
59 }
60
61 pub fn set_vericomm_clock_low_delay(&mut self, delay: u16) {
62 self.words[word::VERICOMM_CLOCK_LOW_DELAY] = delay;
63 }
64
65 pub fn vericomm_isv(&self) -> u8 {
66 ((self.words[word::VERICOMM_MISC] >> 4) & 0x000f) as u8
67 }
68
69 pub fn set_vericomm_isv(&mut self, value: u8) {
70 let value = (value & 0x0f) as u16;
71 let clock_check = self.words[word::VERICOMM_MISC] & 0x0001;
72 self.words[word::VERICOMM_MISC] = (value << 4) | clock_check;
73 }
74
75 pub fn vericomm_clock_check_enabled(&self) -> bool {
76 self.words[word::VERICOMM_MISC] & 0x0001 != 0
77 }
78
79 pub fn set_vericomm_clock_check_enabled(&mut self, enabled: bool) {
80 if enabled {
81 self.words[word::VERICOMM_MISC] |= 0x0001;
82 } else {
83 self.words[word::VERICOMM_MISC] &= !0x0001;
84 }
85 }
86
87 pub fn veri_sdk_channel_selector(&self) -> u8 {
88 (self.words[word::MODE_AND_CHANNEL] & 0x00ff) as u8
89 }
90
91 pub fn set_veri_sdk_channel_selector(&mut self, channel: u8) {
92 self.words[word::MODE_AND_CHANNEL] =
93 (self.words[word::MODE_AND_CHANNEL] & 0xff00) | channel as u16;
94 }
95
96 pub fn mode_selector(&self) -> u8 {
97 (self.words[word::MODE_AND_CHANNEL] >> 8) as u8
98 }
99
100 pub fn set_mode_selector(&mut self, mode: u8) {
101 self.words[word::MODE_AND_CHANNEL] =
102 (self.words[word::MODE_AND_CHANNEL] & 0x00ff) | ((mode as u16) << 8);
103 }
104
105 pub fn flash_begin_block_addr(&self) -> u16 {
106 self.words[word::FLASH_BEGIN_BLOCK]
107 }
108
109 pub fn set_flash_begin_block_addr(&mut self, addr: u16) {
110 self.words[word::FLASH_BEGIN_BLOCK] = addr;
111 }
112
113 pub fn flash_begin_cluster_addr(&self) -> u16 {
114 self.words[word::FLASH_BEGIN_CLUSTER]
115 }
116
117 pub fn set_flash_begin_cluster_addr(&mut self, addr: u16) {
118 self.words[word::FLASH_BEGIN_CLUSTER] = addr;
119 }
120
121 pub fn flash_read_end_block_addr(&self) -> u16 {
122 self.words[word::FLASH_READ_END_BLOCK]
123 }
124
125 pub fn set_flash_read_end_block_addr(&mut self, addr: u16) {
126 self.words[word::FLASH_READ_END_BLOCK] = addr;
127 }
128
129 pub fn flash_read_end_cluster_addr(&self) -> u16 {
130 self.words[word::FLASH_READ_END_CLUSTER]
131 }
132
133 pub fn set_flash_read_end_cluster_addr(&mut self, addr: u16) {
134 self.words[word::FLASH_READ_END_CLUSTER] = addr;
135 }
136
137 pub fn licence_key(&self) -> u16 {
138 self.words[word::LICENCE_AND_SECURITY_KEY]
139 }
140
141 pub fn security_key(&self) -> u16 {
144 self.words[word::LICENCE_AND_SECURITY_KEY]
145 }
146
147 pub fn set_licence_key(&mut self, key: u16) {
148 self.words[word::LICENCE_AND_SECURITY_KEY] = key;
149 }
150
151 pub fn smims_version_raw(&self) -> u16 {
152 self.words[word::SMIMS_VERSION]
153 }
154
155 pub fn smims_major_version(&self) -> u8 {
156 (self.words[word::SMIMS_VERSION] >> 8) as u8
157 }
158
159 pub fn smims_sub_version(&self) -> u8 {
160 ((self.words[word::SMIMS_VERSION] >> 4) & 0x000f) as u8
161 }
162
163 pub fn smims_patch_version(&self) -> u8 {
164 (self.words[word::SMIMS_VERSION] & 0x000f) as u8
165 }
166
167 pub fn fifo_size_words(&self) -> u16 {
172 self.words[word::FIFO_SIZE_WORDS]
173 }
174
175 pub fn fifo_size(&self) -> u16 {
177 self.fifo_size_words()
178 }
179
180 pub fn flash_total_block(&self) -> u16 {
181 self.words[word::FLASH_TOTAL_BLOCK]
182 }
183
184 pub fn flash_block_size(&self) -> u16 {
185 self.words[word::FLASH_BLOCK_SIZE]
186 }
187
188 pub fn flash_cluster_size(&self) -> u16 {
189 self.words[word::FLASH_CLUSTER_SIZE]
190 }
191
192 pub fn vericomm_ability(&self) -> bool {
193 self.has_state_flag(0x0001)
194 }
195
196 pub fn veri_instrument_ability(&self) -> bool {
197 self.has_state_flag(0x0002)
198 }
199
200 pub fn veri_link_ability(&self) -> bool {
201 self.has_state_flag(0x0004)
202 }
203
204 pub fn veri_soc_ability(&self) -> bool {
205 self.has_state_flag(0x0008)
206 }
207
208 pub fn vericomm_pro_ability(&self) -> bool {
209 self.has_state_flag(0x0010)
210 }
211
212 pub fn veri_sdk_ability(&self) -> bool {
213 self.has_state_flag(0x0100)
214 }
215
216 pub fn is_programmed(&self) -> bool {
217 self.words[word::PROGRAM_STATE] & 0x0001 != 0
218 }
219
220 pub fn is_pcb_connected(&self) -> bool {
221 self.words[word::PROGRAM_STATE] & 0x0100 == 0
222 }
223
224 pub fn vericomm_clock_continues(&self) -> bool {
225 self.words[word::CLOCK_STATE] & 0x0001 == 0
226 }
227
228 fn has_state_flag(&self, mask: u16) -> bool {
229 self.words[word::ABILITY_FLAGS] & mask != 0
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use super::Config;
236
237 #[test]
238 fn mode_and_channel_share_the_same_word_without_clobbering_each_other() {
239 let mut config = Config::new();
240 config.set_mode_selector(0x12);
241 config.set_veri_sdk_channel_selector(0x34);
242 assert_eq!(config.mode_selector(), 0x12);
243 assert_eq!(config.veri_sdk_channel_selector(), 0x34);
244 assert_eq!(config.words()[3], 0x1234);
245 }
246
247 #[test]
248 fn fifo_size_aliases_are_word_based() {
249 let mut words = [0u16; Config::WORD_COUNT];
250 words[33] = 512;
251 let config = Config::from_words(words);
252 assert_eq!(config.fifo_size(), 512);
253 assert_eq!(config.fifo_size_words(), 512);
254 }
255
256 #[test]
257 fn licence_and_security_key_share_the_same_backing_word() {
258 let mut config = Config::new();
259 config.set_licence_key(0x55aa);
260 assert_eq!(config.licence_key(), 0x55aa);
261 assert_eq!(config.security_key(), 0x55aa);
262 }
263}