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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//! A device abstraction for infrared receivers using the NEC protocol.
//!
//! This module provides platform-independent types and helpers for NEC IR decoding.
//! See the platform-specific crate (for example `device_envoy_rp::ir` or
//! `device_envoy_esp::ir`) for the primary documentation and examples.
pub use ;
pub use ;
use CriticalSectionRawMutex;
use Channel as EmbassyChannel;
/// Events received from the infrared receiver.
///
/// See the platform-specific crate for usage examples.
/// Platform-agnostic infrared receiver device contract.
///
/// Platform crates implement this for their concrete `Ir` types so shared logic can wait for
/// NEC button press events without depending on platform-specific modules.
///
/// This trait is the core `wait_for_press` surface used by platform IR receiver wrappers.
///
/// # Example
///
/// ```rust,no_run
/// use device_envoy_core::ir::{Ir, IrEvent};
///
/// async fn handle_ir_presses(ir: &impl Ir) -> ! {
/// loop {
/// let ir_event = ir.wait_for_press().await;
/// match ir_event {
/// IrEvent::Press { addr, cmd } => {
/// // Handle decoded NEC press event.
/// let _ = (addr, cmd);
/// }
/// }
/// }
/// }
///
/// # struct DemoIr;
/// # impl Ir for DemoIr {
/// # async fn wait_for_press(&self) -> IrEvent {
/// # IrEvent::Press { addr: 0, cmd: 0 }
/// # }
/// # }
/// # fn main() {
/// # let ir = DemoIr;
/// # let _future = handle_ir_presses(&ir);
/// # }
/// ```
/// Static resources for the [`Ir`] device abstraction.
///
/// See the platform-specific crate for usage examples.
// Public for cross-crate platform plumbing; hidden from end-user docs.
;
/// Decode and validate a 32-bit NEC frame.
///
/// NEC protocol structure (32 bits, LSB first):
/// - Byte 0: Address (8 bits)
/// - Byte 1: Address inverse (~Address)
/// - Byte 2: Command (8 bits)
/// - Byte 3: Command inverse (~Command)
///
/// Extended NEC uses 16-bit address (bytes 0-1) without inversion check.
///
/// Returns `Some((address, command))` if valid, `None` if checksum fails.
// Public for cross-crate platform plumbing; hidden from end-user docs.