rxprog/command/commands/
pe_11_read_lock_bit_status.rs

1use super::command_impl_prelude::*;
2
3/// Requests the state of the lock bit for a specified memory region
4#[derive(Debug)]
5pub struct ReadLockBitStatus {
6    /// The area in which the address resides
7    pub area: MemoryArea,
8    /// Bits 15 to 8 of the address
9    pub a15_to_a8: u8,
10    /// Bits 23 to 16 of the address
11    pub a23_to_a16: u8,
12    /// Bits 31 to 24 of the address
13    pub a31_to_a24: u8,
14}
15
16impl TransmitCommandData for ReadLockBitStatus {
17    fn command_data(&self) -> CommandData {
18        CommandData {
19            opcode: 0x71,
20            has_size_field: true,
21            payload: {
22                let mut payload = vec![];
23                payload.push(match self.area {
24                    MemoryArea::UserBootArea => 0x00,
25                    MemoryArea::UserArea => 0x01,
26                });
27                payload.push(self.a15_to_a8);
28                payload.push(self.a23_to_a16);
29                payload.push(self.a31_to_a24);
30                payload
31            },
32        }
33    }
34}
35
36impl Receive for ReadLockBitStatus {
37    type Response = LockBitStatus;
38
39    fn rx<T: io::Read>(&self, p: &mut T) -> Result<Self::Response> {
40        let mut reader = ResponseReader::<_, SimpleResponse, WithError>::new(
41            p,
42            ResponseFirstByte::OneByteOf(vec![0x00, 0x40]),
43            ErrorFirstByte(0xF1),
44        );
45
46        reader
47            .read_response()?
48            .map(|SimpleResponse { first_byte }| match first_byte {
49                0x00 => LockBitStatus::Locked,
50                0x40 => LockBitStatus::Unlocked,
51                _ => panic!("Response with unknown first byte"),
52            })
53            .map_err(|error_code| match error_code {
54                0x11 => CommandError::Checksum.into(),
55                0x2A => CommandError::Address.into(),
56                _ => panic!("Unknown error code"),
57            })
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::super::test_util::is_script_complete;
64    use super::*;
65
66    #[test]
67    fn test_tx() -> Result<()> {
68        let cmd = ReadLockBitStatus {
69            area: MemoryArea::UserArea,
70            a15_to_a8: 0x00,
71            a23_to_a16: 0xAA,
72            a31_to_a24: 0xFF,
73        };
74        let command_bytes = [0x71, 0x04, 0x01, 0x00, 0xAA, 0xFF, 0xE1];
75        let mut p = mock_io::Builder::new().write(&command_bytes).build();
76
77        cmd.tx(&mut p)?;
78
79        assert!(is_script_complete(&mut p));
80
81        Ok(())
82    }
83
84    #[test]
85    fn test_rx_success_locked() {
86        let cmd = ReadLockBitStatus {
87            area: MemoryArea::UserArea,
88            a15_to_a8: 0x00,
89            a23_to_a16: 0xAA,
90            a31_to_a24: 0xFF,
91        };
92        let response_bytes = [0x00];
93        let mut p = mock_io::Builder::new().read(&response_bytes).build();
94
95        let response = cmd.rx(&mut p);
96
97        assert_eq!(response, Ok(LockBitStatus::Locked));
98        assert!(is_script_complete(&mut p));
99    }
100
101    #[test]
102    fn test_rx_success_unlocked() {
103        let cmd = ReadLockBitStatus {
104            area: MemoryArea::UserArea,
105            a15_to_a8: 0x00,
106            a23_to_a16: 0xAA,
107            a31_to_a24: 0xFF,
108        };
109        let response_bytes = [0x40];
110        let mut p = mock_io::Builder::new().read(&response_bytes).build();
111
112        let response = cmd.rx(&mut p);
113
114        assert_eq!(response, Ok(LockBitStatus::Unlocked));
115        assert!(is_script_complete(&mut p));
116    }
117
118    #[test]
119    fn test_rx_fail() {
120        let cmd = ReadLockBitStatus {
121            area: MemoryArea::UserArea,
122            a15_to_a8: 0x00,
123            a23_to_a16: 0xAA,
124            a31_to_a24: 0xFF,
125        };
126        let response_bytes = [0xF1, 0x2A];
127        let mut p = mock_io::Builder::new().read(&response_bytes).build();
128
129        let response = cmd.rx(&mut p);
130
131        assert_eq!(response, Err(CommandError::Address.into()));
132        assert!(is_script_complete(&mut p));
133    }
134}