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 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 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 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 fn start_transaction(&self) {
102 if let Some(ref s) = self.strobe {
103 s.set_high();
104 }
105 }
106
107 fn end_transaction(&self) {
109 if let Some(ref s) = self.strobe {
110 s.set_low();
111 }
112 }
113
114 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 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 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 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 pub fn add_child(&mut self, child: BusChild) {
226 self.children.push(child);
227 }
228}
229
230impl BusDriver for TsNbus {
231 fn name(&self) -> &str {
233 "ts-nbus"
234 }
235
236 fn compatible(&self) -> &[&str] {
238 COMPATIBLE
239 }
240
241 fn probe(&self) -> bool {
243 false
244 }
245
246 fn init(&mut self, _base: usize) -> Result<(), BusError> {
248 self.reset_bus();
249 self.power_state = PowerState::On;
250 Ok(())
251 }
252
253 fn shutdown(&mut self) -> Result<(), BusError> {
255 self.reset_bus();
256 self.power_state = PowerState::Off;
257 Ok(())
258 }
259
260 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 fn write_reg(&mut self, offset: usize, value: u32) -> Result<(), BusError> {
268 self.bus_write(offset as u16, value as u16)
269 }
270
271 fn children(&self) -> Vec<BusChild> {
273 self.children.clone()
274 }
275}