aboutsummaryrefslogtreecommitdiff
path: root/cyw43/src/consts.rs
blob: b6e22e61dbf7bc0376849cbb4b05fd4abc334599 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
#![allow(unused)]

pub(crate) const FUNC_BUS: u32 = 0;
pub(crate) const FUNC_BACKPLANE: u32 = 1;
pub(crate) const FUNC_WLAN: u32 = 2;
pub(crate) const FUNC_BT: u32 = 3;

// Register addresses
pub(crate) const REG_BUS_CTRL: u32 = 0x0;
pub(crate) const REG_BUS_RESPONSE_DELAY: u32 = 0x1;
pub(crate) const REG_BUS_STATUS_ENABLE: u32 = 0x2;
pub(crate) const REG_BUS_INTERRUPT: u32 = 0x04; // 16 bits - Interrupt status
pub(crate) const REG_BUS_INTERRUPT_ENABLE: u32 = 0x06; // 16 bits - Interrupt mask
pub(crate) const REG_BUS_STATUS: u32 = 0x8;
pub(crate) const REG_BUS_TEST_RO: u32 = 0x14;
pub(crate) const REG_BUS_TEST_RW: u32 = 0x18;
pub(crate) const REG_BUS_RESP_DELAY: u32 = 0x1c;

// SPI_BUS_CONTROL Bits
pub(crate) const WORD_LENGTH_32: u32 = 0x1;
pub(crate) const ENDIAN_BIG: u32 = 0x2;
pub(crate) const CLOCK_PHASE: u32 = 0x4;
pub(crate) const CLOCK_POLARITY: u32 = 0x8;
pub(crate) const HIGH_SPEED: u32 = 0x10;
pub(crate) const INTERRUPT_POLARITY_HIGH: u32 = 0x20;
pub(crate) const WAKE_UP: u32 = 0x80;

// SPI_STATUS_ENABLE bits
pub(crate) const STATUS_ENABLE: u32 = 0x01;
pub(crate) const INTR_WITH_STATUS: u32 = 0x02;
pub(crate) const RESP_DELAY_ALL: u32 = 0x04;
pub(crate) const DWORD_PKT_LEN_EN: u32 = 0x08;
pub(crate) const CMD_ERR_CHK_EN: u32 = 0x20;
pub(crate) const DATA_ERR_CHK_EN: u32 = 0x40;

// SPI_STATUS_REGISTER bits
pub(crate) const STATUS_DATA_NOT_AVAILABLE: u32 = 0x00000001;
pub(crate) const STATUS_UNDERFLOW: u32 = 0x00000002;
pub(crate) const STATUS_OVERFLOW: u32 = 0x00000004;
pub(crate) const STATUS_F2_INTR: u32 = 0x00000008;
pub(crate) const STATUS_F3_INTR: u32 = 0x00000010;
pub(crate) const STATUS_F2_RX_READY: u32 = 0x00000020;
pub(crate) const STATUS_F3_RX_READY: u32 = 0x00000040;
pub(crate) const STATUS_HOST_CMD_DATA_ERR: u32 = 0x00000080;
pub(crate) const STATUS_F2_PKT_AVAILABLE: u32 = 0x00000100;
pub(crate) const STATUS_F2_PKT_LEN_MASK: u32 = 0x000FFE00;
pub(crate) const STATUS_F2_PKT_LEN_SHIFT: u32 = 9;
pub(crate) const STATUS_F3_PKT_AVAILABLE: u32 = 0x00100000;
pub(crate) const STATUS_F3_PKT_LEN_MASK: u32 = 0xFFE00000;
pub(crate) const STATUS_F3_PKT_LEN_SHIFT: u32 = 21;

pub(crate) const REG_BACKPLANE_GPIO_SELECT: u32 = 0x10005;
pub(crate) const REG_BACKPLANE_GPIO_OUTPUT: u32 = 0x10006;
pub(crate) const REG_BACKPLANE_GPIO_ENABLE: u32 = 0x10007;
pub(crate) const REG_BACKPLANE_FUNCTION2_WATERMARK: u32 = 0x10008;
pub(crate) const REG_BACKPLANE_DEVICE_CONTROL: u32 = 0x10009;
pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_LOW: u32 = 0x1000A;
pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_MID: u32 = 0x1000B;
pub(crate) const REG_BACKPLANE_BACKPLANE_ADDRESS_HIGH: u32 = 0x1000C;
pub(crate) const REG_BACKPLANE_FRAME_CONTROL: u32 = 0x1000D;
pub(crate) const REG_BACKPLANE_CHIP_CLOCK_CSR: u32 = 0x1000E;
pub(crate) const REG_BACKPLANE_PULL_UP: u32 = 0x1000F;
pub(crate) const REG_BACKPLANE_READ_FRAME_BC_LOW: u32 = 0x1001B;
pub(crate) const REG_BACKPLANE_READ_FRAME_BC_HIGH: u32 = 0x1001C;
pub(crate) const REG_BACKPLANE_WAKEUP_CTRL: u32 = 0x1001E;
pub(crate) const REG_BACKPLANE_SLEEP_CSR: u32 = 0x1001F;

pub(crate) const I_HMB_SW_MASK: u32 = 0x000000f0;
pub(crate) const I_HMB_FC_CHANGE: u32 = 1 << 5;
pub(crate) const SDIO_INT_STATUS: u32 = 0x20;
pub(crate) const SDIO_INT_HOST_MASK: u32 = 0x24;

pub(crate) const SPI_F2_WATERMARK: u8 = 0x20;

pub(crate) const BACKPLANE_WINDOW_SIZE: usize = 0x8000;
pub(crate) const BACKPLANE_ADDRESS_MASK: u32 = 0x7FFF;
pub(crate) const BACKPLANE_ADDRESS_32BIT_FLAG: u32 = 0x08000;
pub(crate) const BACKPLANE_MAX_TRANSFER_SIZE: usize = 64;
// Active Low Power (ALP) clock constants
pub(crate) const BACKPLANE_ALP_AVAIL_REQ: u8 = 0x08;
pub(crate) const BACKPLANE_ALP_AVAIL: u8 = 0x40;

// Broadcom AMBA (Advanced Microcontroller Bus Architecture) Interconnect
// (AI) pub (crate) constants
pub(crate) const AI_IOCTRL_OFFSET: u32 = 0x408;
pub(crate) const AI_IOCTRL_BIT_FGC: u8 = 0x0002;
pub(crate) const AI_IOCTRL_BIT_CLOCK_EN: u8 = 0x0001;
pub(crate) const AI_IOCTRL_BIT_CPUHALT: u8 = 0x0020;

pub(crate) const AI_RESETCTRL_OFFSET: u32 = 0x800;
pub(crate) const AI_RESETCTRL_BIT_RESET: u8 = 1;

pub(crate) const AI_RESETSTATUS_OFFSET: u32 = 0x804;

pub(crate) const TEST_PATTERN: u32 = 0x12345678;
pub(crate) const FEEDBEAD: u32 = 0xFEEDBEAD;

// SPI_INTERRUPT_REGISTER and SPI_INTERRUPT_ENABLE_REGISTER Bits
pub(crate) const IRQ_DATA_UNAVAILABLE: u16 = 0x0001; // Requested data not available; Clear by writing a "1"
pub(crate) const IRQ_F2_F3_FIFO_RD_UNDERFLOW: u16 = 0x0002;
pub(crate) const IRQ_F2_F3_FIFO_WR_OVERFLOW: u16 = 0x0004;
pub(crate) const IRQ_COMMAND_ERROR: u16 = 0x0008; // Cleared by writing 1
pub(crate) const IRQ_DATA_ERROR: u16 = 0x0010; // Cleared by writing 1
pub(crate) const IRQ_F2_PACKET_AVAILABLE: u16 = 0x0020;
pub(crate) const IRQ_F3_PACKET_AVAILABLE: u16 = 0x0040;
pub(crate) const IRQ_F1_OVERFLOW: u16 = 0x0080; // Due to last write. Bkplane has pending write requests
pub(crate) const IRQ_MISC_INTR0: u16 = 0x0100;
pub(crate) const IRQ_MISC_INTR1: u16 = 0x0200;
pub(crate) const IRQ_MISC_INTR2: u16 = 0x0400;
pub(crate) const IRQ_MISC_INTR3: u16 = 0x0800;
pub(crate) const IRQ_MISC_INTR4: u16 = 0x1000;
pub(crate) const IRQ_F1_INTR: u16 = 0x2000;
pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
pub(crate) const IRQ_F3_INTR: u16 = 0x8000;

pub(crate) const IOCTL_CMD_UP: u32 = 2;
pub(crate) const IOCTL_CMD_DOWN: u32 = 3;
pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26;
pub(crate) const IOCTL_CMD_SET_CHANNEL: u32 = 30;
pub(crate) const IOCTL_CMD_DISASSOC: u32 = 52;
pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64;
pub(crate) const IOCTL_CMD_SET_AP: u32 = 118;
pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263;
pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262;
pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268;

pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0;
pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1;
pub(crate) const CHANNEL_TYPE_DATA: u8 = 2;

// CYW_SPID command structure constants.
pub(crate) const WRITE: bool = true;
pub(crate) const READ: bool = false;
pub(crate) const INC_ADDR: bool = true;
pub(crate) const FIXED_ADDR: bool = false;

pub(crate) const AES_ENABLED: u32 = 0x0004;
pub(crate) const WPA2_SECURITY: u32 = 0x00400000;

pub(crate) const MIN_PSK_LEN: usize = 8;
pub(crate) const MAX_PSK_LEN: usize = 64;

// Bluetooth firmware extraction constants.
pub(crate) const BTFW_ADDR_MODE_UNKNOWN: i32 = 0;
pub(crate) const BTFW_ADDR_MODE_EXTENDED: i32 = 1;
pub(crate) const BTFW_ADDR_MODE_SEGMENT: i32 = 2;
pub(crate) const BTFW_ADDR_MODE_LINEAR32: i32 = 3;

pub(crate) const BTFW_HEX_LINE_TYPE_DATA: u8 = 0;
pub(crate) const BTFW_HEX_LINE_TYPE_END_OF_DATA: u8 = 1;
pub(crate) const BTFW_HEX_LINE_TYPE_EXTENDED_SEGMENT_ADDRESS: u8 = 2;
pub(crate) const BTFW_HEX_LINE_TYPE_EXTENDED_ADDRESS: u8 = 4;
pub(crate) const BTFW_HEX_LINE_TYPE_ABSOLUTE_32BIT_ADDRESS: u8 = 5;

// Bluetooth constants.
pub(crate) const SPI_RESP_DELAY_F1: u32 = 0x001d;
pub(crate) const WHD_BUS_SPI_BACKPLANE_READ_PADD_SIZE: u8 = 4;

pub(crate) const BT2WLAN_PWRUP_WAKE: u32 = 3;
pub(crate) const BT2WLAN_PWRUP_ADDR: u32 = 0x640894;

pub(crate) const BT_CTRL_REG_ADDR: u32 = 0x18000c7c;
pub(crate) const HOST_CTRL_REG_ADDR: u32 = 0x18000d6c;
pub(crate) const WLAN_RAM_BASE_REG_ADDR: u32 = 0x18000d68;

pub(crate) const BTSDIO_REG_DATA_VALID_BITMASK: u32 = 1 << 1;
pub(crate) const BTSDIO_REG_BT_AWAKE_BITMASK: u32 = 1 << 8;
pub(crate) const BTSDIO_REG_WAKE_BT_BITMASK: u32 = 1 << 17;
pub(crate) const BTSDIO_REG_SW_RDY_BITMASK: u32 = 1 << 24;
pub(crate) const BTSDIO_REG_FW_RDY_BITMASK: u32 = 1 << 24;

pub(crate) const BTSDIO_FWBUF_SIZE: u32 = 0x1000;
pub(crate) const BTSDIO_OFFSET_HOST_WRITE_BUF: u32 = 0;
pub(crate) const BTSDIO_OFFSET_HOST_READ_BUF: u32 = BTSDIO_FWBUF_SIZE;

pub(crate) const BTSDIO_OFFSET_HOST2BT_IN: u32 = 0x00002000;
pub(crate) const BTSDIO_OFFSET_HOST2BT_OUT: u32 = 0x00002004;
pub(crate) const BTSDIO_OFFSET_BT2HOST_IN: u32 = 0x00002008;
pub(crate) const BTSDIO_OFFSET_BT2HOST_OUT: u32 = 0x0000200C;

// Security type (authentication and encryption types are combined using bit mask)
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq)]
#[repr(u32)]
pub(crate) enum Security {
    OPEN = 0,
    WPA2_AES_PSK = WPA2_SECURITY | AES_ENABLED,
}

#[allow(non_camel_case_types)]
#[derive(Copy, Clone)]
#[repr(u8)]
pub enum EStatus {
    /// operation was successful
    SUCCESS = 0,
    /// operation failed
    FAIL = 1,
    /// operation timed out
    TIMEOUT = 2,
    /// failed due to no matching network found
    NO_NETWORKS = 3,
    /// operation was aborted
    ABORT = 4,
    /// protocol failure: packet not ack'd
    NO_ACK = 5,
    /// AUTH or ASSOC packet was unsolicited
    UNSOLICITED = 6,
    /// attempt to assoc to an auto auth configuration
    ATTEMPT = 7,
    /// scan results are incomplete
    PARTIAL = 8,
    /// scan aborted by another scan
    NEWSCAN = 9,
    /// scan aborted due to assoc in progress
    NEWASSOC = 10,
    /// 802.11h quiet period started
    _11HQUIET = 11,
    /// user disabled scanning (WLC_SET_SCANSUPPRESS)
    SUPPRESS = 12,
    /// no allowable channels to scan
    NOCHANS = 13,
    /// scan aborted due to CCX fast roam
    CCXFASTRM = 14,
    /// abort channel select
    CS_ABORT = 15,
}

impl PartialEq<EStatus> for u32 {
    fn eq(&self, other: &EStatus) -> bool {
        *self == *other as Self
    }
}

#[allow(dead_code)]
pub(crate) struct FormatStatus(pub u32);

#[cfg(feature = "defmt")]
impl defmt::Format for FormatStatus {
    fn format(&self, fmt: defmt::Formatter) {
        macro_rules! implm {
            ($($name:ident),*) => {
                $(
                    if self.0 & $name > 0 {
                        defmt::write!(fmt, " | {}", &stringify!($name)[7..]);
                    }
                )*
            };
        }

        implm!(
            STATUS_DATA_NOT_AVAILABLE,
            STATUS_UNDERFLOW,
            STATUS_OVERFLOW,
            STATUS_F2_INTR,
            STATUS_F3_INTR,
            STATUS_F2_RX_READY,
            STATUS_F3_RX_READY,
            STATUS_HOST_CMD_DATA_ERR,
            STATUS_F2_PKT_AVAILABLE,
            STATUS_F3_PKT_AVAILABLE
        );
    }
}

#[cfg(feature = "log")]
impl core::fmt::Debug for FormatStatus {
    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
        macro_rules! implm {
            ($($name:ident),*) => {
                $(
                    if self.0 & $name > 0 {
                        core::write!(fmt, " | {}", &stringify!($name)[7..])?;
                    }
                )*
            };
        }

        implm!(
            STATUS_DATA_NOT_AVAILABLE,
            STATUS_UNDERFLOW,
            STATUS_OVERFLOW,
            STATUS_F2_INTR,
            STATUS_F3_INTR,
            STATUS_F2_RX_READY,
            STATUS_F3_RX_READY,
            STATUS_HOST_CMD_DATA_ERR,
            STATUS_F2_PKT_AVAILABLE,
            STATUS_F3_PKT_AVAILABLE
        );
        Ok(())
    }
}

#[cfg(feature = "log")]
impl core::fmt::Display for FormatStatus {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        core::fmt::Debug::fmt(self, f)
    }
}

#[allow(dead_code)]
pub(crate) struct FormatInterrupt(pub u16);

#[cfg(feature = "defmt")]
impl defmt::Format for FormatInterrupt {
    fn format(&self, fmt: defmt::Formatter) {
        macro_rules! implm {
            ($($name:ident),*) => {
                $(
                    if self.0 & $name > 0 {
                        defmt::write!(fmt, " | {}", &stringify!($name)[4..]);
                    }
                )*
            };
        }

        implm!(
            IRQ_DATA_UNAVAILABLE,
            IRQ_F2_F3_FIFO_RD_UNDERFLOW,
            IRQ_F2_F3_FIFO_WR_OVERFLOW,
            IRQ_COMMAND_ERROR,
            IRQ_DATA_ERROR,
            IRQ_F2_PACKET_AVAILABLE,
            IRQ_F3_PACKET_AVAILABLE,
            IRQ_F1_OVERFLOW,
            IRQ_MISC_INTR0,
            IRQ_MISC_INTR1,
            IRQ_MISC_INTR2,
            IRQ_MISC_INTR3,
            IRQ_MISC_INTR4,
            IRQ_F1_INTR,
            IRQ_F2_INTR,
            IRQ_F3_INTR
        );
    }
}

#[cfg(feature = "log")]
impl core::fmt::Debug for FormatInterrupt {
    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
        macro_rules! implm {
            ($($name:ident),*) => {
                $(
                    if self.0 & $name > 0 {
                        core::write!(fmt, " | {}", &stringify!($name)[7..])?;
                    }
                )*
            };
        }

        implm!(
            IRQ_DATA_UNAVAILABLE,
            IRQ_F2_F3_FIFO_RD_UNDERFLOW,
            IRQ_F2_F3_FIFO_WR_OVERFLOW,
            IRQ_COMMAND_ERROR,
            IRQ_DATA_ERROR,
            IRQ_F2_PACKET_AVAILABLE,
            IRQ_F3_PACKET_AVAILABLE,
            IRQ_F1_OVERFLOW,
            IRQ_MISC_INTR0,
            IRQ_MISC_INTR1,
            IRQ_MISC_INTR2,
            IRQ_MISC_INTR3,
            IRQ_MISC_INTR4,
            IRQ_F1_INTR,
            IRQ_F2_INTR,
            IRQ_F3_INTR
        );
        Ok(())
    }
}

#[cfg(feature = "log")]
impl core::fmt::Display for FormatInterrupt {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        core::fmt::Debug::fmt(self, f)
    }
}