capsules_extra/test/
crc.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Test the CRC hardware.
6
7use kernel::debug;
8use kernel::hil::crc::{Client, Crc, CrcAlgorithm, CrcOutput};
9use kernel::utilities::cells::TakeCell;
10use kernel::utilities::leasable_buffer::SubSliceMut;
11use kernel::ErrorCode;
12
13pub struct TestCrc<'a, C: 'a> {
14    crc: &'a C,
15    data: TakeCell<'static, [u8]>,
16}
17
18impl<'a, C: Crc<'a>> TestCrc<'a, C> {
19    pub fn new(crc: &'a C, data: &'static mut [u8]) -> Self {
20        TestCrc {
21            crc,
22            data: TakeCell::new(data),
23        }
24    }
25
26    pub fn run_test(&self, algorithm: CrcAlgorithm) {
27        let res = self.crc.set_algorithm(algorithm);
28        if res.is_err() {
29            debug!("CrcTest ERROR: failed to set algorithm to Crc32: {:?}", res);
30            return;
31        }
32        let leasable: SubSliceMut<'static, u8> = SubSliceMut::new(self.data.take().unwrap());
33
34        let res = self.crc.input(leasable);
35        if let Err((error, _buffer)) = res {
36            debug!(
37                "CrcTest ERROR: failed to start input processing: {:?}",
38                error
39            );
40        }
41    }
42
43    pub fn run(&self) {
44        self.run_test(CrcAlgorithm::Crc32);
45    }
46}
47
48impl<'a, C: Crc<'a>> Client for TestCrc<'a, C> {
49    fn input_done(&self, result: Result<(), ErrorCode>, buffer: SubSliceMut<'static, u8>) {
50        if result.is_err() {
51            debug!("CrcTest ERROR: failed to process input: {:?}", result);
52            return;
53        }
54
55        if buffer.len() == 0 {
56            self.data.replace(buffer.take());
57            let res = self.crc.compute();
58            if res.is_err() {
59                debug!("CrcTest ERROR: failed to start CRC computation: {:?}", res);
60            }
61        } else {
62            let res = self.crc.input(buffer);
63            if let Err((error, _buffer)) = res {
64                debug!(
65                    "CrcTest ERROR: failed to start input processing: {:?}",
66                    error
67                );
68            }
69        }
70    }
71
72    /// Called when the CRC computation is finished.
73    fn crc_done(&self, result: Result<CrcOutput, ErrorCode>) {
74        if let Err(code) = result {
75            debug!("CrcTest ERROR: failed to compute CRC: {:?}", code);
76        } else {
77            if let Ok(output) = result {
78                match output {
79                    CrcOutput::Crc32(x) => {
80                        debug!("CRC32: {:#x}", x);
81                        self.run_test(CrcAlgorithm::Crc32C);
82                    }
83                    CrcOutput::Crc32C(x) => {
84                        debug!("CRC32C: {:#x}", x);
85                        self.run_test(CrcAlgorithm::Crc16CCITT);
86                    }
87                    CrcOutput::Crc16CCITT(x) => {
88                        debug!("CRC16CCITT: {:#x}", x);
89                    }
90                }
91            }
92        }
93    }
94}