aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-12-26 23:21:58 +0100
committerDario Nieuwenhuis <[email protected]>2022-12-26 23:34:27 +0100
commit1b6799d93f0bbd6154c124d51aa47aeed0acf15d (patch)
tree1c8e206bcfcfd533355cde2b5533660ee940f86e /src
parent076ada4c0233d2f89c89cda4c01910a86add90ac (diff)
split bus, consts into separate mods.
Diffstat (limited to 'src')
-rw-r--r--src/bus.rs321
-rw-r--r--src/consts.rs105
-rw-r--r--src/lib.rs536
3 files changed, 496 insertions, 466 deletions
diff --git a/src/bus.rs b/src/bus.rs
new file mode 100644
index 000000000..f220cffcd
--- /dev/null
+++ b/src/bus.rs
@@ -0,0 +1,321 @@
1use core::slice;
2
3use embassy_time::{Duration, Timer};
4use embedded_hal_1::digital::OutputPin;
5use embedded_hal_async::spi::{transaction, SpiBusRead, SpiBusWrite, SpiDevice};
6
7use crate::consts::*;
8
9pub(crate) struct Bus<PWR, SPI> {
10 backplane_window: u32,
11 pwr: PWR,
12 spi: SPI,
13}
14
15impl<PWR, SPI> Bus<PWR, SPI>
16where
17 PWR: OutputPin,
18 SPI: SpiDevice,
19 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
20{
21 pub(crate) fn new(pwr: PWR, spi: SPI) -> Self {
22 Self {
23 backplane_window: 0xAAAA_AAAA,
24 pwr,
25 spi,
26 }
27 }
28
29 pub async fn init(&mut self) {
30 // Reset
31 self.pwr.set_low().unwrap();
32 Timer::after(Duration::from_millis(20)).await;
33 self.pwr.set_high().unwrap();
34 Timer::after(Duration::from_millis(250)).await;
35
36 while self.read32_swapped(REG_BUS_TEST_RO).await != FEEDBEAD {}
37
38 self.write32_swapped(REG_BUS_TEST_RW, TEST_PATTERN).await;
39 let val = self.read32_swapped(REG_BUS_TEST_RW).await;
40 assert_eq!(val, TEST_PATTERN);
41
42 // 32-bit word length, little endian (which is the default endianess).
43 self.write32_swapped(REG_BUS_CTRL, WORD_LENGTH_32 | HIGH_SPEED).await;
44
45 let val = self.read32(FUNC_BUS, REG_BUS_TEST_RO).await;
46 assert_eq!(val, FEEDBEAD);
47 let val = self.read32(FUNC_BUS, REG_BUS_TEST_RW).await;
48 assert_eq!(val, TEST_PATTERN);
49 }
50
51 pub async fn wlan_read(&mut self, buf: &mut [u32]) {
52 let cmd = cmd_word(READ, INC_ADDR, FUNC_WLAN, 0, buf.len() as u32 * 4);
53 transaction!(&mut self.spi, |bus| async {
54 bus.write(&[cmd]).await?;
55 bus.read(buf).await?;
56 Ok(())
57 })
58 .await
59 .unwrap();
60 }
61
62 pub async fn wlan_write(&mut self, buf: &[u32]) {
63 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_WLAN, 0, buf.len() as u32 * 4);
64 transaction!(&mut self.spi, |bus| async {
65 bus.write(&[cmd]).await?;
66 bus.write(buf).await?;
67 Ok(())
68 })
69 .await
70 .unwrap();
71 }
72
73 #[allow(unused)]
74 pub async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) {
75 // It seems the HW force-aligns the addr
76 // to 2 if data.len() >= 2
77 // to 4 if data.len() >= 4
78 // To simplify, enforce 4-align for now.
79 assert!(addr % 4 == 0);
80
81 let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4];
82
83 while !data.is_empty() {
84 // Ensure transfer doesn't cross a window boundary.
85 let window_offs = addr & BACKPLANE_ADDRESS_MASK;
86 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize;
87
88 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining);
89
90 self.backplane_set_window(addr).await;
91
92 let cmd = cmd_word(READ, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32);
93
94 transaction!(&mut self.spi, |bus| async {
95 bus.write(&[cmd]).await?;
96
97 // 4-byte response delay.
98 let mut junk = [0; 1];
99 bus.read(&mut junk).await?;
100
101 // Read data
102 bus.read(&mut buf[..(len + 3) / 4]).await?;
103 Ok(())
104 })
105 .await
106 .unwrap();
107
108 data[..len].copy_from_slice(&slice8_mut(&mut buf)[..len]);
109
110 // Advance ptr.
111 addr += len as u32;
112 data = &mut data[len..];
113 }
114 }
115
116 pub async fn bp_write(&mut self, mut addr: u32, mut data: &[u8]) {
117 // It seems the HW force-aligns the addr
118 // to 2 if data.len() >= 2
119 // to 4 if data.len() >= 4
120 // To simplify, enforce 4-align for now.
121 assert!(addr % 4 == 0);
122
123 let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4];
124
125 while !data.is_empty() {
126 // Ensure transfer doesn't cross a window boundary.
127 let window_offs = addr & BACKPLANE_ADDRESS_MASK;
128 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize;
129
130 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining);
131 slice8_mut(&mut buf)[..len].copy_from_slice(&data[..len]);
132
133 self.backplane_set_window(addr).await;
134
135 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32);
136
137 transaction!(&mut self.spi, |bus| async {
138 bus.write(&[cmd]).await?;
139 bus.write(&buf[..(len + 3) / 4]).await?;
140 Ok(())
141 })
142 .await
143 .unwrap();
144
145 // Advance ptr.
146 addr += len as u32;
147 data = &data[len..];
148 }
149 }
150
151 pub async fn bp_read8(&mut self, addr: u32) -> u8 {
152 self.backplane_readn(addr, 1).await as u8
153 }
154
155 pub async fn bp_write8(&mut self, addr: u32, val: u8) {
156 self.backplane_writen(addr, val as u32, 1).await
157 }
158
159 pub async fn bp_read16(&mut self, addr: u32) -> u16 {
160 self.backplane_readn(addr, 2).await as u16
161 }
162
163 #[allow(unused)]
164 pub async fn bp_write16(&mut self, addr: u32, val: u16) {
165 self.backplane_writen(addr, val as u32, 2).await
166 }
167
168 #[allow(unused)]
169 pub async fn bp_read32(&mut self, addr: u32) -> u32 {
170 self.backplane_readn(addr, 4).await
171 }
172
173 pub async fn bp_write32(&mut self, addr: u32, val: u32) {
174 self.backplane_writen(addr, val, 4).await
175 }
176
177 async fn backplane_readn(&mut self, addr: u32, len: u32) -> u32 {
178 self.backplane_set_window(addr).await;
179
180 let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK;
181 if len == 4 {
182 bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG
183 }
184 self.readn(FUNC_BACKPLANE, bus_addr, len).await
185 }
186
187 async fn backplane_writen(&mut self, addr: u32, val: u32, len: u32) {
188 self.backplane_set_window(addr).await;
189
190 let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK;
191 if len == 4 {
192 bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG
193 }
194 self.writen(FUNC_BACKPLANE, bus_addr, val, len).await
195 }
196
197 async fn backplane_set_window(&mut self, addr: u32) {
198 let new_window = addr & !BACKPLANE_ADDRESS_MASK;
199
200 if (new_window >> 24) as u8 != (self.backplane_window >> 24) as u8 {
201 self.write8(
202 FUNC_BACKPLANE,
203 REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH,
204 (new_window >> 24) as u8,
205 )
206 .await;
207 }
208 if (new_window >> 16) as u8 != (self.backplane_window >> 16) as u8 {
209 self.write8(
210 FUNC_BACKPLANE,
211 REG_BACKPLANE_BACKPLANE_ADDRESS_MID,
212 (new_window >> 16) as u8,
213 )
214 .await;
215 }
216 if (new_window >> 8) as u8 != (self.backplane_window >> 8) as u8 {
217 self.write8(
218 FUNC_BACKPLANE,
219 REG_BACKPLANE_BACKPLANE_ADDRESS_LOW,
220 (new_window >> 8) as u8,
221 )
222 .await;
223 }
224 self.backplane_window = new_window;
225 }
226
227 pub async fn read8(&mut self, func: u32, addr: u32) -> u8 {
228 self.readn(func, addr, 1).await as u8
229 }
230
231 pub async fn write8(&mut self, func: u32, addr: u32, val: u8) {
232 self.writen(func, addr, val as u32, 1).await
233 }
234
235 pub async fn read16(&mut self, func: u32, addr: u32) -> u16 {
236 self.readn(func, addr, 2).await as u16
237 }
238
239 #[allow(unused)]
240 pub async fn write16(&mut self, func: u32, addr: u32, val: u16) {
241 self.writen(func, addr, val as u32, 2).await
242 }
243
244 pub async fn read32(&mut self, func: u32, addr: u32) -> u32 {
245 self.readn(func, addr, 4).await
246 }
247
248 #[allow(unused)]
249 pub async fn write32(&mut self, func: u32, addr: u32, val: u32) {
250 self.writen(func, addr, val, 4).await
251 }
252
253 async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 {
254 let cmd = cmd_word(READ, INC_ADDR, func, addr, len);
255 let mut buf = [0; 1];
256
257 transaction!(&mut self.spi, |bus| async {
258 bus.write(&[cmd]).await?;
259 if func == FUNC_BACKPLANE {
260 // 4-byte response delay.
261 bus.read(&mut buf).await?;
262 }
263 bus.read(&mut buf).await?;
264 Ok(())
265 })
266 .await
267 .unwrap();
268
269 buf[0]
270 }
271
272 async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) {
273 let cmd = cmd_word(WRITE, INC_ADDR, func, addr, len);
274
275 transaction!(&mut self.spi, |bus| async {
276 bus.write(&[cmd, val]).await?;
277 Ok(())
278 })
279 .await
280 .unwrap();
281 }
282
283 async fn read32_swapped(&mut self, addr: u32) -> u32 {
284 let cmd = cmd_word(READ, INC_ADDR, FUNC_BUS, addr, 4);
285 let mut buf = [0; 1];
286
287 transaction!(&mut self.spi, |bus| async {
288 bus.write(&[swap16(cmd)]).await?;
289 bus.read(&mut buf).await?;
290 Ok(())
291 })
292 .await
293 .unwrap();
294
295 swap16(buf[0])
296 }
297
298 async fn write32_swapped(&mut self, addr: u32, val: u32) {
299 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BUS, addr, 4);
300
301 transaction!(&mut self.spi, |bus| async {
302 bus.write(&[swap16(cmd), swap16(val)]).await?;
303 Ok(())
304 })
305 .await
306 .unwrap();
307 }
308}
309
310fn swap16(x: u32) -> u32 {
311 x.rotate_left(16)
312}
313
314fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 {
315 (write as u32) << 31 | (incr as u32) << 30 | (func & 0b11) << 28 | (addr & 0x1FFFF) << 11 | (len & 0x7FF)
316}
317
318fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
319 let len = x.len() * 4;
320 unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
321}
diff --git a/src/consts.rs b/src/consts.rs
new file mode 100644
index 000000000..bee706600
--- /dev/null
+++ b/src/consts.rs
@@ -0,0 +1,105 @@
1#![allow(unused)]
2pub(crate) const FUNC_BUS: u32 = 0;
3pub(crate) const FUNC_BACKPLANE: u32 = 1;
4pub(crate) const FUNC_WLAN: u32 = 2;
5pub(crate) const FUNC_BT: u32 = 3;
6
7pub(crate) const REG_BUS_CTRL: u32 = 0x0;
8pub(crate) const REG_BUS_INTERRUPT: u32 = 0x04; // 16 bits - Interrupt status
9pub(crate) const REG_BUS_INTERRUPT_ENABLE: u32 = 0x06; // 16 bits - Interrupt mask
10pub(crate) const REG_BUS_STATUS: u32 = 0x8;
11pub(crate) const REG_BUS_TEST_RO: u32 = 0x14;
12pub(crate) const REG_BUS_TEST_RW: u32 = 0x18;
13pub(crate) const REG_BUS_RESP_DELAY: u32 = 0x1c;
14pub(crate) const WORD_LENGTH_32: u32 = 0x1;
15pub(crate) const HIGH_SPEED: u32 = 0x10;
16
17// SPI_STATUS_REGISTER bits
18pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001;
19pub(crate) const STATUS_UNDERFLOW: u32 = 0x00000002;
20pub(crate) const STATUS_OVERFLOW: u32 = 0x00000004;
21pub(crate) const STATUS_F2_INTR: u32 = 0x00000008;
22pub(crate) const STATUS_F3_INTR: u32 = 0x00000010;
23pub(crate) const STATUS_F2_RX_READY: u32 = 0x00000020;
24pub(crate) const STATUS_F3_RX_READY: u32 = 0x00000040;
25pub(crate) const STATUS_HOST_CMD_DATA_ERR: u32 = 0x00000080;
26pub(crate) const STATUS_F2_PKT_AVAILABLE: u32 = 0x00000100;
27pub(crate) const STATUS_F2_PKT_LEN_MASK: u32 = 0x000FFE00;
28pub(crate) const STATUS_F2_PKT_LEN_SHIFT: u32 = 9;
29pub(crate) const STATUS_F3_PKT_AVAILABLE: u32 = 0x00100000;
30pub(crate) const STATUS_F3_PKT_LEN_MASK: u32 = 0xFFE00000;
31pub(crate) const STATUS_F3_PKT_LEN_SHIFT: u32 = 21;
32
33pub(crate) const REG_BACKPLANE_GPIO_SELECT: u32 = 0x10005;
34pub(crate) const REG_BACKPLANE_GPIO_OUTPUT: u32 = 0x10006;
35pub(crate) const REG_BACKPLANE_GPIO_ENABLE: u32 = 0x10007;
36pub(crate) const REG_BACKPLANE_FUNCTION2_WATERMARK: u32 = 0x10008;
37pub(crate) const REG_BACKPLANE_DEVICE_CONTROL: u32 = 0x10009;
38pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_LOW: u32 = 0x1000A;
39pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_MID: u32 = 0x1000B;
40pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH: u32 = 0x1000C;
41pub(crate) const REG_BACKPLANE_FRAME_CONTROL: u32 = 0x1000D;
42pub(crate) const REG_BACKPLANE_CHIP_CLOCK_CSR: u32 = 0x1000E;
43pub(crate) const REG_BACKPLANE_PULL_UP: u32 = 0x1000F;
44pub(crate) const REG_BACKPLANE_READ_FRAME_BC_LOW: u32 = 0x1001B;
45pub(crate) const REG_BACKPLANE_READ_FRAME_BC_HIGH: u32 = 0x1001C;
46pub(crate) const REG_BACKPLANE_WAKEUP_CTRL: u32 = 0x1001E;
47pub(crate) const REG_BACKPLANE_SLEEP_CSR: u32 = 0x1001F;
48
49pub(crate) const BACKPLANE_WINDOW_SIZE: usize = 0x8000;
50pub(crate) const BACKPLANE_ADDRESS_MASK: u32 = 0x7FFF;
51pub(crate) const BACKPLANE_ADDRESS_32BIT_FLAG: u32 = 0x08000;
52pub(crate) const BACKPLANE_MAX_TRANSFER_SIZE: usize = 64;
53// Active Low Power (ALP) clock constants
54pub(crate) const BACKPLANE_ALP_AVAIL_REQ: u8 = 0x08;
55pub(crate) const BACKPLANE_ALP_AVAIL: u8 = 0x40;
56
57// Broadcom AMBA (Advanced Microcontroller Bus Architecture) Interconnect
58// (AI) pub (crate) constants
59pub(crate) const AI_IOCTRL_OFFSET: u32 = 0x408;
60pub(crate) const AI_IOCTRL_BIT_FGC: u8 = 0x0002;
61pub(crate) const AI_IOCTRL_BIT_CLOCK_EN: u8 = 0x0001;
62pub(crate) const AI_IOCTRL_BIT_CPUHALT: u8 = 0x0020;
63
64pub(crate) const AI_RESETCTRL_OFFSET: u32 = 0x800;
65pub(crate) const AI_RESETCTRL_BIT_RESET: u8 = 1;
66
67pub(crate) const AI_RESETSTATUS_OFFSET: u32 = 0x804;
68
69pub(crate) const TEST_PATTERN: u32 = 0x12345678;
70pub(crate) const FEEDBEAD: u32 = 0xFEEDBEAD;
71
72// SPI_INTERRUPT_REGISTER and SPI_INTERRUPT_ENABLE_REGISTER Bits
73pub(crate) const IRQ_DATA_UNAVAILABLE: u16 = 0x0001; // Requested data not available; Clear by writing a "1"
74pub(crate) const IRQ_F2_F3_FIFO_RD_UNDERFLOW: u16 = 0x0002;
75pub(crate) const IRQ_F2_F3_FIFO_WR_OVERFLOW: u16 = 0x0004;
76pub(crate) const IRQ_COMMAND_ERROR: u16 = 0x0008; // Cleared by writing 1
77pub(crate) const IRQ_DATA_ERROR: u16 = 0x0010; // Cleared by writing 1
78pub(crate) const IRQ_F2_PACKET_AVAILABLE: u16 = 0x0020;
79pub(crate) const IRQ_F3_PACKET_AVAILABLE: u16 = 0x0040;
80pub(crate) const IRQ_F1_OVERFLOW: u16 = 0x0080; // Due to last write. Bkplane has pending write requests
81pub(crate) const IRQ_MISC_INTR0: u16 = 0x0100;
82pub(crate) const IRQ_MISC_INTR1: u16 = 0x0200;
83pub(crate) const IRQ_MISC_INTR2: u16 = 0x0400;
84pub(crate) const IRQ_MISC_INTR3: u16 = 0x0800;
85pub(crate) const IRQ_MISC_INTR4: u16 = 0x1000;
86pub(crate) const IRQ_F1_INTR: u16 = 0x2000;
87pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
88pub(crate) const IRQ_F3_INTR: u16 = 0x8000;
89
90pub(crate) const IOCTL_CMD_UP: u32 = 2;
91pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26;
92pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64;
93pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263;
94pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262;
95pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268;
96
97pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0;
98pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1;
99pub(crate) const CHANNEL_TYPE_DATA: u8 = 2;
100
101// CYW_SPID command structure constants.
102pub(crate) const WRITE: bool = true;
103pub(crate) const READ: bool = false;
104pub(crate) const INC_ADDR: bool = true;
105pub(crate) const FIXED_ADDR: bool = false;
diff --git a/src/lib.rs b/src/lib.rs
index 883e669de..fa73b32e0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,6 +6,8 @@
6// This mod MUST go first, so that the others see its macros. 6// This mod MUST go first, so that the others see its macros.
7pub(crate) mod fmt; 7pub(crate) mod fmt;
8 8
9mod bus;
10mod consts;
9mod countries; 11mod countries;
10mod events; 12mod events;
11mod structs; 13mod structs;
@@ -23,132 +25,12 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex;
23use embassy_sync::channel::Channel; 25use embassy_sync::channel::Channel;
24use embassy_time::{block_for, Duration, Timer}; 26use embassy_time::{block_for, Duration, Timer};
25use embedded_hal_1::digital::OutputPin; 27use embedded_hal_1::digital::OutputPin;
26use embedded_hal_async::spi::{transaction, SpiBusRead, SpiBusWrite, SpiDevice}; 28use embedded_hal_async::spi::{SpiBusRead, SpiBusWrite, SpiDevice};
27 29
28use self::structs::*; 30use crate::bus::Bus;
31use crate::consts::*;
29use crate::events::Event; 32use crate::events::Event;
30 33use crate::structs::*;
31fn swap16(x: u32) -> u32 {
32 x.rotate_left(16)
33}
34
35fn cmd_word(write: bool, incr: bool, func: u32, addr: u32, len: u32) -> u32 {
36 (write as u32) << 31 | (incr as u32) << 30 | (func & 0b11) << 28 | (addr & 0x1FFFF) << 11 | (len & 0x7FF)
37}
38
39fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
40 let len = x.len() * 4;
41 unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
42}
43
44mod constants {
45 #![allow(unused)]
46 pub(crate) const FUNC_BUS: u32 = 0;
47 pub(crate) const FUNC_BACKPLANE: u32 = 1;
48 pub(crate) const FUNC_WLAN: u32 = 2;
49 pub(crate) const FUNC_BT: u32 = 3;
50
51 pub(crate) const REG_BUS_CTRL: u32 = 0x0;
52 pub(crate) const REG_BUS_INTERRUPT: u32 = 0x04; // 16 bits - Interrupt status
53 pub(crate) const REG_BUS_INTERRUPT_ENABLE: u32 = 0x06; // 16 bits - Interrupt mask
54 pub(crate) const REG_BUS_STATUS: u32 = 0x8;
55 pub(crate) const REG_BUS_TEST_RO: u32 = 0x14;
56 pub(crate) const REG_BUS_TEST_RW: u32 = 0x18;
57 pub(crate) const REG_BUS_RESP_DELAY: u32 = 0x1c;
58 pub(crate) const WORD_LENGTH_32: u32 = 0x1;
59 pub(crate) const HIGH_SPEED: u32 = 0x10;
60
61 // SPI_STATUS_REGISTER bits
62 pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001;
63 pub(crate) const STATUS_UNDERFLOW: u32 = 0x00000002;
64 pub(crate) const STATUS_OVERFLOW: u32 = 0x00000004;
65 pub(crate) const STATUS_F2_INTR: u32 = 0x00000008;
66 pub(crate) const STATUS_F3_INTR: u32 = 0x00000010;
67 pub(crate) const STATUS_F2_RX_READY: u32 = 0x00000020;
68 pub(crate) const STATUS_F3_RX_READY: u32 = 0x00000040;
69 pub(crate) const STATUS_HOST_CMD_DATA_ERR: u32 = 0x00000080;
70 pub(crate) const STATUS_F2_PKT_AVAILABLE: u32 = 0x00000100;
71 pub(crate) const STATUS_F2_PKT_LEN_MASK: u32 = 0x000FFE00;
72 pub(crate) const STATUS_F2_PKT_LEN_SHIFT: u32 = 9;
73 pub(crate) const STATUS_F3_PKT_AVAILABLE: u32 = 0x00100000;
74 pub(crate) const STATUS_F3_PKT_LEN_MASK: u32 = 0xFFE00000;
75 pub(crate) const STATUS_F3_PKT_LEN_SHIFT: u32 = 21;
76
77 pub(crate) const REG_BACKPLANE_GPIO_SELECT: u32 = 0x10005;
78 pub(crate) const REG_BACKPLANE_GPIO_OUTPUT: u32 = 0x10006;
79 pub(crate) const REG_BACKPLANE_GPIO_ENABLE: u32 = 0x10007;
80 pub(crate) const REG_BACKPLANE_FUNCTION2_WATERMARK: u32 = 0x10008;
81 pub(crate) const REG_BACKPLANE_DEVICE_CONTROL: u32 = 0x10009;
82 pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_LOW: u32 = 0x1000A;
83 pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_MID: u32 = 0x1000B;
84 pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH: u32 = 0x1000C;
85 pub(crate) const REG_BACKPLANE_FRAME_CONTROL: u32 = 0x1000D;
86 pub(crate) const REG_BACKPLANE_CHIP_CLOCK_CSR: u32 = 0x1000E;
87 pub(crate) const REG_BACKPLANE_PULL_UP: u32 = 0x1000F;
88 pub(crate) const REG_BACKPLANE_READ_FRAME_BC_LOW: u32 = 0x1001B;
89 pub(crate) const REG_BACKPLANE_READ_FRAME_BC_HIGH: u32 = 0x1001C;
90 pub(crate) const REG_BACKPLANE_WAKEUP_CTRL: u32 = 0x1001E;
91 pub(crate) const REG_BACKPLANE_SLEEP_CSR: u32 = 0x1001F;
92
93 pub(crate) const BACKPLANE_WINDOW_SIZE: usize = 0x8000;
94 pub(crate) const BACKPLANE_ADDRESS_MASK: u32 = 0x7FFF;
95 pub(crate) const BACKPLANE_ADDRESS_32BIT_FLAG: u32 = 0x08000;
96 pub(crate) const BACKPLANE_MAX_TRANSFER_SIZE: usize = 64;
97 // Active Low Power (ALP) clock constants
98 pub(crate) const BACKPLANE_ALP_AVAIL_REQ: u8 = 0x08;
99 pub(crate) const BACKPLANE_ALP_AVAIL: u8 = 0x40;
100
101 // Broadcom AMBA (Advanced Microcontroller Bus Architecture) Interconnect
102 // (AI) pub (crate) constants
103 pub(crate) const AI_IOCTRL_OFFSET: u32 = 0x408;
104 pub(crate) const AI_IOCTRL_BIT_FGC: u8 = 0x0002;
105 pub(crate) const AI_IOCTRL_BIT_CLOCK_EN: u8 = 0x0001;
106 pub(crate) const AI_IOCTRL_BIT_CPUHALT: u8 = 0x0020;
107
108 pub(crate) const AI_RESETCTRL_OFFSET: u32 = 0x800;
109 pub(crate) const AI_RESETCTRL_BIT_RESET: u8 = 1;
110
111 pub(crate) const AI_RESETSTATUS_OFFSET: u32 = 0x804;
112
113 pub(crate) const TEST_PATTERN: u32 = 0x12345678;
114 pub(crate) const FEEDBEAD: u32 = 0xFEEDBEAD;
115
116 // SPI_INTERRUPT_REGISTER and SPI_INTERRUPT_ENABLE_REGISTER Bits
117 pub(crate) const IRQ_DATA_UNAVAILABLE: u16 = 0x0001; // Requested data not available; Clear by writing a "1"
118 pub(crate) const IRQ_F2_F3_FIFO_RD_UNDERFLOW: u16 = 0x0002;
119 pub(crate) const IRQ_F2_F3_FIFO_WR_OVERFLOW: u16 = 0x0004;
120 pub(crate) const IRQ_COMMAND_ERROR: u16 = 0x0008; // Cleared by writing 1
121 pub(crate) const IRQ_DATA_ERROR: u16 = 0x0010; // Cleared by writing 1
122 pub(crate) const IRQ_F2_PACKET_AVAILABLE: u16 = 0x0020;
123 pub(crate) const IRQ_F3_PACKET_AVAILABLE: u16 = 0x0040;
124 pub(crate) const IRQ_F1_OVERFLOW: u16 = 0x0080; // Due to last write. Bkplane has pending write requests
125 pub(crate) const IRQ_MISC_INTR0: u16 = 0x0100;
126 pub(crate) const IRQ_MISC_INTR1: u16 = 0x0200;
127 pub(crate) const IRQ_MISC_INTR2: u16 = 0x0400;
128 pub(crate) const IRQ_MISC_INTR3: u16 = 0x0800;
129 pub(crate) const IRQ_MISC_INTR4: u16 = 0x1000;
130 pub(crate) const IRQ_F1_INTR: u16 = 0x2000;
131 pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
132 pub(crate) const IRQ_F3_INTR: u16 = 0x8000;
133
134 pub(crate) const IOCTL_CMD_UP: u32 = 2;
135 pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26;
136 pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64;
137 pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263;
138 pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262;
139 pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268;
140
141 pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0;
142 pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1;
143 pub(crate) const CHANNEL_TYPE_DATA: u8 = 2;
144
145 // CYW_SPID command structure constants.
146 pub(crate) const WRITE: bool = true;
147 pub(crate) const READ: bool = false;
148 pub(crate) const INC_ADDR: bool = true;
149 pub(crate) const FIXED_ADDR: bool = false;
150}
151use crate::constants::*;
152 34
153#[derive(Clone, Copy)] 35#[derive(Clone, Copy)]
154pub enum IoctlType { 36pub enum IoctlType {
@@ -565,15 +447,11 @@ impl<'a> embassy_net::Device for NetDevice<'a> {
565} 447}
566 448
567pub struct Runner<'a, PWR, SPI> { 449pub struct Runner<'a, PWR, SPI> {
568 state: &'a State, 450 bus: Bus<PWR, SPI>,
569
570 pwr: PWR,
571 spi: SPI,
572 451
452 state: &'a State,
573 ioctl_id: u16, 453 ioctl_id: u16,
574 sdpcm_seq: u8, 454 sdpcm_seq: u8,
575 backplane_window: u32,
576
577 sdpcm_seq_max: u8, 455 sdpcm_seq_max: u8,
578 456
579 #[cfg(feature = "firmware-logs")] 457 #[cfg(feature = "firmware-logs")]
@@ -600,14 +478,11 @@ where
600 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>, 478 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
601{ 479{
602 let mut runner = Runner { 480 let mut runner = Runner {
603 state, 481 bus: Bus::new(pwr, spi),
604 pwr,
605 spi,
606 482
483 state,
607 ioctl_id: 0, 484 ioctl_id: 0,
608 sdpcm_seq: 0, 485 sdpcm_seq: 0,
609 backplane_window: 0xAAAA_AAAA,
610
611 sdpcm_seq_max: 1, 486 sdpcm_seq_max: 1,
612 487
613 #[cfg(feature = "firmware-logs")] 488 #[cfg(feature = "firmware-logs")]
@@ -631,62 +506,41 @@ where
631 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>, 506 SPI::Bus: SpiBusRead<u32> + SpiBusWrite<u32>,
632{ 507{
633 async fn init(&mut self, firmware: &[u8]) { 508 async fn init(&mut self, firmware: &[u8]) {
634 // Reset 509 self.bus.init().await;
635 self.pwr.set_low().unwrap();
636 Timer::after(Duration::from_millis(20)).await;
637 self.pwr.set_high().unwrap();
638 Timer::after(Duration::from_millis(250)).await;
639
640 info!("waiting for ping...");
641 while self.read32_swapped(REG_BUS_TEST_RO).await != FEEDBEAD {}
642 info!("ping ok");
643
644 self.write32_swapped(REG_BUS_TEST_RW, TEST_PATTERN).await;
645 let val = self.read32_swapped(REG_BUS_TEST_RW).await;
646 assert_eq!(val, TEST_PATTERN);
647
648 // 32-bit word length, little endian (which is the default endianess).
649 self.write32_swapped(REG_BUS_CTRL, WORD_LENGTH_32 | HIGH_SPEED).await;
650
651 let val = self.read32(FUNC_BUS, REG_BUS_TEST_RO).await;
652 assert_eq!(val, FEEDBEAD);
653 let val = self.read32(FUNC_BUS, REG_BUS_TEST_RW).await;
654 assert_eq!(val, TEST_PATTERN);
655
656 // No response delay in any of the funcs.
657 // seems to break backplane??? eat the 4-byte delay instead, that's what the vendor drivers do...
658 //self.write32(FUNC_BUS, REG_BUS_RESP_DELAY, 0).await;
659 510
660 // Init ALP (Active Low Power) clock 511 // Init ALP (Active Low Power) clock
661 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, BACKPLANE_ALP_AVAIL_REQ) 512 self.bus
513 .write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, BACKPLANE_ALP_AVAIL_REQ)
662 .await; 514 .await;
663 info!("waiting for clock..."); 515 info!("waiting for clock...");
664 while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & BACKPLANE_ALP_AVAIL == 0 {} 516 while self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & BACKPLANE_ALP_AVAIL == 0 {}
665 info!("clock ok"); 517 info!("clock ok");
666 518
667 let chip_id = self.bp_read16(0x1800_0000).await; 519 let chip_id = self.bus.bp_read16(0x1800_0000).await;
668 info!("chip ID: {}", chip_id); 520 info!("chip ID: {}", chip_id);
669 521
670 // Upload firmware. 522 // Upload firmware.
671 self.core_disable(Core::WLAN).await; 523 self.core_disable(Core::WLAN).await;
672 self.core_reset(Core::SOCSRAM).await; 524 self.core_reset(Core::SOCSRAM).await;
673 self.bp_write32(CHIP.socsram_base_address + 0x10, 3).await; 525 self.bus.bp_write32(CHIP.socsram_base_address + 0x10, 3).await;
674 self.bp_write32(CHIP.socsram_base_address + 0x44, 0).await; 526 self.bus.bp_write32(CHIP.socsram_base_address + 0x44, 0).await;
675 527
676 let ram_addr = CHIP.atcm_ram_base_address; 528 let ram_addr = CHIP.atcm_ram_base_address;
677 529
678 info!("loading fw"); 530 info!("loading fw");
679 self.bp_write(ram_addr, firmware).await; 531 self.bus.bp_write(ram_addr, firmware).await;
680 532
681 info!("loading nvram"); 533 info!("loading nvram");
682 // Round up to 4 bytes. 534 // Round up to 4 bytes.
683 let nvram_len = (NVRAM.len() + 3) / 4 * 4; 535 let nvram_len = (NVRAM.len() + 3) / 4 * 4;
684 self.bp_write(ram_addr + CHIP.chip_ram_size - 4 - nvram_len as u32, NVRAM) 536 self.bus
537 .bp_write(ram_addr + CHIP.chip_ram_size - 4 - nvram_len as u32, NVRAM)
685 .await; 538 .await;
686 539
687 let nvram_len_words = nvram_len as u32 / 4; 540 let nvram_len_words = nvram_len as u32 / 4;
688 let nvram_len_magic = (!nvram_len_words << 16) | nvram_len_words; 541 let nvram_len_magic = (!nvram_len_words << 16) | nvram_len_words;
689 self.bp_write32(ram_addr + CHIP.chip_ram_size - 4, nvram_len_magic) 542 self.bus
543 .bp_write32(ram_addr + CHIP.chip_ram_size - 4, nvram_len_magic)
690 .await; 544 .await;
691 545
692 // Start core! 546 // Start core!
@@ -694,18 +548,20 @@ where
694 self.core_reset(Core::WLAN).await; 548 self.core_reset(Core::WLAN).await;
695 assert!(self.core_is_up(Core::WLAN).await); 549 assert!(self.core_is_up(Core::WLAN).await);
696 550
697 while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} 551 while self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {}
698 552
699 // "Set up the interrupt mask and enable interrupts" 553 // "Set up the interrupt mask and enable interrupts"
700 self.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0).await; 554 self.bus.bp_write32(CHIP.sdiod_core_base_address + 0x24, 0xF0).await;
701 555
702 // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped." 556 // "Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped."
703 // Sounds scary... 557 // Sounds scary...
704 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_FUNCTION2_WATERMARK, 32).await; 558 self.bus
559 .write8(FUNC_BACKPLANE, REG_BACKPLANE_FUNCTION2_WATERMARK, 32)
560 .await;
705 561
706 // wait for wifi startup 562 // wait for wifi startup
707 info!("waiting for wifi init..."); 563 info!("waiting for wifi init...");
708 while self.read32(FUNC_BUS, REG_BUS_STATUS).await & STATUS_F2_RX_READY == 0 {} 564 while self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await & STATUS_F2_RX_READY == 0 {}
709 565
710 // Some random configs related to sleep. 566 // Some random configs related to sleep.
711 // These aren't needed if we don't want to sleep the bus. 567 // These aren't needed if we don't want to sleep the bus.
@@ -713,25 +569,25 @@ where
713 // being on the same pin as MOSI/MISO? 569 // being on the same pin as MOSI/MISO?
714 570
715 /* 571 /*
716 let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL).await; 572 let mut val = self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL).await;
717 val |= 0x02; // WAKE_TILL_HT_AVAIL 573 val |= 0x02; // WAKE_TILL_HT_AVAIL
718 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL, val).await; 574 self.bus.write8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL, val).await;
719 self.write8(FUNC_BUS, 0xF0, 0x08).await; // SDIOD_CCCR_BRCM_CARDCAP.CMD_NODEC = 1 575 self.bus.write8(FUNC_BUS, 0xF0, 0x08).await; // SDIOD_CCCR_BRCM_CARDCAP.CMD_NODEC = 1
720 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x02).await; // SBSDIO_FORCE_HT 576 self.bus.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x02).await; // SBSDIO_FORCE_HT
721 577
722 let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR).await; 578 let mut val = self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR).await;
723 val |= 0x01; // SBSDIO_SLPCSR_KEEP_SDIO_ON 579 val |= 0x01; // SBSDIO_SLPCSR_KEEP_SDIO_ON
724 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR, val).await; 580 self.bus.write8(FUNC_BACKPLANE, REG_BACKPLANE_SLEEP_CSR, val).await;
725 */ 581 */
726 582
727 // clear pulls 583 // clear pulls
728 self.write8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP, 0).await; 584 self.bus.write8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP, 0).await;
729 let _ = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP).await; 585 let _ = self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_PULL_UP).await;
730 586
731 // start HT clock 587 // start HT clock
732 //self.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x10).await; 588 //self.bus.write8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR, 0x10).await;
733 //info!("waiting for HT clock..."); 589 //info!("waiting for HT clock...");
734 //while self.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {} 590 //while self.bus.read8(FUNC_BACKPLANE, REG_BACKPLANE_CHIP_CLOCK_CSR).await & 0x80 == 0 {}
735 //info!("clock ok"); 591 //info!("clock ok");
736 592
737 #[cfg(feature = "firmware-logs")] 593 #[cfg(feature = "firmware-logs")]
@@ -744,13 +600,12 @@ where
744 async fn log_init(&mut self) { 600 async fn log_init(&mut self) {
745 // Initialize shared memory for logging. 601 // Initialize shared memory for logging.
746 602
747 let shared_addr = self 603 let addr = CHIP.atcm_ram_base_address + CHIP.chip_ram_size - 4 - CHIP.socram_srmem_size;
748 .bp_read32(CHIP.atcm_ram_base_address + CHIP.chip_ram_size - 4 - CHIP.socram_srmem_size) 604 let shared_addr = self.bus.bp_read32(addr).await;
749 .await;
750 info!("shared_addr {:08x}", shared_addr); 605 info!("shared_addr {:08x}", shared_addr);
751 606
752 let mut shared = [0; SharedMemData::SIZE]; 607 let mut shared = [0; SharedMemData::SIZE];
753 self.bp_read(shared_addr, &mut shared).await; 608 self.bus.bp_read(shared_addr, &mut shared).await;
754 let shared = SharedMemData::from_bytes(&shared); 609 let shared = SharedMemData::from_bytes(&shared);
755 info!("shared: {:08x}", shared); 610 info!("shared: {:08x}", shared);
756 611
@@ -761,7 +616,7 @@ where
761 async fn log_read(&mut self) { 616 async fn log_read(&mut self) {
762 // Read log struct 617 // Read log struct
763 let mut log = [0; SharedMemLog::SIZE]; 618 let mut log = [0; SharedMemLog::SIZE];
764 self.bp_read(self.log.addr, &mut log).await; 619 self.bus.bp_read(self.log.addr, &mut log).await;
765 let log = SharedMemLog::from_bytes(&log); 620 let log = SharedMemLog::from_bytes(&log);
766 621
767 let idx = log.idx as usize; 622 let idx = log.idx as usize;
@@ -774,7 +629,7 @@ where
774 // Read entire buf for now. We could read only what we need, but then we 629 // Read entire buf for now. We could read only what we need, but then we
775 // run into annoying alignment issues in `bp_read`. 630 // run into annoying alignment issues in `bp_read`.
776 let mut buf = [0; 0x400]; 631 let mut buf = [0; 0x400];
777 self.bp_read(log.buf, &mut buf).await; 632 self.bus.bp_read(log.buf, &mut buf).await;
778 633
779 while self.log.last_idx != idx as usize { 634 while self.log.last_idx != idx as usize {
780 let b = buf[self.log.last_idx]; 635 let b = buf[self.log.last_idx];
@@ -821,29 +676,19 @@ where
821 } 676 }
822 677
823 // Receive stuff 678 // Receive stuff
824 let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT).await; 679 let irq = self.bus.read16(FUNC_BUS, REG_BUS_INTERRUPT).await;
825 680
826 if irq & IRQ_F2_PACKET_AVAILABLE != 0 { 681 if irq & IRQ_F2_PACKET_AVAILABLE != 0 {
827 let mut status = 0xFFFF_FFFF; 682 let mut status = 0xFFFF_FFFF;
828 while status == 0xFFFF_FFFF { 683 while status == 0xFFFF_FFFF {
829 status = self.read32(FUNC_BUS, REG_BUS_STATUS).await; 684 status = self.bus.read32(FUNC_BUS, REG_BUS_STATUS).await;
830 } 685 }
831 686
832 if status & STATUS_F2_PKT_AVAILABLE != 0 { 687 if status & STATUS_F2_PKT_AVAILABLE != 0 {
833 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT; 688 let len = (status & STATUS_F2_PKT_LEN_MASK) >> STATUS_F2_PKT_LEN_SHIFT;
834 689
835 let cmd = cmd_word(READ, INC_ADDR, FUNC_WLAN, 0, len); 690 self.bus.wlan_read(&mut buf[..(len as usize + 3) / 4]).await;
836
837 transaction!(&mut self.spi, |bus| async {
838 bus.write(&[cmd]).await?;
839 bus.read(&mut buf[..(len as usize + 3) / 4]).await?;
840 Ok(())
841 })
842 .await
843 .unwrap();
844
845 trace!("rx {:02x}", &slice8_mut(&mut buf)[..(len as usize).min(48)]); 691 trace!("rx {:02x}", &slice8_mut(&mut buf)[..(len as usize).min(48)]);
846
847 self.rx(&slice8_mut(&mut buf)[..len as usize]); 692 self.rx(&slice8_mut(&mut buf)[..len as usize]);
848 } 693 }
849 } 694 }
@@ -893,14 +738,7 @@ where
893 738
894 trace!(" {:02x}", &buf8[..total_len.min(48)]); 739 trace!(" {:02x}", &buf8[..total_len.min(48)]);
895 740
896 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_WLAN, 0, total_len as _); 741 self.bus.wlan_write(&buf[..(total_len / 4)]).await;
897 transaction!(&mut self.spi, |bus| async {
898 bus.write(&[cmd]).await?;
899 bus.write(&buf[..(total_len / 4)]).await?;
900 Ok(())
901 })
902 .await
903 .unwrap();
904 } 742 }
905 743
906 fn rx(&mut self, packet: &[u8]) { 744 fn rx(&mut self, packet: &[u8]) {
@@ -1086,52 +924,49 @@ where
1086 924
1087 trace!(" {:02x}", &buf8[..total_len.min(48)]); 925 trace!(" {:02x}", &buf8[..total_len.min(48)]);
1088 926
1089 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_WLAN, 0, total_len as _); 927 self.bus.wlan_write(&buf[..total_len / 4]).await;
1090
1091 transaction!(&mut self.spi, |bus| async {
1092 bus.write(&[cmd]).await?;
1093 bus.write(&buf[..total_len / 4]).await?;
1094 Ok(())
1095 })
1096 .await
1097 .unwrap();
1098 } 928 }
1099 929
1100 async fn core_disable(&mut self, core: Core) { 930 async fn core_disable(&mut self, core: Core) {
1101 let base = core.base_addr(); 931 let base = core.base_addr();
1102 932
1103 // Dummy read? 933 // Dummy read?
1104 let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; 934 let _ = self.bus.bp_read8(base + AI_RESETCTRL_OFFSET).await;
1105 935
1106 // Check it isn't already reset 936 // Check it isn't already reset
1107 let r = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; 937 let r = self.bus.bp_read8(base + AI_RESETCTRL_OFFSET).await;
1108 if r & AI_RESETCTRL_BIT_RESET != 0 { 938 if r & AI_RESETCTRL_BIT_RESET != 0 {
1109 return; 939 return;
1110 } 940 }
1111 941
1112 self.bp_write8(base + AI_IOCTRL_OFFSET, 0).await; 942 self.bus.bp_write8(base + AI_IOCTRL_OFFSET, 0).await;
1113 let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; 943 let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
1114 944
1115 block_for(Duration::from_millis(1)); 945 block_for(Duration::from_millis(1));
1116 946
1117 self.bp_write8(base + AI_RESETCTRL_OFFSET, AI_RESETCTRL_BIT_RESET).await; 947 self.bus
1118 let _ = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; 948 .bp_write8(base + AI_RESETCTRL_OFFSET, AI_RESETCTRL_BIT_RESET)
949 .await;
950 let _ = self.bus.bp_read8(base + AI_RESETCTRL_OFFSET).await;
1119 } 951 }
1120 952
1121 async fn core_reset(&mut self, core: Core) { 953 async fn core_reset(&mut self, core: Core) {
1122 self.core_disable(core).await; 954 self.core_disable(core).await;
1123 955
1124 let base = core.base_addr(); 956 let base = core.base_addr();
1125 self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) 957 self.bus
958 .bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN)
1126 .await; 959 .await;
1127 let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; 960 let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
1128 961
1129 self.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await; 962 self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await;
1130 963
1131 Timer::after(Duration::from_millis(1)).await; 964 Timer::after(Duration::from_millis(1)).await;
1132 965
1133 self.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN).await; 966 self.bus
1134 let _ = self.bp_read8(base + AI_IOCTRL_OFFSET).await; 967 .bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN)
968 .await;
969 let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
1135 970
1136 Timer::after(Duration::from_millis(1)).await; 971 Timer::after(Duration::from_millis(1)).await;
1137 } 972 }
@@ -1139,13 +974,13 @@ where
1139 async fn core_is_up(&mut self, core: Core) -> bool { 974 async fn core_is_up(&mut self, core: Core) -> bool {
1140 let base = core.base_addr(); 975 let base = core.base_addr();
1141 976
1142 let io = self.bp_read8(base + AI_IOCTRL_OFFSET).await; 977 let io = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
1143 if io & (AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) != AI_IOCTRL_BIT_CLOCK_EN { 978 if io & (AI_IOCTRL_BIT_FGC | AI_IOCTRL_BIT_CLOCK_EN) != AI_IOCTRL_BIT_CLOCK_EN {
1144 debug!("core_is_up: returning false due to bad ioctrl {:02x}", io); 979 debug!("core_is_up: returning false due to bad ioctrl {:02x}", io);
1145 return false; 980 return false;
1146 } 981 }
1147 982
1148 let r = self.bp_read8(base + AI_RESETCTRL_OFFSET).await; 983 let r = self.bus.bp_read8(base + AI_RESETCTRL_OFFSET).await;
1149 if r & (AI_RESETCTRL_BIT_RESET) != 0 { 984 if r & (AI_RESETCTRL_BIT_RESET) != 0 {
1150 debug!("core_is_up: returning false due to bad resetctrl {:02x}", r); 985 debug!("core_is_up: returning false due to bad resetctrl {:02x}", r);
1151 return false; 986 return false;
@@ -1153,242 +988,11 @@ where
1153 988
1154 true 989 true
1155 } 990 }
991}
1156 992
1157 #[allow(unused)] 993fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
1158 async fn bp_read(&mut self, mut addr: u32, mut data: &mut [u8]) { 994 let len = x.len() * 4;
1159 // It seems the HW force-aligns the addr 995 unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
1160 // to 2 if data.len() >= 2
1161 // to 4 if data.len() >= 4
1162 // To simplify, enforce 4-align for now.
1163 assert!(addr % 4 == 0);
1164
1165 let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4];
1166
1167 while !data.is_empty() {
1168 // Ensure transfer doesn't cross a window boundary.
1169 let window_offs = addr & BACKPLANE_ADDRESS_MASK;
1170 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize;
1171
1172 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining);
1173
1174 self.backplane_set_window(addr).await;
1175
1176 let cmd = cmd_word(READ, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32);
1177
1178 transaction!(&mut self.spi, |bus| async {
1179 bus.write(&[cmd]).await?;
1180
1181 // 4-byte response delay.
1182 let mut junk = [0; 1];
1183 bus.read(&mut junk).await?;
1184
1185 // Read data
1186 bus.read(&mut buf[..(len + 3) / 4]).await?;
1187 Ok(())
1188 })
1189 .await
1190 .unwrap();
1191
1192 data[..len].copy_from_slice(&slice8_mut(&mut buf)[..len]);
1193
1194 // Advance ptr.
1195 addr += len as u32;
1196 data = &mut data[len..];
1197 }
1198 }
1199
1200 async fn bp_write(&mut self, mut addr: u32, mut data: &[u8]) {
1201 // It seems the HW force-aligns the addr
1202 // to 2 if data.len() >= 2
1203 // to 4 if data.len() >= 4
1204 // To simplify, enforce 4-align for now.
1205 assert!(addr % 4 == 0);
1206
1207 let mut buf = [0u32; BACKPLANE_MAX_TRANSFER_SIZE / 4];
1208
1209 while !data.is_empty() {
1210 // Ensure transfer doesn't cross a window boundary.
1211 let window_offs = addr & BACKPLANE_ADDRESS_MASK;
1212 let window_remaining = BACKPLANE_WINDOW_SIZE - window_offs as usize;
1213
1214 let len = data.len().min(BACKPLANE_MAX_TRANSFER_SIZE).min(window_remaining);
1215 slice8_mut(&mut buf)[..len].copy_from_slice(&data[..len]);
1216
1217 self.backplane_set_window(addr).await;
1218
1219 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BACKPLANE, window_offs, len as u32);
1220
1221 transaction!(&mut self.spi, |bus| async {
1222 bus.write(&[cmd]).await?;
1223 bus.write(&buf[..(len + 3) / 4]).await?;
1224 Ok(())
1225 })
1226 .await
1227 .unwrap();
1228
1229 // Advance ptr.
1230 addr += len as u32;
1231 data = &data[len..];
1232 }
1233 }
1234
1235 async fn bp_read8(&mut self, addr: u32) -> u8 {
1236 self.backplane_readn(addr, 1).await as u8
1237 }
1238
1239 async fn bp_write8(&mut self, addr: u32, val: u8) {
1240 self.backplane_writen(addr, val as u32, 1).await
1241 }
1242
1243 async fn bp_read16(&mut self, addr: u32) -> u16 {
1244 self.backplane_readn(addr, 2).await as u16
1245 }
1246
1247 #[allow(unused)]
1248 async fn bp_write16(&mut self, addr: u32, val: u16) {
1249 self.backplane_writen(addr, val as u32, 2).await
1250 }
1251
1252 #[allow(unused)]
1253 async fn bp_read32(&mut self, addr: u32) -> u32 {
1254 self.backplane_readn(addr, 4).await
1255 }
1256
1257 async fn bp_write32(&mut self, addr: u32, val: u32) {
1258 self.backplane_writen(addr, val, 4).await
1259 }
1260
1261 async fn backplane_readn(&mut self, addr: u32, len: u32) -> u32 {
1262 self.backplane_set_window(addr).await;
1263
1264 let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK;
1265 if len == 4 {
1266 bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG
1267 }
1268 self.readn(FUNC_BACKPLANE, bus_addr, len).await
1269 }
1270
1271 async fn backplane_writen(&mut self, addr: u32, val: u32, len: u32) {
1272 self.backplane_set_window(addr).await;
1273
1274 let mut bus_addr = addr & BACKPLANE_ADDRESS_MASK;
1275 if len == 4 {
1276 bus_addr |= BACKPLANE_ADDRESS_32BIT_FLAG
1277 }
1278 self.writen(FUNC_BACKPLANE, bus_addr, val, len).await
1279 }
1280
1281 async fn backplane_set_window(&mut self, addr: u32) {
1282 let new_window = addr & !BACKPLANE_ADDRESS_MASK;
1283
1284 if (new_window >> 24) as u8 != (self.backplane_window >> 24) as u8 {
1285 self.write8(
1286 FUNC_BACKPLANE,
1287 REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH,
1288 (new_window >> 24) as u8,
1289 )
1290 .await;
1291 }
1292 if (new_window >> 16) as u8 != (self.backplane_window >> 16) as u8 {
1293 self.write8(
1294 FUNC_BACKPLANE,
1295 REG_BACKPLANE_BACKPLANE_ADDRESS_MID,
1296 (new_window >> 16) as u8,
1297 )
1298 .await;
1299 }
1300 if (new_window >> 8) as u8 != (self.backplane_window >> 8) as u8 {
1301 self.write8(
1302 FUNC_BACKPLANE,
1303 REG_BACKPLANE_BACKPLANE_ADDRESS_LOW,
1304 (new_window >> 8) as u8,
1305 )
1306 .await;
1307 }
1308 self.backplane_window = new_window;
1309 }
1310
1311 async fn read8(&mut self, func: u32, addr: u32) -> u8 {
1312 self.readn(func, addr, 1).await as u8
1313 }
1314
1315 async fn write8(&mut self, func: u32, addr: u32, val: u8) {
1316 self.writen(func, addr, val as u32, 1).await
1317 }
1318
1319 async fn read16(&mut self, func: u32, addr: u32) -> u16 {
1320 self.readn(func, addr, 2).await as u16
1321 }
1322
1323 #[allow(unused)]
1324 async fn write16(&mut self, func: u32, addr: u32, val: u16) {
1325 self.writen(func, addr, val as u32, 2).await
1326 }
1327
1328 async fn read32(&mut self, func: u32, addr: u32) -> u32 {
1329 self.readn(func, addr, 4).await
1330 }
1331
1332 #[allow(unused)]
1333 async fn write32(&mut self, func: u32, addr: u32, val: u32) {
1334 self.writen(func, addr, val, 4).await
1335 }
1336
1337 async fn readn(&mut self, func: u32, addr: u32, len: u32) -> u32 {
1338 let cmd = cmd_word(READ, INC_ADDR, func, addr, len);
1339 let mut buf = [0; 1];
1340
1341 transaction!(&mut self.spi, |bus| async {
1342 bus.write(&[cmd]).await?;
1343 if func == FUNC_BACKPLANE {
1344 // 4-byte response delay.
1345 bus.read(&mut buf).await?;
1346 }
1347 bus.read(&mut buf).await?;
1348 Ok(())
1349 })
1350 .await
1351 .unwrap();
1352
1353 buf[0]
1354 }
1355
1356 async fn writen(&mut self, func: u32, addr: u32, val: u32, len: u32) {
1357 let cmd = cmd_word(WRITE, INC_ADDR, func, addr, len);
1358
1359 transaction!(&mut self.spi, |bus| async {
1360 bus.write(&[cmd, val]).await?;
1361 Ok(())
1362 })
1363 .await
1364 .unwrap();
1365 }
1366
1367 async fn read32_swapped(&mut self, addr: u32) -> u32 {
1368 let cmd = cmd_word(READ, INC_ADDR, FUNC_BUS, addr, 4);
1369 let mut buf = [0; 1];
1370
1371 transaction!(&mut self.spi, |bus| async {
1372 bus.write(&[swap16(cmd)]).await?;
1373 bus.read(&mut buf).await?;
1374 Ok(())
1375 })
1376 .await
1377 .unwrap();
1378
1379 swap16(buf[0])
1380 }
1381
1382 async fn write32_swapped(&mut self, addr: u32, val: u32) {
1383 let cmd = cmd_word(WRITE, INC_ADDR, FUNC_BUS, addr, 4);
1384
1385 transaction!(&mut self.spi, |bus| async {
1386 bus.write(&[swap16(cmd), swap16(val)]).await?;
1387 Ok(())
1388 })
1389 .await
1390 .unwrap();
1391 }
1392} 996}
1393 997
1394macro_rules! nvram { 998macro_rules! nvram {