diff options
Diffstat (limited to 'embassy-mcxa/src/crc.rs')
| -rw-r--r-- | embassy-mcxa/src/crc.rs | 758 |
1 files changed, 758 insertions, 0 deletions
diff --git a/embassy-mcxa/src/crc.rs b/embassy-mcxa/src/crc.rs new file mode 100644 index 000000000..753a59122 --- /dev/null +++ b/embassy-mcxa/src/crc.rs | |||
| @@ -0,0 +1,758 @@ | |||
| 1 | //! Cyclic Redundancy Check (CRC) | ||
| 2 | |||
| 3 | use core::marker::PhantomData; | ||
| 4 | |||
| 5 | use embassy_hal_internal::Peri; | ||
| 6 | use mcxa_pac::crc0::ctrl::{Fxor, Tcrc, Tot, Totr}; | ||
| 7 | |||
| 8 | use crate::clocks::enable_and_reset; | ||
| 9 | use crate::clocks::periph_helpers::NoConfig; | ||
| 10 | use crate::peripherals::CRC0; | ||
| 11 | |||
| 12 | /// CRC driver. | ||
| 13 | pub struct Crc<'d, M> { | ||
| 14 | _peri: Peri<'d, CRC0>, | ||
| 15 | _phantom: PhantomData<M>, | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<'d, M: Mode> Crc<'d, M> { | ||
| 19 | fn new_inner(_peri: Peri<'d, CRC0>) -> Self { | ||
| 20 | _ = unsafe { enable_and_reset::<CRC0>(&NoConfig) }; | ||
| 21 | |||
| 22 | Crc { | ||
| 23 | _peri, | ||
| 24 | _phantom: PhantomData, | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | // Configure the underlying peripheral according to the reference manual. | ||
| 29 | fn configure(config: Config, width: Tcrc) { | ||
| 30 | Self::regs().ctrl().modify(|_, w| { | ||
| 31 | w.fxor() | ||
| 32 | .variant(config.complement_out.into()) | ||
| 33 | .totr() | ||
| 34 | .variant(config.reflect_out.into()) | ||
| 35 | .tot() | ||
| 36 | .variant(config.reflect_in.into()) | ||
| 37 | .was() | ||
| 38 | .data() | ||
| 39 | .tcrc() | ||
| 40 | .variant(width) | ||
| 41 | }); | ||
| 42 | |||
| 43 | Self::regs().gpoly32().write(|w| unsafe { w.bits(config.polynomial) }); | ||
| 44 | |||
| 45 | Self::regs().ctrl().modify(|_, w| w.was().seed()); | ||
| 46 | Self::regs().data32().write(|w| unsafe { w.bits(config.seed) }); | ||
| 47 | Self::regs().ctrl().modify(|_, w| w.was().data()); | ||
| 48 | } | ||
| 49 | |||
| 50 | fn regs() -> &'static crate::pac::crc0::RegisterBlock { | ||
| 51 | unsafe { &*crate::pac::Crc0::ptr() } | ||
| 52 | } | ||
| 53 | |||
| 54 | /// Read the computed CRC value | ||
| 55 | fn finalize_inner<W: Word>(self) -> W { | ||
| 56 | // Reference manual states: | ||
| 57 | // | ||
| 58 | // "After writing all the data, you must wait for at least two | ||
| 59 | // clock cycles to read the data from CRC Data (DATA) | ||
| 60 | // register." | ||
| 61 | cortex_m::asm::delay(2); | ||
| 62 | W::read(Self::regs()) | ||
| 63 | } | ||
| 64 | |||
| 65 | fn feed_word<W: Word>(&mut self, word: W) { | ||
| 66 | W::write(Self::regs(), word); | ||
| 67 | } | ||
| 68 | |||
| 69 | /// Feeds a slice of `Word`s into the CRC peripheral. Returns the computed | ||
| 70 | /// checksum. | ||
| 71 | /// | ||
| 72 | /// The input is strided efficiently into as many `u32`s as possible, | ||
| 73 | /// falling back to smaller writes for the remainder. | ||
| 74 | fn feed_inner<W: Word>(&mut self, data: &[W]) { | ||
| 75 | let (prefix, aligned, suffix) = unsafe { data.align_to::<u32>() }; | ||
| 76 | |||
| 77 | for w in prefix { | ||
| 78 | self.feed_word(*w); | ||
| 79 | } | ||
| 80 | |||
| 81 | for w in aligned { | ||
| 82 | self.feed_word(*w); | ||
| 83 | } | ||
| 84 | |||
| 85 | for w in suffix { | ||
| 86 | self.feed_word(*w); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | impl<'d> Crc<'d, Crc16> { | ||
| 92 | /// Instantiates a new CRC peripheral driver in 16-bit mode | ||
| 93 | pub fn new_crc16(peri: Peri<'d, CRC0>, config: Config) -> Self { | ||
| 94 | let inst = Self::new_inner(peri); | ||
| 95 | Self::configure(config, Tcrc::B16); | ||
| 96 | inst | ||
| 97 | } | ||
| 98 | |||
| 99 | /// Instantiates a new CRC peripheral driver for the given `Algorithm16`. | ||
| 100 | pub fn new_algorithm16(peri: Peri<'d, CRC0>, algorithm: Algorithm16) -> Self { | ||
| 101 | Self::new_crc16(peri, algorithm.into_config()) | ||
| 102 | } | ||
| 103 | |||
| 104 | /// Instantiates a new CRC peripheral for the `A` algorithm. | ||
| 105 | pub fn new_a(peri: Peri<'d, CRC0>) -> Self { | ||
| 106 | Self::new_algorithm16(peri, Algorithm16::A) | ||
| 107 | } | ||
| 108 | |||
| 109 | /// Instantiates a new CRC peripheral for the `AugCcitt` algorithm. | ||
| 110 | pub fn new_aug_ccitt(peri: Peri<'d, CRC0>) -> Self { | ||
| 111 | Self::new_algorithm16(peri, Algorithm16::AugCcitt) | ||
| 112 | } | ||
| 113 | |||
| 114 | /// Instantiates a new CRC peripheral for the `Arc` algorithm. | ||
| 115 | pub fn new_arc(peri: Peri<'d, CRC0>) -> Self { | ||
| 116 | Self::new_algorithm16(peri, Algorithm16::Arc) | ||
| 117 | } | ||
| 118 | |||
| 119 | /// Instantiates a new CRC peripheral for the `Buypass` algorithm. | ||
| 120 | pub fn new_buypass(peri: Peri<'d, CRC0>) -> Self { | ||
| 121 | Self::new_algorithm16(peri, Algorithm16::Buypass) | ||
| 122 | } | ||
| 123 | |||
| 124 | /// Instantiates a new CRC peripheral for the `CcittFalse` algorithm. | ||
| 125 | pub fn new_ccitt_false(peri: Peri<'d, CRC0>) -> Self { | ||
| 126 | Self::new_algorithm16(peri, Algorithm16::CcittFalse) | ||
| 127 | } | ||
| 128 | |||
| 129 | /// Instantiates a new CRC peripheral for the `CcittZero` algorithm. | ||
| 130 | pub fn new_ccitt_zero(peri: Peri<'d, CRC0>) -> Self { | ||
| 131 | Self::new_algorithm16(peri, Algorithm16::CcittZero) | ||
| 132 | } | ||
| 133 | |||
| 134 | /// Instantiates a new CRC peripheral for the `Cdma2000` algorithm. | ||
| 135 | pub fn new_cdma_2000(peri: Peri<'d, CRC0>) -> Self { | ||
| 136 | Self::new_algorithm16(peri, Algorithm16::Cdma2000) | ||
| 137 | } | ||
| 138 | |||
| 139 | /// Instantiates a new CRC peripheral for the `Dds110` algorithm. | ||
| 140 | pub fn new_dds_110(peri: Peri<'d, CRC0>) -> Self { | ||
| 141 | Self::new_algorithm16(peri, Algorithm16::Dds110) | ||
| 142 | } | ||
| 143 | |||
| 144 | /// Instantiates a new CRC peripheral for the `DectX` algorithm. | ||
| 145 | pub fn new_dect_x(peri: Peri<'d, CRC0>) -> Self { | ||
| 146 | Self::new_algorithm16(peri, Algorithm16::DectX) | ||
| 147 | } | ||
| 148 | |||
| 149 | /// Instantiates a new CRC peripheral for the `Dnp` algorithm. | ||
| 150 | pub fn new_dnp(peri: Peri<'d, CRC0>) -> Self { | ||
| 151 | Self::new_algorithm16(peri, Algorithm16::Dnp) | ||
| 152 | } | ||
| 153 | |||
| 154 | /// Instantiates a new CRC peripheral for the `En13757` algorithm. | ||
| 155 | pub fn new_en13757(peri: Peri<'d, CRC0>) -> Self { | ||
| 156 | Self::new_algorithm16(peri, Algorithm16::En13757) | ||
| 157 | } | ||
| 158 | |||
| 159 | /// Instantiates a new CRC peripheral for the `Genibus` algorithm. | ||
| 160 | pub fn new_genibus(peri: Peri<'d, CRC0>) -> Self { | ||
| 161 | Self::new_algorithm16(peri, Algorithm16::Genibus) | ||
| 162 | } | ||
| 163 | |||
| 164 | /// Instantiates a new CRC peripheral for the `Kermit` algorithm. | ||
| 165 | pub fn new_kermit(peri: Peri<'d, CRC0>) -> Self { | ||
| 166 | Self::new_algorithm16(peri, Algorithm16::Kermit) | ||
| 167 | } | ||
| 168 | |||
| 169 | /// Instantiates a new CRC peripheral for the `Maxim` algorithm. | ||
| 170 | pub fn new_maxim(peri: Peri<'d, CRC0>) -> Self { | ||
| 171 | Self::new_algorithm16(peri, Algorithm16::Maxim) | ||
| 172 | } | ||
| 173 | |||
| 174 | /// Instantiates a new CRC peripheral for the `Mcrf4xx` algorithm. | ||
| 175 | pub fn new_mcrf4xx(peri: Peri<'d, CRC0>) -> Self { | ||
| 176 | Self::new_algorithm16(peri, Algorithm16::Mcrf4xx) | ||
| 177 | } | ||
| 178 | |||
| 179 | /// Instantiates a new CRC peripheral for the `Modbus` algorithm. | ||
| 180 | pub fn new_modbus(peri: Peri<'d, CRC0>) -> Self { | ||
| 181 | Self::new_algorithm16(peri, Algorithm16::Modbus) | ||
| 182 | } | ||
| 183 | |||
| 184 | /// Instantiates a new CRC peripheral for the `Riello` algorithm. | ||
| 185 | pub fn new_riello(peri: Peri<'d, CRC0>) -> Self { | ||
| 186 | Self::new_algorithm16(peri, Algorithm16::Riello) | ||
| 187 | } | ||
| 188 | |||
| 189 | /// Instantiates a new CRC peripheral for the `T10Dif` algorithm. | ||
| 190 | pub fn new_t10_dif(peri: Peri<'d, CRC0>) -> Self { | ||
| 191 | Self::new_algorithm16(peri, Algorithm16::T10Dif) | ||
| 192 | } | ||
| 193 | |||
| 194 | /// Instantiates a new CRC peripheral for the `Teledisk` algorithm. | ||
| 195 | pub fn new_teledisk(peri: Peri<'d, CRC0>) -> Self { | ||
| 196 | Self::new_algorithm16(peri, Algorithm16::Teledisk) | ||
| 197 | } | ||
| 198 | |||
| 199 | /// Instantiates a new CRC peripheral for the `Tms37157` algorithm. | ||
| 200 | pub fn new_tms_37157(peri: Peri<'d, CRC0>) -> Self { | ||
| 201 | Self::new_algorithm16(peri, Algorithm16::Tms37157) | ||
| 202 | } | ||
| 203 | |||
| 204 | /// Instantiates a new CRC peripheral for the `Usb` algorithm. | ||
| 205 | pub fn new_usb(peri: Peri<'d, CRC0>) -> Self { | ||
| 206 | Self::new_algorithm16(peri, Algorithm16::Usb) | ||
| 207 | } | ||
| 208 | |||
| 209 | /// Instantiates a new CRC peripheral for the `X25` algorithm. | ||
| 210 | pub fn new_x25(peri: Peri<'d, CRC0>) -> Self { | ||
| 211 | Self::new_algorithm16(peri, Algorithm16::X25) | ||
| 212 | } | ||
| 213 | |||
| 214 | /// Instantiates a new CRC peripheral for the `Xmodem` algorithm. | ||
| 215 | pub fn new_xmodem(peri: Peri<'d, CRC0>) -> Self { | ||
| 216 | Self::new_algorithm16(peri, Algorithm16::Xmodem) | ||
| 217 | } | ||
| 218 | |||
| 219 | /// Feeds a slice of `Word`s into the CRC peripheral. | ||
| 220 | /// | ||
| 221 | /// The input is strided efficiently into as many `u32`s as possible, | ||
| 222 | /// falling back to smaller writes for the remainder. | ||
| 223 | pub fn feed<W: Word>(&mut self, data: &[W]) { | ||
| 224 | self.feed_inner(data); | ||
| 225 | } | ||
| 226 | |||
| 227 | /// Finalizes the CRC calculation and reads the resulting CRC from the | ||
| 228 | /// hardware consuming `self`. | ||
| 229 | pub fn finalize(self) -> u16 { | ||
| 230 | self.finalize_inner() | ||
| 231 | } | ||
| 232 | } | ||
| 233 | |||
| 234 | impl<'d> Crc<'d, Crc32> { | ||
| 235 | /// Instantiates a new CRC peripheral driver in 32-bit mode | ||
| 236 | pub fn new_crc32(peri: Peri<'d, CRC0>, config: Config) -> Self { | ||
| 237 | let inst = Self::new_inner(peri); | ||
| 238 | Self::configure(config, Tcrc::B32); | ||
| 239 | inst | ||
| 240 | } | ||
| 241 | |||
| 242 | /// Instantiates a new CRC peripheral driver for the given `Algorithm32`. | ||
| 243 | pub fn new_algorithm32(peri: Peri<'d, CRC0>, algorithm: Algorithm32) -> Self { | ||
| 244 | Self::new_crc32(peri, algorithm.into_config()) | ||
| 245 | } | ||
| 246 | |||
| 247 | /// Instantiates a new CRC peripheral for the `Bzip2` algorithm. | ||
| 248 | pub fn new_bzip2(peri: Peri<'d, CRC0>) -> Self { | ||
| 249 | Self::new_algorithm32(peri, Algorithm32::Bzip2) | ||
| 250 | } | ||
| 251 | |||
| 252 | /// Instantiates a new CRC peripheral for the `C` algorithm. | ||
| 253 | pub fn new_c(peri: Peri<'d, CRC0>) -> Self { | ||
| 254 | Self::new_algorithm32(peri, Algorithm32::C) | ||
| 255 | } | ||
| 256 | |||
| 257 | /// Instantiates a new CRC peripheral for the `D` algorithm. | ||
| 258 | pub fn new_d(peri: Peri<'d, CRC0>) -> Self { | ||
| 259 | Self::new_algorithm32(peri, Algorithm32::D) | ||
| 260 | } | ||
| 261 | |||
| 262 | /// Instantiates a new CRC peripheral for the `IsoHdlc` algorithm. | ||
| 263 | pub fn new_iso_hdlc(peri: Peri<'d, CRC0>) -> Self { | ||
| 264 | Self::new_algorithm32(peri, Algorithm32::IsoHdlc) | ||
| 265 | } | ||
| 266 | |||
| 267 | /// Instantiates a new CRC peripheral for the `JamCrc` algorithm. | ||
| 268 | pub fn new_jam_crc(peri: Peri<'d, CRC0>) -> Self { | ||
| 269 | Self::new_algorithm32(peri, Algorithm32::JamCrc) | ||
| 270 | } | ||
| 271 | |||
| 272 | /// Instantiates a new CRC peripheral for the `Mpeg2` algorithm. | ||
| 273 | pub fn new_mpeg2(peri: Peri<'d, CRC0>) -> Self { | ||
| 274 | Self::new_algorithm32(peri, Algorithm32::Mpeg2) | ||
| 275 | } | ||
| 276 | |||
| 277 | /// Instantiates a new CRC peripheral for the `Posix` algorithm. | ||
| 278 | pub fn new_posix(peri: Peri<'d, CRC0>) -> Self { | ||
| 279 | Self::new_algorithm32(peri, Algorithm32::Posix) | ||
| 280 | } | ||
| 281 | |||
| 282 | /// Instantiates a new CRC peripheral for the `Q` algorithm. | ||
| 283 | pub fn new_q(peri: Peri<'d, CRC0>) -> Self { | ||
| 284 | Self::new_algorithm32(peri, Algorithm32::Q) | ||
| 285 | } | ||
| 286 | |||
| 287 | /// Instantiates a new CRC peripheral for the `Xfer` algorithm. | ||
| 288 | pub fn new_xfer(peri: Peri<'d, CRC0>) -> Self { | ||
| 289 | Self::new_algorithm32(peri, Algorithm32::Xfer) | ||
| 290 | } | ||
| 291 | |||
| 292 | /// Feeds a slice of `Word`s into the CRC peripheral. | ||
| 293 | /// | ||
| 294 | /// The input is strided efficiently into as many `u32`s as possible, | ||
| 295 | /// falling back to smaller writes for the remainder. | ||
| 296 | pub fn feed<W: Word>(&mut self, data: &[W]) { | ||
| 297 | self.feed_inner(data); | ||
| 298 | } | ||
| 299 | |||
| 300 | /// Finalizes the CRC calculation and reads the resulting CRC from the | ||
| 301 | /// hardware consuming `self`. | ||
| 302 | pub fn finalize(self) -> u32 { | ||
| 303 | self.finalize_inner() | ||
| 304 | } | ||
| 305 | } | ||
| 306 | |||
| 307 | mod sealed { | ||
| 308 | pub trait SealedMode {} | ||
| 309 | |||
| 310 | pub trait SealedWord: Copy { | ||
| 311 | fn write(regs: &'static crate::pac::crc0::RegisterBlock, word: Self); | ||
| 312 | fn read(regs: &'static crate::pac::crc0::RegisterBlock) -> Self; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | /// Mode of operation: 32 or 16-bit CRC. | ||
| 317 | #[allow(private_bounds)] | ||
| 318 | pub trait Mode: sealed::SealedMode {} | ||
| 319 | |||
| 320 | /// 16-bit CRC. | ||
| 321 | pub struct Crc16; | ||
| 322 | impl sealed::SealedMode for Crc16 {} | ||
| 323 | impl Mode for Crc16 {} | ||
| 324 | |||
| 325 | /// 32-bit CRC. | ||
| 326 | pub struct Crc32; | ||
| 327 | impl sealed::SealedMode for Crc32 {} | ||
| 328 | impl Mode for Crc32 {} | ||
| 329 | |||
| 330 | /// Word size for the CRC. | ||
| 331 | #[allow(private_bounds)] | ||
| 332 | pub trait Word: sealed::SealedWord {} | ||
| 333 | |||
| 334 | macro_rules! impl_word { | ||
| 335 | ($t:ty, $width:literal, $write:expr, $read:expr) => { | ||
| 336 | impl sealed::SealedWord for $t { | ||
| 337 | #[inline] | ||
| 338 | fn write(regs: &'static crate::pac::crc0::RegisterBlock, word: Self) { | ||
| 339 | $write(regs, word) | ||
| 340 | } | ||
| 341 | |||
| 342 | #[inline] | ||
| 343 | fn read(regs: &'static crate::pac::crc0::RegisterBlock) -> Self { | ||
| 344 | $read(regs) | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | impl Word for $t {} | ||
| 349 | }; | ||
| 350 | } | ||
| 351 | |||
| 352 | impl_word!(u8, 8, write_u8, read_u8); | ||
| 353 | impl_word!(u16, 16, write_u16, read_u16); | ||
| 354 | impl_word!(u32, 32, write_u32, read_u32); | ||
| 355 | |||
| 356 | fn write_u8(regs: &'static crate::pac::crc0::RegisterBlock, word: u8) { | ||
| 357 | regs.data8().write(|w| unsafe { w.bits(word) }); | ||
| 358 | } | ||
| 359 | |||
| 360 | fn read_u8(regs: &'static crate::pac::crc0::RegisterBlock) -> u8 { | ||
| 361 | regs.data8().read().bits() | ||
| 362 | } | ||
| 363 | |||
| 364 | fn write_u16(regs: &'static crate::pac::crc0::RegisterBlock, word: u16) { | ||
| 365 | regs.data16().write(|w| unsafe { w.bits(word) }); | ||
| 366 | } | ||
| 367 | |||
| 368 | fn read_u16(regs: &'static crate::pac::crc0::RegisterBlock) -> u16 { | ||
| 369 | let ctrl = regs.ctrl().read(); | ||
| 370 | |||
| 371 | // if transposition is enabled, result sits in the upper 16 bits | ||
| 372 | if ctrl.totr().is_byts_trnps() || ctrl.totr().is_byts_bts_trnps() { | ||
| 373 | (regs.data32().read().bits() >> 16) as u16 | ||
| 374 | } else { | ||
| 375 | regs.data16().read().bits() | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 379 | fn write_u32(regs: &'static crate::pac::crc0::RegisterBlock, word: u32) { | ||
| 380 | regs.data32().write(|w| unsafe { w.bits(word) }); | ||
| 381 | } | ||
| 382 | |||
| 383 | fn read_u32(regs: &'static crate::pac::crc0::RegisterBlock) -> u32 { | ||
| 384 | regs.data32().read().bits() | ||
| 385 | } | ||
| 386 | |||
| 387 | /// CRC configuration. | ||
| 388 | #[derive(Copy, Clone, Debug)] | ||
| 389 | #[non_exhaustive] | ||
| 390 | pub struct Config { | ||
| 391 | /// The CRC polynomial to be used. | ||
| 392 | pub polynomial: u32, | ||
| 393 | |||
| 394 | /// Reflect bit order of input? | ||
| 395 | pub reflect_in: Reflect, | ||
| 396 | |||
| 397 | /// Reflect CRC bit order? | ||
| 398 | pub reflect_out: Reflect, | ||
| 399 | |||
| 400 | /// 1's complement CRC? | ||
| 401 | pub complement_out: Complement, | ||
| 402 | |||
| 403 | /// CRC Seed | ||
| 404 | pub seed: u32, | ||
| 405 | } | ||
| 406 | |||
| 407 | impl Config { | ||
| 408 | /// Create a new CRC config. | ||
| 409 | #[must_use] | ||
| 410 | pub fn new( | ||
| 411 | polynomial: u32, | ||
| 412 | reflect_in: Reflect, | ||
| 413 | reflect_out: Reflect, | ||
| 414 | complement_out: Complement, | ||
| 415 | seed: u32, | ||
| 416 | ) -> Self { | ||
| 417 | Config { | ||
| 418 | polynomial, | ||
| 419 | reflect_in, | ||
| 420 | reflect_out, | ||
| 421 | complement_out, | ||
| 422 | seed, | ||
| 423 | } | ||
| 424 | } | ||
| 425 | } | ||
| 426 | |||
| 427 | impl Default for Config { | ||
| 428 | fn default() -> Self { | ||
| 429 | Self { | ||
| 430 | polynomial: 0, | ||
| 431 | reflect_in: Reflect::No, | ||
| 432 | reflect_out: Reflect::No, | ||
| 433 | complement_out: Complement::No, | ||
| 434 | seed: 0xffff_ffff, | ||
| 435 | } | ||
| 436 | } | ||
| 437 | } | ||
| 438 | |||
| 439 | /// Supported standard CRC16 algorithms. | ||
| 440 | #[derive(Copy, Clone, Debug)] | ||
| 441 | pub enum Algorithm16 { | ||
| 442 | A, | ||
| 443 | Arc, | ||
| 444 | AugCcitt, | ||
| 445 | Buypass, | ||
| 446 | CcittFalse, | ||
| 447 | CcittZero, | ||
| 448 | Cdma2000, | ||
| 449 | Dds110, | ||
| 450 | DectX, | ||
| 451 | Dnp, | ||
| 452 | En13757, | ||
| 453 | Genibus, | ||
| 454 | Kermit, | ||
| 455 | Maxim, | ||
| 456 | Mcrf4xx, | ||
| 457 | Modbus, | ||
| 458 | Riello, | ||
| 459 | T10Dif, | ||
| 460 | Teledisk, | ||
| 461 | Tms37157, | ||
| 462 | Usb, | ||
| 463 | X25, | ||
| 464 | Xmodem, | ||
| 465 | } | ||
| 466 | |||
| 467 | impl Algorithm16 { | ||
| 468 | fn into_config(self) -> Config { | ||
| 469 | match self { | ||
| 470 | Algorithm16::A => Config { | ||
| 471 | polynomial: 0x1021, | ||
| 472 | reflect_in: Reflect::Yes, | ||
| 473 | reflect_out: Reflect::Yes, | ||
| 474 | complement_out: Complement::No, | ||
| 475 | seed: 0xc6c6, | ||
| 476 | }, | ||
| 477 | Algorithm16::Arc => Config { | ||
| 478 | polynomial: 0x8005, | ||
| 479 | reflect_in: Reflect::Yes, | ||
| 480 | reflect_out: Reflect::Yes, | ||
| 481 | complement_out: Complement::No, | ||
| 482 | seed: 0, | ||
| 483 | }, | ||
| 484 | Algorithm16::AugCcitt => Config { | ||
| 485 | polynomial: 0x1021, | ||
| 486 | reflect_in: Reflect::No, | ||
| 487 | reflect_out: Reflect::No, | ||
| 488 | complement_out: Complement::No, | ||
| 489 | seed: 0x1d0f, | ||
| 490 | }, | ||
| 491 | Algorithm16::Buypass => Config { | ||
| 492 | polynomial: 0x8005, | ||
| 493 | reflect_in: Reflect::No, | ||
| 494 | reflect_out: Reflect::No, | ||
| 495 | complement_out: Complement::No, | ||
| 496 | seed: 0, | ||
| 497 | }, | ||
| 498 | Algorithm16::CcittFalse => Config { | ||
| 499 | polynomial: 0x1021, | ||
| 500 | reflect_in: Reflect::No, | ||
| 501 | reflect_out: Reflect::No, | ||
| 502 | complement_out: Complement::No, | ||
| 503 | seed: 0xffff, | ||
| 504 | }, | ||
| 505 | Algorithm16::CcittZero => Config { | ||
| 506 | polynomial: 0x1021, | ||
| 507 | reflect_in: Reflect::No, | ||
| 508 | reflect_out: Reflect::No, | ||
| 509 | complement_out: Complement::No, | ||
| 510 | seed: 0, | ||
| 511 | }, | ||
| 512 | Algorithm16::Cdma2000 => Config { | ||
| 513 | polynomial: 0xc867, | ||
| 514 | reflect_in: Reflect::No, | ||
| 515 | reflect_out: Reflect::No, | ||
| 516 | complement_out: Complement::No, | ||
| 517 | seed: 0xffff, | ||
| 518 | }, | ||
| 519 | Algorithm16::Dds110 => Config { | ||
| 520 | polynomial: 0x8005, | ||
| 521 | reflect_in: Reflect::No, | ||
| 522 | reflect_out: Reflect::No, | ||
| 523 | complement_out: Complement::No, | ||
| 524 | seed: 0x800d, | ||
| 525 | }, | ||
| 526 | Algorithm16::DectX => Config { | ||
| 527 | polynomial: 0x0589, | ||
| 528 | reflect_in: Reflect::No, | ||
| 529 | reflect_out: Reflect::No, | ||
| 530 | complement_out: Complement::No, | ||
| 531 | seed: 0, | ||
| 532 | }, | ||
| 533 | Algorithm16::Dnp => Config { | ||
| 534 | polynomial: 0x3d65, | ||
| 535 | reflect_in: Reflect::Yes, | ||
| 536 | reflect_out: Reflect::Yes, | ||
| 537 | complement_out: Complement::Yes, | ||
| 538 | seed: 0, | ||
| 539 | }, | ||
| 540 | Algorithm16::En13757 => Config { | ||
| 541 | polynomial: 0x3d65, | ||
| 542 | reflect_in: Reflect::No, | ||
| 543 | reflect_out: Reflect::No, | ||
| 544 | complement_out: Complement::Yes, | ||
| 545 | seed: 0, | ||
| 546 | }, | ||
| 547 | Algorithm16::Genibus => Config { | ||
| 548 | polynomial: 0x1021, | ||
| 549 | reflect_in: Reflect::No, | ||
| 550 | reflect_out: Reflect::No, | ||
| 551 | complement_out: Complement::Yes, | ||
| 552 | seed: 0xffff, | ||
| 553 | }, | ||
| 554 | Algorithm16::Kermit => Config { | ||
| 555 | polynomial: 0x1021, | ||
| 556 | reflect_in: Reflect::Yes, | ||
| 557 | reflect_out: Reflect::Yes, | ||
| 558 | complement_out: Complement::No, | ||
| 559 | seed: 0, | ||
| 560 | }, | ||
| 561 | Algorithm16::Maxim => Config { | ||
| 562 | polynomial: 0x8005, | ||
| 563 | reflect_in: Reflect::Yes, | ||
| 564 | reflect_out: Reflect::Yes, | ||
| 565 | complement_out: Complement::Yes, | ||
| 566 | seed: 0, | ||
| 567 | }, | ||
| 568 | Algorithm16::Mcrf4xx => Config { | ||
| 569 | polynomial: 0x1021, | ||
| 570 | reflect_in: Reflect::Yes, | ||
| 571 | reflect_out: Reflect::Yes, | ||
| 572 | complement_out: Complement::No, | ||
| 573 | seed: 0xffff, | ||
| 574 | }, | ||
| 575 | Algorithm16::Modbus => Config { | ||
| 576 | polynomial: 0x8005, | ||
| 577 | reflect_in: Reflect::Yes, | ||
| 578 | reflect_out: Reflect::Yes, | ||
| 579 | complement_out: Complement::No, | ||
| 580 | seed: 0xffff, | ||
| 581 | }, | ||
| 582 | Algorithm16::Riello => Config { | ||
| 583 | polynomial: 0x1021, | ||
| 584 | reflect_in: Reflect::Yes, | ||
| 585 | reflect_out: Reflect::Yes, | ||
| 586 | complement_out: Complement::No, | ||
| 587 | seed: 0xb2aa, | ||
| 588 | }, | ||
| 589 | Algorithm16::T10Dif => Config { | ||
| 590 | polynomial: 0x8bb7, | ||
| 591 | reflect_in: Reflect::No, | ||
| 592 | reflect_out: Reflect::No, | ||
| 593 | complement_out: Complement::No, | ||
| 594 | seed: 0, | ||
| 595 | }, | ||
| 596 | Algorithm16::Teledisk => Config { | ||
| 597 | polynomial: 0xa097, | ||
| 598 | reflect_in: Reflect::No, | ||
| 599 | reflect_out: Reflect::No, | ||
| 600 | complement_out: Complement::No, | ||
| 601 | seed: 0, | ||
| 602 | }, | ||
| 603 | Algorithm16::Tms37157 => Config { | ||
| 604 | polynomial: 0x1021, | ||
| 605 | reflect_in: Reflect::Yes, | ||
| 606 | reflect_out: Reflect::Yes, | ||
| 607 | complement_out: Complement::No, | ||
| 608 | seed: 0x89ec, | ||
| 609 | }, | ||
| 610 | Algorithm16::Usb => Config { | ||
| 611 | polynomial: 0x8005, | ||
| 612 | reflect_in: Reflect::Yes, | ||
| 613 | reflect_out: Reflect::Yes, | ||
| 614 | complement_out: Complement::No, | ||
| 615 | seed: 0xffff, | ||
| 616 | }, | ||
| 617 | Algorithm16::X25 => Config { | ||
| 618 | polynomial: 0x1021, | ||
| 619 | reflect_in: Reflect::Yes, | ||
| 620 | reflect_out: Reflect::Yes, | ||
| 621 | complement_out: Complement::Yes, | ||
| 622 | seed: 0xffff, | ||
| 623 | }, | ||
| 624 | Algorithm16::Xmodem => Config { | ||
| 625 | polynomial: 0x1021, | ||
| 626 | reflect_in: Reflect::No, | ||
| 627 | reflect_out: Reflect::No, | ||
| 628 | complement_out: Complement::No, | ||
| 629 | seed: 0, | ||
| 630 | }, | ||
| 631 | } | ||
| 632 | } | ||
| 633 | } | ||
| 634 | |||
| 635 | /// Supported standard CRC32 algorithms. | ||
| 636 | #[derive(Copy, Clone, Debug)] | ||
| 637 | pub enum Algorithm32 { | ||
| 638 | Bzip2, | ||
| 639 | C, | ||
| 640 | D, | ||
| 641 | IsoHdlc, | ||
| 642 | JamCrc, | ||
| 643 | Mpeg2, | ||
| 644 | Posix, | ||
| 645 | Q, | ||
| 646 | Xfer, | ||
| 647 | } | ||
| 648 | |||
| 649 | impl Algorithm32 { | ||
| 650 | fn into_config(self) -> Config { | ||
| 651 | match self { | ||
| 652 | Algorithm32::Bzip2 => Config { | ||
| 653 | polynomial: 0x04c1_1db7, | ||
| 654 | reflect_in: Reflect::No, | ||
| 655 | reflect_out: Reflect::No, | ||
| 656 | complement_out: Complement::Yes, | ||
| 657 | seed: 0xffff_ffff, | ||
| 658 | }, | ||
| 659 | Algorithm32::C => Config { | ||
| 660 | polynomial: 0x1edc_6f41, | ||
| 661 | reflect_in: Reflect::Yes, | ||
| 662 | reflect_out: Reflect::Yes, | ||
| 663 | complement_out: Complement::Yes, | ||
| 664 | seed: 0xffff_ffff, | ||
| 665 | }, | ||
| 666 | Algorithm32::D => Config { | ||
| 667 | polynomial: 0xa833_982b, | ||
| 668 | reflect_in: Reflect::Yes, | ||
| 669 | reflect_out: Reflect::Yes, | ||
| 670 | complement_out: Complement::Yes, | ||
| 671 | seed: 0xffff_ffff, | ||
| 672 | }, | ||
| 673 | Algorithm32::IsoHdlc => Config { | ||
| 674 | polynomial: 0x04c1_1db7, | ||
| 675 | reflect_in: Reflect::Yes, | ||
| 676 | reflect_out: Reflect::Yes, | ||
| 677 | complement_out: Complement::Yes, | ||
| 678 | seed: 0xffff_ffff, | ||
| 679 | }, | ||
| 680 | Algorithm32::JamCrc => Config { | ||
| 681 | polynomial: 0x04c1_1db7, | ||
| 682 | reflect_in: Reflect::Yes, | ||
| 683 | reflect_out: Reflect::Yes, | ||
| 684 | complement_out: Complement::No, | ||
| 685 | seed: 0xffff_ffff, | ||
| 686 | }, | ||
| 687 | Algorithm32::Mpeg2 => Config { | ||
| 688 | polynomial: 0x04c1_1db7, | ||
| 689 | reflect_in: Reflect::No, | ||
| 690 | reflect_out: Reflect::No, | ||
| 691 | complement_out: Complement::No, | ||
| 692 | seed: 0xffff_ffff, | ||
| 693 | }, | ||
| 694 | Algorithm32::Posix => Config { | ||
| 695 | polynomial: 0x04c1_1db7, | ||
| 696 | reflect_in: Reflect::No, | ||
| 697 | reflect_out: Reflect::No, | ||
| 698 | complement_out: Complement::Yes, | ||
| 699 | seed: 0, | ||
| 700 | }, | ||
| 701 | Algorithm32::Q => Config { | ||
| 702 | polynomial: 0x8141_41ab, | ||
| 703 | reflect_in: Reflect::No, | ||
| 704 | reflect_out: Reflect::No, | ||
| 705 | complement_out: Complement::No, | ||
| 706 | seed: 0, | ||
| 707 | }, | ||
| 708 | Algorithm32::Xfer => Config { | ||
| 709 | polynomial: 0x0000_00af, | ||
| 710 | reflect_in: Reflect::No, | ||
| 711 | reflect_out: Reflect::No, | ||
| 712 | complement_out: Complement::No, | ||
| 713 | seed: 0, | ||
| 714 | }, | ||
| 715 | } | ||
| 716 | } | ||
| 717 | } | ||
| 718 | |||
| 719 | /// Reflect bit order. | ||
| 720 | #[derive(Copy, Clone, Debug)] | ||
| 721 | pub enum Reflect { | ||
| 722 | No, | ||
| 723 | Yes, | ||
| 724 | } | ||
| 725 | |||
| 726 | impl From<Reflect> for Tot { | ||
| 727 | fn from(value: Reflect) -> Tot { | ||
| 728 | match value { | ||
| 729 | Reflect::No => Tot::BytsTrnps, | ||
| 730 | Reflect::Yes => Tot::BytsBtsTrnps, | ||
| 731 | } | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | impl From<Reflect> for Totr { | ||
| 736 | fn from(value: Reflect) -> Totr { | ||
| 737 | match value { | ||
| 738 | Reflect::No => Totr::Notrnps, | ||
| 739 | Reflect::Yes => Totr::BytsBtsTrnps, | ||
| 740 | } | ||
| 741 | } | ||
| 742 | } | ||
| 743 | |||
| 744 | /// 1's complement output. | ||
| 745 | #[derive(Copy, Clone, Debug)] | ||
| 746 | pub enum Complement { | ||
| 747 | No, | ||
| 748 | Yes, | ||
| 749 | } | ||
| 750 | |||
| 751 | impl From<Complement> for Fxor { | ||
| 752 | fn from(value: Complement) -> Fxor { | ||
| 753 | match value { | ||
| 754 | Complement::No => Fxor::Noxor, | ||
| 755 | Complement::Yes => Fxor::Invert, | ||
| 756 | } | ||
| 757 | } | ||
| 758 | } | ||
