Skip to main content

strat9_bus_drivers/
ts_nbus.rs

1use crate::{BusChild, BusDriver, BusError, PowerState};
2use alloc::{string::String, vec::Vec};
3
4const TS_NBUS_DIRECTION_IN: bool = false;
5const TS_NBUS_DIRECTION_OUT: bool = true;
6const TS_NBUS_WRITE_ADR: bool = false;
7const TS_NBUS_WRITE_VAL: bool = true;
8
9const MAX_POLL_RDY: u32 = 10000;
10
11const COMPATIBLE: &[&str] = &["technologic,ts-nbus"];
12
13pub struct GpioPin {
14    pub base: usize,
15    pub offset: u32,
16    pub active_low: bool,
17}
18
19impl GpioPin {
20    /// Sets high.
21    pub fn set_high(&self) { /* MMIO GPIO set */
22    }
23    /// Sets low.
24    pub fn set_low(&self) { /* MMIO GPIO clear */
25    }
26    /// Returns value.
27    pub fn get_value(&self) -> bool {
28        false
29    }
30    /// Sets direction input.
31    pub fn set_direction_input(&self) { /* configure as input */
32    }
33    /// Sets direction output.
34    pub fn set_direction_output(&self) { /* configure as output */
35    }
36}
37
38pub struct TsNbus {
39    data_pins: [Option<GpioPin>; 8],
40    csn: Option<GpioPin>,
41    txrx: Option<GpioPin>,
42    strobe: Option<GpioPin>,
43    ale: Option<GpioPin>,
44    rdy: Option<GpioPin>,
45    power_state: PowerState,
46    children: Vec<BusChild>,
47}
48
49impl TsNbus {
50    /// Creates a new instance.
51    pub fn new() -> Self {
52        Self {
53            data_pins: [const { None }; 8],
54            csn: None,
55            txrx: None,
56            strobe: None,
57            ale: None,
58            rdy: None,
59            power_state: PowerState::Off,
60            children: Vec::new(),
61        }
62    }
63
64    /// Sets data direction.
65    fn set_data_direction(&self, output: bool) {
66        for p in self.data_pins.iter().flatten() {
67            if output {
68                p.set_direction_output();
69            } else {
70                p.set_direction_input();
71            }
72        }
73    }
74
75    /// Writes byte.
76    fn write_byte(&self, val: u8) {
77        for i in 0..8 {
78            if let Some(ref p) = self.data_pins[i] {
79                if (val >> i) & 1 != 0 {
80                    p.set_high();
81                } else {
82                    p.set_low();
83                }
84            }
85        }
86    }
87
88    /// Reads byte.
89    fn read_byte(&self) -> u8 {
90        let mut val = 0u8;
91        for i in 0..8 {
92            if let Some(ref p) = self.data_pins[i]
93                && p.get_value() {
94                    val |= 1 << i;
95                }
96        }
97        val
98    }
99
100    /// Starts transaction.
101    fn start_transaction(&self) {
102        if let Some(ref s) = self.strobe {
103            s.set_high();
104        }
105    }
106
107    /// Performs the end transaction operation.
108    fn end_transaction(&self) {
109        if let Some(ref s) = self.strobe {
110            s.set_low();
111        }
112    }
113
114    /// Performs the wait rdy operation.
115    fn wait_rdy(&self) -> Result<(), BusError> {
116        for _ in 0..MAX_POLL_RDY {
117            if let Some(ref r) = self.rdy
118                && r.get_value() {
119                    return Ok(());
120                }
121        }
122        Err(BusError::Timeout)
123    }
124
125    /// Performs the reset bus operation.
126    fn reset_bus(&self) {
127        self.write_byte(0);
128        if let Some(ref c) = self.csn {
129            c.set_low();
130        }
131        if let Some(ref s) = self.strobe {
132            s.set_low();
133        }
134        if let Some(ref a) = self.ale {
135            a.set_low();
136        }
137    }
138
139    /// Performs the bus read operation.
140    pub fn bus_read(&self, address: u16) -> Result<u16, BusError> {
141        self.set_data_direction(true);
142        if let Some(ref t) = self.txrx {
143            t.set_low();
144        }
145        if let Some(ref a) = self.ale {
146            a.set_high();
147        }
148
149        self.write_byte((address >> 8) as u8);
150        self.start_transaction();
151        self.end_transaction();
152
153        self.write_byte(address as u8);
154        self.start_transaction();
155        self.end_transaction();
156
157        if let Some(ref a) = self.ale {
158            a.set_low();
159        }
160        self.set_data_direction(false);
161
162        if let Some(ref c) = self.csn {
163            c.set_high();
164        }
165        self.start_transaction();
166        self.wait_rdy()?;
167        let msb = self.read_byte();
168        self.end_transaction();
169
170        self.start_transaction();
171        self.wait_rdy()?;
172        let lsb = self.read_byte();
173        self.end_transaction();
174
175        if let Some(ref c) = self.csn {
176            c.set_low();
177        }
178
179        Ok(((msb as u16) << 8) | (lsb as u16))
180    }
181
182    /// Performs the bus write operation.
183    pub fn bus_write(&self, address: u16, value: u16) -> Result<(), BusError> {
184        self.set_data_direction(true);
185        if let Some(ref t) = self.txrx {
186            t.set_high();
187        }
188        if let Some(ref a) = self.ale {
189            a.set_high();
190        }
191
192        self.write_byte((address >> 8) as u8);
193        self.start_transaction();
194        self.end_transaction();
195
196        self.write_byte(address as u8);
197        self.start_transaction();
198        self.end_transaction();
199
200        if let Some(ref a) = self.ale {
201            a.set_low();
202        }
203        if let Some(ref c) = self.csn {
204            c.set_high();
205        }
206
207        self.write_byte((value >> 8) as u8);
208        self.start_transaction();
209        self.wait_rdy()?;
210        self.end_transaction();
211
212        self.write_byte(value as u8);
213        self.start_transaction();
214        self.wait_rdy()?;
215        self.end_transaction();
216
217        if let Some(ref c) = self.csn {
218            c.set_low();
219        }
220
221        Ok(())
222    }
223
224    /// Performs the add child operation.
225    pub fn add_child(&mut self, child: BusChild) {
226        self.children.push(child);
227    }
228}
229
230impl BusDriver for TsNbus {
231    /// Performs the name operation.
232    fn name(&self) -> &str {
233        "ts-nbus"
234    }
235
236    /// Performs the compatible operation.
237    fn compatible(&self) -> &[&str] {
238        COMPATIBLE
239    }
240
241    /// Requires explicit GPIO pin configuration; no auto-detect.
242    fn probe(&self) -> bool {
243        false
244    }
245
246    /// Performs the init operation.
247    fn init(&mut self, _base: usize) -> Result<(), BusError> {
248        self.reset_bus();
249        self.power_state = PowerState::On;
250        Ok(())
251    }
252
253    /// Performs the shutdown operation.
254    fn shutdown(&mut self) -> Result<(), BusError> {
255        self.reset_bus();
256        self.power_state = PowerState::Off;
257        Ok(())
258    }
259
260    /// Reads reg.
261    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
262        let val = self.bus_read(offset as u16)?;
263        Ok(val as u32)
264    }
265
266    /// Writes reg.
267    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
268        self.bus_write(offset as u16, value as u16)
269    }
270
271    /// Performs the children operation.
272    fn children(&self) -> Vec<BusChild> {
273        self.children.clone()
274    }
275}