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 pin in &self.data_pins {
67            if let Some(p) = pin {
68                if output {
69                    p.set_direction_output();
70                } else {
71                    p.set_direction_input();
72                }
73            }
74        }
75    }
76
77    /// Writes byte.
78    fn write_byte(&self, val: u8) {
79        for i in 0..8 {
80            if let Some(ref p) = self.data_pins[i] {
81                if (val >> i) & 1 != 0 {
82                    p.set_high();
83                } else {
84                    p.set_low();
85                }
86            }
87        }
88    }
89
90    /// Reads byte.
91    fn read_byte(&self) -> u8 {
92        let mut val = 0u8;
93        for i in 0..8 {
94            if let Some(ref p) = self.data_pins[i] {
95                if p.get_value() {
96                    val |= 1 << i;
97                }
98            }
99        }
100        val
101    }
102
103    /// Starts transaction.
104    fn start_transaction(&self) {
105        if let Some(ref s) = self.strobe {
106            s.set_high();
107        }
108    }
109
110    /// Performs the end transaction operation.
111    fn end_transaction(&self) {
112        if let Some(ref s) = self.strobe {
113            s.set_low();
114        }
115    }
116
117    /// Performs the wait rdy operation.
118    fn wait_rdy(&self) -> Result<(), BusError> {
119        for _ in 0..MAX_POLL_RDY {
120            if let Some(ref r) = self.rdy {
121                if r.get_value() {
122                    return Ok(());
123                }
124            }
125        }
126        Err(BusError::Timeout)
127    }
128
129    /// Performs the reset bus operation.
130    fn reset_bus(&self) {
131        self.write_byte(0);
132        if let Some(ref c) = self.csn {
133            c.set_low();
134        }
135        if let Some(ref s) = self.strobe {
136            s.set_low();
137        }
138        if let Some(ref a) = self.ale {
139            a.set_low();
140        }
141    }
142
143    /// Performs the bus read operation.
144    pub fn bus_read(&self, address: u16) -> Result<u16, BusError> {
145        self.set_data_direction(true);
146        if let Some(ref t) = self.txrx {
147            t.set_low();
148        }
149        if let Some(ref a) = self.ale {
150            a.set_high();
151        }
152
153        self.write_byte((address >> 8) as u8);
154        self.start_transaction();
155        self.end_transaction();
156
157        self.write_byte(address as u8);
158        self.start_transaction();
159        self.end_transaction();
160
161        if let Some(ref a) = self.ale {
162            a.set_low();
163        }
164        self.set_data_direction(false);
165
166        if let Some(ref c) = self.csn {
167            c.set_high();
168        }
169        self.start_transaction();
170        self.wait_rdy()?;
171        let msb = self.read_byte();
172        self.end_transaction();
173
174        self.start_transaction();
175        self.wait_rdy()?;
176        let lsb = self.read_byte();
177        self.end_transaction();
178
179        if let Some(ref c) = self.csn {
180            c.set_low();
181        }
182
183        Ok(((msb as u16) << 8) | (lsb as u16))
184    }
185
186    /// Performs the bus write operation.
187    pub fn bus_write(&self, address: u16, value: u16) -> Result<(), BusError> {
188        self.set_data_direction(true);
189        if let Some(ref t) = self.txrx {
190            t.set_high();
191        }
192        if let Some(ref a) = self.ale {
193            a.set_high();
194        }
195
196        self.write_byte((address >> 8) as u8);
197        self.start_transaction();
198        self.end_transaction();
199
200        self.write_byte(address as u8);
201        self.start_transaction();
202        self.end_transaction();
203
204        if let Some(ref a) = self.ale {
205            a.set_low();
206        }
207        if let Some(ref c) = self.csn {
208            c.set_high();
209        }
210
211        self.write_byte((value >> 8) as u8);
212        self.start_transaction();
213        self.wait_rdy()?;
214        self.end_transaction();
215
216        self.write_byte(value as u8);
217        self.start_transaction();
218        self.wait_rdy()?;
219        self.end_transaction();
220
221        if let Some(ref c) = self.csn {
222            c.set_low();
223        }
224
225        Ok(())
226    }
227
228    /// Performs the add child operation.
229    pub fn add_child(&mut self, child: BusChild) {
230        self.children.push(child);
231    }
232}
233
234impl BusDriver for TsNbus {
235    /// Performs the name operation.
236    fn name(&self) -> &str {
237        "ts-nbus"
238    }
239
240    /// Performs the compatible operation.
241    fn compatible(&self) -> &[&str] {
242        COMPATIBLE
243    }
244
245    /// Performs the init operation.
246    fn init(&mut self, _base: usize) -> Result<(), BusError> {
247        self.reset_bus();
248        self.power_state = PowerState::On;
249        Ok(())
250    }
251
252    /// Performs the shutdown operation.
253    fn shutdown(&mut self) -> Result<(), BusError> {
254        self.reset_bus();
255        self.power_state = PowerState::Off;
256        Ok(())
257    }
258
259    /// Reads reg.
260    fn read_reg(&self, offset: usize) -> Result<u32, BusError> {
261        let val = self.bus_read(offset as u16)?;
262        Ok(val as u32)
263    }
264
265    /// Writes reg.
266    fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
267        self.bus_write(offset as u16, value as u16)
268    }
269
270    /// Performs the children operation.
271    fn children(&self) -> Vec<BusChild> {
272        self.children.clone()
273    }
274}