strat9_bus_drivers/
ts_nbus.rs1use 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 pub fn set_high(&self) { }
23 pub fn set_low(&self) { }
26 pub fn get_value(&self) -> bool {
28 false
29 }
30 pub fn set_direction_input(&self) { }
33 pub fn set_direction_output(&self) { }
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 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 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 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 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 fn start_transaction(&self) {
105 if let Some(ref s) = self.strobe {
106 s.set_high();
107 }
108 }
109
110 fn end_transaction(&self) {
112 if let Some(ref s) = self.strobe {
113 s.set_low();
114 }
115 }
116
117 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 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 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 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 pub fn add_child(&mut self, child: BusChild) {
230 self.children.push(child);
231 }
232}
233
234impl BusDriver for TsNbus {
235 fn name(&self) -> &str {
237 "ts-nbus"
238 }
239
240 fn compatible(&self) -> &[&str] {
242 COMPATIBLE
243 }
244
245 fn init(&mut self, _base: usize) -> Result<(), BusError> {
247 self.reset_bus();
248 self.power_state = PowerState::On;
249 Ok(())
250 }
251
252 fn shutdown(&mut self) -> Result<(), BusError> {
254 self.reset_bus();
255 self.power_state = PowerState::Off;
256 Ok(())
257 }
258
259 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 fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
267 self.bus_write(offset as u16, value as u16)
268 }
269
270 fn children(&self) -> Vec<BusChild> {
272 self.children.clone()
273 }
274}