This commit uses wrapping_sub for subtraction in update_credit.
The motivation for this is that currently the rpi-pico-w example panics
(at least for me) with the following error:
3.825277 INFO init done
└─ cyw43::{impl#4}::init::{async_fn#0} @ /embassy/cyw43/src/fmt.rs:138
3.825486 INFO Downloading CLM...
└─ cyw43::{impl#2}::init::{async_fn#0} @ /embassy/cyw43/src/fmt.rs:138
3.841328 WARN TX stalled
└─ cyw43::{impl#4}::run::{async_fn#0} @ /embassy/cyw43/src/fmt.rs:151
3.845549 ERROR panicked at 'attempt to subtract with overflow', /embassy/cyw43/src/lib.rs:919:16
└─ panic_probe::print_defmt::print @ .cargo/registry/src/github.com-1ecc6299db9ec823/panic-probe-0.3.0/src/lib.rs:91
────────────────────────────────────────────────────────────────────────────────
stack backtrace:
0: HardFaultTrampoline
<exception entry>
1: lib::inline::__udf
at ./asm/inline.rs:181:5
2: __udf
at ./asm/lib.rs:51:17
3: cortex_m::asm::udf
at .cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.6/src/asm.rs:43:5
4: rust_begin_unwind
at .cargo/registry/src/github.com-1ecc6299db9ec823/panic-probe-0.3.0/src/lib.rs:72:9
5: core::panicking::panic_fmt
at rustc/1c7b36d4db582cb47513a6c7176baaec1c3346ab/library/core/src/panicking.rs:142:14
6: core::panicking::panic
at /rustc/1c7b36d4db582cb47513a6c7176baaec1c3346ab/library/core/src/panicking.rs:48:5
7: cyw43::Runner<PWR,SPI>::update_credit
at /embassy/cyw43/src/lib.rs:919:16
8: cyw43::Runner<PWR,SPI>::rx
at /embassy/cyw43/src/lib.rs:808:9
9: cyw43::Runner<PWR,SPI>::run::{{closure}}
at /embassy/cyw43/src/lib.rs:727:21
10: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
at /rustc/1c7b36d4db582cb47513a6c7176baaec1c3346ab/library/core/src/future/mod.rs:91:19
11: cyw43_example_rpi_pico_w::__wifi_task_task::{{closure}}
at src/main.rs:32:17
total_len is already rounded up, so the `+ 3` is not needed.
And even if it was, the calculation should have been `((total_len + 3) / 4)`.
`(total_len + 3 / 4)` is equivalent to `total_len` and can overflow
the slice, leading to a panic which can easily be triggered by sending
large ICMP ECHO packets to the device.
This commit adds two constants which are intended to be used for setting
the `Word Length` and `High Speed` fields in the gSPR register
(address: 0x0000, bit: 0 and bit 4).
Currently, this field is being set by the following line:
```rust
// 32bit, little endian.
self.write32_swapped(REG_BUS_CTRL, 0x00010031).await;
```
Assuming that we are sending these bits using the gSPI write protocol
and using 16-bit word operation in little endian (which I think might
be the default) then the data bytes should be packed like this:
```
+--+--+--+--+
|D1|D0|D3|D2|
+--+--+--+--+
val (hex): 0x00010031
val (bin): 00000000000000010000000000110001
rotated(16): 00000000001100010000000000000001
```
If we split val into bytes and rotated the bits we get:
```
Split into bytes:
D3 D2 D1 D0
00000000 00000001 00000000 00110001
Rotate 16 and split into bytes:
D1 D0 D3 D2
00000000 00110001 00000000 00000001
```
Looking at the write procotol it seems to me that the above will
indeed set the `Word Length` to 1 but will also set other values.
```
Status enable (1=default)
D1 D0 D3 D2 ↓
00000000 00110001 00000000 00000001
↑↑ ↑↑ ↑
|| |Word Length (1=32-bit)
|| |
|| Endianess (0=Little)
||
|High-speed mode (1=High speed (default))
|
Interrupt polarity (1=high (default))
```
This commit suggests adding the above mentioned constants for setting
the only the word length field and the high speed field.
This commit renames the REG_BUS_FEEDBEAD to REG_BUS_TEST_RO
(Read-Only) which is the name used in the specification, section 4.2.3
Table 6.
It also adds a constant named REG_BUS_TEST_RW (Read-Write) to represent
the dummy register which the host can use to write data and read back
to check that the gSPI interface is working properly.
For some reason I got strange events on channel 1 (ASYNCEVENT_HEADER):
0.647329 WARN unexpected ehternet type 0x0508, expected Qualcom ether type 0x886c
This patch improves the validation of BCD WHD events to minimize the
risk for panic.