Compare commits

...

546 Commits

Author SHA1 Message Date
3cbc687424 net/driver: remove Medium, make HardwareAddress non_exhaustive. 2023-10-18 05:28:16 +02:00
51708c8ed1 Merge pull request #2089 from artisdom/patch-1
Update basic_application.adoc
2023-10-18 02:59:48 +00:00
10f08445e4 Update basic_application.adoc
typo: change "embassy::main" to "embassy_executor::main"
2023-10-18 14:53:49 +13:00
f24a1b62bb Merge pull request #2085 from xoviat/rcc
stm32: update metapac
2023-10-18 01:33:00 +00:00
bbd12c9372 stm32: update metapac 2023-10-17 20:31:44 -05:00
d94b9fe6fb Merge pull request #2082 from embassy-rs/stm32wl-hil
stm32/tests: add stm32wl hil.
2023-10-17 14:58:53 +00:00
b478640463 fix clocks in stm32wl rng example. 2023-10-17 15:57:09 +02:00
846f2fc6e4 stm32/tests: add stm32wl hil. 2023-10-17 15:57:09 +02:00
683d5c3066 Merge pull request #2077 from xoviat/rcc
stm32: update metapac
2023-10-17 01:05:18 +00:00
a3574e519a stm32: update metapac 2023-10-16 20:04:10 -05:00
3e3317e8bd Merge pull request #2078 from GrantM11235/prefetch
stm32f1: Keep flash prefetch enabled
2023-10-17 00:29:30 +00:00
e7aeb9b29f stm32f1: Keep flash prefetch enabled 2023-10-16 19:23:01 -05:00
7fd868ade9 Merge pull request #2068 from barafael/const_usb_config_builder_new
Constify UsbDevice Config::new (and clippy fixes) in embassy-usb
2023-10-16 23:23:10 +00:00
6e6df22979 Merge pull request #2075 from CBJamo/rosc_example
Add example to show useage of rp2040 rosc
2023-10-16 23:22:06 +00:00
f7980885a5 Merge pull request #2066 from bugadani/net
Prepare embassy-net 0.2.0
2023-10-16 21:19:29 +00:00
5a1393aa0b Add example to show useage of rp2040 rosc 2023-10-16 16:17:07 -04:00
40e4ca4751 Prepare embassy-net(/-driver,/-driver-channel) 0.2.0 2023-10-16 20:59:06 +02:00
1d810baa18 Merge pull request #2074 from embassy-rs/rcc-no-spaghetti
time: add `links` key, release v0.1.5.
2023-10-16 18:19:59 +00:00
213b4c9dca time: add links key, release v0.1.5. 2023-10-16 20:11:35 +02:00
889d482d2d Merge pull request #2073 from embassy-rs/rcc-no-spaghetti
nrf/pac: reeport s and ns peripherals always independently of the current mode.
2023-10-16 17:43:13 +00:00
ea0e83a7f9 nrf/pac: reeport s and ns peripherals always independently of the current mode.
You sometimes need this, for example for using nrf91 modem from S mode
you need to acces IPC_NS.
2023-10-16 19:38:53 +02:00
f0497039ed Merge pull request #2071 from embassy-rs/rcc-no-spaghetti
stm32/rng: add test.
2023-10-16 03:37:18 +00:00
aff77d2b65 stm32/rng: add test. 2023-10-16 05:35:29 +02:00
a7c6999670 Merge pull request #2070 from embassy-rs/rcc-no-spaghetti
stm32/rcc: unify L4 and L5.
2023-10-16 02:10:37 +00:00
18e96898ea stm32/rcc: unify L4 and L5. 2023-10-16 04:00:51 +02:00
870dcc5970 Merge pull request #2069 from embassy-rs/rcc-no-spaghetti
stm32/rcc: add better support for L4/L4+ differences.
2023-10-16 01:41:40 +00:00
5c5e681819 stm32/rcc: add better support for L4/L4+ differences. 2023-10-16 03:23:43 +02:00
f54753beaa Merge pull request #2067 from xoviat/rcc
rcc: update pll clock naming
2023-10-16 00:52:47 +00:00
b24520579a rcc: ahb/apb -> hclk/pclk 2023-10-15 19:51:35 -05:00
31d4516516 Apply Pedantic Clippy Lints 2023-10-15 23:52:44 +02:00
66e62e9994 Fix clippy 2023-10-15 22:25:35 +02:00
eeedaf2e76 Constify Config::new 2023-10-15 22:11:30 +02:00
1fc35c753b rcc: update pll clock naming 2023-10-15 15:10:42 -05:00
cd92bc3145 Merge pull request #2060 from xoviat/rcc
stm32: expand rcc mux to g4 and h7
2023-10-15 04:37:36 +00:00
4a156df7a1 stm32: expand rcc mux to g4 and h7 2023-10-14 23:33:57 -05:00
c46e758e2c Merge pull request #2063 from embassy-rs/rcc-no-spaghetti
stm32/rcc: port L4 to the "flattened" API like h5/h7.
2023-10-15 01:12:46 +00:00
8a10948ce9 stm32/rcc: port L4 to the "flattened" API like h5/h7. 2023-10-15 03:08:49 +02:00
7045c53170 Merge pull request #2061 from adamgreig/timer-helpers
Add convenience methods for Timer::after_secs/millis/micros/ticks
2023-10-15 00:34:59 +00:00
0621e957a0 time: Update examples, tests, and other code to use new Timer::after_x convenience methods 2023-10-15 01:30:12 +01:00
a818f33658 Merge pull request #2062 from embassy-rs/rcc-no-spaghetti
stm32/rcc: remove unused lse/lsi fields in h7
2023-10-15 01:49:01 +02:00
3bfbf2697f stm32/rcc: remove unused lse/lsi fields in h7 2023-10-15 01:48:27 +02:00
7559f9e583 time: Update documentation to use new after_x convenience methods 2023-10-15 00:47:56 +01:00
c8fdbe19f9 time: Add convenience methods for Timer::after_secs/millis/micros/ticks 2023-10-15 00:47:55 +01:00
2e50bf667a Merge pull request #2055 from kalkyl/usb-midi
embassy-usb: Add MIDI class
2023-10-14 23:10:25 +00:00
ba62037642 Merge pull request #2058 from xoviat/rcc
rcc: remove mux_prefix from clocks
2023-10-14 17:57:44 +00:00
824556c9c8 rcc: remove mux_prefix from clocks 2023-10-14 12:51:45 -05:00
f7c0ec66d2 Merge pull request #2057 from bugadani/dns
Wake Stack's polling task after queueing a DNS query
2023-10-14 14:17:54 +00:00
69bb455c60 Wake stack's task after queueing a DNS query 2023-10-14 13:35:53 +02:00
575db17264 Merge pull request #2053 from jr-oss/fix_stm32_advanced_timer_enable_output
STM32: Fix regression in advanced timer to enable output of PWM signa…
2023-10-14 04:09:57 +00:00
0aa99e66f7 Merge pull request #2054 from xoviat/rcc-mux
rcc mux: update metapac
2023-10-14 04:07:38 +00:00
3264941c1b rcc mux: update metapac 2023-10-13 23:06:32 -05:00
a57d383b1d embassy-usb: Add MIDI class 2023-10-14 04:20:59 +02:00
9a7fda87b0 STM32: timer enable_output does not take bool, but just enables the output 2023-10-13 18:52:10 +02:00
adc810d24b STM32: Fix regression in advanced timer to enable output of PWM signal by partly reverting commit 74eb519 2023-10-13 17:38:40 +02:00
75baf186f3 Merge pull request #2051 from MabezDev/stm32/set_config-concrete
make set_config concrete methods public again
2023-10-12 22:06:29 +00:00
a6bbb130c5 make set_config concrete methods public again 2023-10-12 23:03:33 +01:00
d1ac6d2824 Merge pull request #2050 from embassy-rs/remove-unused-rb
Remove unused ringbuffer
2023-10-12 19:13:12 +00:00
636958ff70 fix: correct name in readme 2023-10-12 20:54:38 +02:00
7f6fe93f55 fix: remove unused ringbuffer code 2023-10-12 20:54:26 +02:00
e9b1904db8 Merge pull request #2049 from bugadani/time
(Please) Release embassy-time 0.1.4
2023-10-12 16:40:40 +00:00
02d2c06b23 Release embassy-time 0.1.4 2023-10-12 18:14:33 +02:00
debda2f52c Merge pull request #2045 from embassy-rs/stm32-cs-spam
Avoid creating many tiny critical sections in embassy-stm32::init
2023-10-12 14:29:23 +00:00
97ca0e77bf stm32: avoid creating many tiny critical sections in init.
Saves 292 bytes on stm32f0 bilnky with max optimizations (from 3132 to 2840).
2023-10-12 16:20:34 +02:00
66e399b5c6 Merge pull request #2035 from pbert519/stm_reset_and_enable
STM32: combine RccPeripherals reset() and enable() to enable_and_reset()
2023-10-12 14:09:13 +00:00
01eb1a7339 Merge pull request #2033 from andresovela/stm32-add-timeout-to-i2c
stm32: add timeout to I2C driver
2023-10-12 10:44:27 +00:00
f0d6ee69bc Add some builds without time feature to CI 2023-10-12 11:25:44 +02:00
65f81a1f57 Remove critical section for reset 2023-10-12 11:04:45 +02:00
ecdd7c0e2f enable clock first 2023-10-12 11:04:44 +02:00
d7d79f3068 Remove workaround for adc v3 2023-10-12 11:04:20 +02:00
f65a96c541 STM32: combine RccPeripherals reset() and enable() to reset_and_enable() 2023-10-12 11:04:19 +02:00
eb368f77a4 Merge pull request #2023 from xoviat/rcc-mux
stm32: add rcc mux for h5
2023-10-12 02:01:27 +00:00
57ccc1051a stm32: add initial rcc mux for h5 2023-10-11 20:59:47 -05:00
ac84631a2a Merge pull request #2046 from embassy-rs/stm32-remove-polyfill
stm32: remove atomic-polyfill.
2023-10-12 00:14:02 +00:00
70a91945fc stm32: remove atomic-polyfill. 2023-10-12 02:07:26 +02:00
32b89eeba1 net: remove atomic-polyfill. 2023-10-12 02:07:26 +02:00
063e6f96da Remove outdated comment 2023-10-11 23:56:21 +02:00
4cec4b0548 Remove more unused stuff 2023-10-11 23:52:26 +02:00
e6c47c3718 cargo fmt 2023-10-11 23:47:24 +02:00
2f7c2750d1 Feature guarded more unused stuff 2023-10-11 23:45:47 +02:00
032b1f2d59 Fix some issues with unused stuff 2023-10-11 23:42:40 +02:00
f76d50e837 cfg! macro didn't work, had to duplicate functions with different guards 2023-10-11 23:39:24 +02:00
ee5ea7aa06 cargo fmt 2023-10-11 23:34:02 +02:00
251d004708 Try using cfg! macro 2023-10-11 23:32:40 +02:00
cd68f85501 Added guards to individual APIs 2023-10-11 23:25:13 +02:00
b6c0ddb7df Move the feature gates to the i2c module instead of the pub use statement 2023-10-11 23:05:12 +02:00
ee93bbf1d4 Gate pub use _version::* 2023-10-11 22:45:54 +02:00
7b1cd42936 Add time feature to CI 2023-10-11 22:20:27 +02:00
1cd3ae9bd5 Add comment about feature gate on I2C mod 2023-10-11 22:20:17 +02:00
bfcca79c1e Add time feature back and gate i2c on time 2023-10-11 22:12:03 +02:00
c283e2d1b9 Merge pull request #2044 from embassy-rs/stm32-pac-pll-enums
stm32/rcc: LSE xtal is 32768hz, not 32000hz.
2023-10-11 11:42:27 +00:00
4a43cd3982 stm32/rcc: LSE xtal is 32768hz, not 32000hz.
Fixes #2043
2023-10-11 13:39:04 +02:00
0dda888c95 Merge pull request #2041 from embassy-rs/stm32-pac-pll-enums
stm32/rcc: add LSE/LSI to all chips, add RTC to more chips.
2023-10-11 02:18:24 +00:00
b91d1eaca0 stm32/rcc: add LSE/LSI to all chips, add RTC to more chips. 2023-10-11 04:12:38 +02:00
5a19d18b9c Merge pull request #2039 from jcdickinson/rp-i2c-stop-restart
fix (rp i2c): fix restart/stop flags for i2c master methods
2023-10-11 00:40:59 +00:00
ed7b6056a6 Merge pull request #2038 from jcdickinson/rp-i2c-slew
fix (rp i2c): set i2c slew rate to spec value
2023-10-11 00:38:13 +00:00
322f9cb153 fix (rp i2c): fix restart/stop flags for i2c master methods
Update the start and stop flags for all read/write/read_write methods to match
those in the default blocking implementation of these methods (as well as
other RP2040 I2C implementations, and expected I2C behavior).

Also adds a write_read_async method that doesnt require using embedded-hal, as
this is required to use I2C in an idiomatic fashion (see TI Application Report
SLVA704).
2023-10-10 20:24:38 -04:00
3ec4e6320a fix (rp i2c): set i2c slew rate to spec value
The RP2040 datasheet indicates that I2C pins should have a limited
slew rate (Page 440 - 4.3.1.3.). This configures that for both
`I2c` and `I2cSlave`.

In addition, the pin configuration has been centralized to a single
fn.
2023-10-10 20:14:09 -04:00
233aa1b53a Merge pull request #2037 from embassy-rs/stm32-pac-pll-enums
stm32/rcc: rename hse32 to hse, unify L0 and L1
2023-10-10 23:37:10 +00:00
21915a9a3f stm32/rcc: unify L0 and L1. 2023-10-11 01:22:27 +02:00
d0d0ceec6a stm32/rcc: rename HSE32 to HSE 2023-10-11 01:06:44 +02:00
9be61a2967 Merge pull request #2036 from embassy-rs/stm32-pac-pll-enums
stm32/rcc: use more PLL etc enums from PAC.
2023-10-10 22:24:08 +00:00
0cfa8d1bb5 stm32/rcc: use more PLL etc enums from PAC. 2023-10-11 00:12:33 +02:00
cd12c9cbce stm32: add timeout to I2C driver 2023-10-10 18:20:46 +02:00
eff73d6dfa Merge pull request #2032 from andresv/stm32-check-flash-lock-before-unlocking
stm32 flash: check lock bit before unlocking
2023-10-10 10:12:55 +00:00
3616d68aaa stm32 flash: check lock bit before unlocking
It hardfaults if already unlocked flash is unlocked again.
2023-10-10 12:55:43 +03:00
904f1cfc7a Merge pull request #2028 from glaeqen/stm32-eth-station-management
stm32/eth: Move `phy_addr` from `Ethernet` to `PHY`
2023-10-10 01:50:45 +00:00
e62bf6a9fd Patch tests & examples 2023-10-09 13:46:56 +02:00
7526b8edba stm32/eth: Move phy_addr from Ethernet to PHY
Previously, PHY addressing was a concern of the `Ethernet` struct
which limited the `PHY` implementations which very often have to manage
multiple PHYs internally and thus possibly need to address many of them.

This change extends `StationManagement` to allow addressing different
PHY addresses via SMI.
2023-10-09 13:46:56 +02:00
c3ef98a73d Merge pull request #2026 from embassy-rs/stm32-pac-pll-enums
stm32/rcc: use PLL enums from PAC.
2023-10-09 00:58:22 +00:00
6186fe0807 stm32/rcc: use PLL enums from PAC. 2023-10-09 02:48:22 +02:00
c4cff0b79b Merge pull request #2025 from xoviat/update-pac
stm32: update metapac
2023-10-08 23:35:14 +00:00
2e5ab7981e stm32: update metapac 2023-10-08 18:27:36 -05:00
9d311121f2 Merge pull request #2022 from HelloWorldTeraByte/impl-pwm-trait
Implemented Pwm trait from embedded_hal for simple and complementary pwm
2023-10-07 00:35:05 +00:00
25c3754cd2 Merge pull request #2019 from embassy-rs/net-hostname
net: add support for dhcp hostname option.
2023-10-07 00:17:35 +00:00
85c6f23dcb Merge pull request #2018 from jamesmunns/add-derives
Add some uncontroversial derives to Error types
2023-10-07 00:03:10 +00:00
9c6a2d9cbd Merge pull request #1880 from phire/rp_bootsel
rp2040: BOOTSEL button support
2023-10-06 23:56:00 +00:00
b67b179933 rp/bootsel: add test. 2023-10-07 01:47:25 +02:00
d4ed8e5779 rp/bootsel: change it to a method on the peripheral. 2023-10-07 01:47:20 +02:00
3e054a6f0d rp2040: implement BOOTSEL button support 2023-10-07 01:39:29 +02:00
c6d53e7bce rp2040: move in_ram helper outside of Flash's impl
Allow it to be called from other modules.
2023-10-07 01:39:29 +02:00
3bf8e4de5f Merge pull request #2015 from willglynn/stm32u5_faster_clocks
stm32: u5: implement >55 MHz clock speeds
2023-10-06 23:38:15 +00:00
9090a78df4 ci: set target dir if not specified. 2023-10-07 01:34:17 +02:00
022d870d61 Add missing derive 2023-10-07 01:33:43 +02:00
534eb960e9 net: add support for dhcp hostname option. 2023-10-07 01:33:21 +02:00
7a2b8481f7 Merge pull request #2021 from embassy-rs/stm32-mco
stm32: add MCO for all chips
2023-10-06 23:31:32 +00:00
710874021a Implemented Pwm trait for complementary pwm from embedded_hal 2023-10-07 12:22:31 +13:00
3a8e0d4a27 stm32: implement MCO for all chips. 2023-10-07 01:15:24 +02:00
b217d147de Implemented Pwm trait from embedded_hal 2023-10-07 11:57:19 +13:00
68c4820dde Add MCO support for stm32wl family 2023-10-06 14:37:36 -07:00
f30fc949ff Merge pull request #2012 from mattico/h7-rtc
H7: support LSE, LSI, LSEBYP, and RTCCLKSEL
2023-10-06 21:27:04 +00:00
75c1a9a3aa disable flaky f2 eth test 2023-10-06 23:25:39 +02:00
4075ac84e1 h7: enable rtc test 2023-10-06 14:12:57 -05:00
f01609036f h7: implement RTC and LSE clock configuration 2023-10-06 13:28:30 -05:00
930b8f3495 Add some uncontroversial derives to Error types 2023-10-06 17:45:35 +02:00
38e7709a24 stm32: u5: implement >55 MHz clock speeds
This commit allows STM32U5 devices to operate at 160 MHz.

On STM32U5, MSIS can run at 48 MHz and HSE can reach 50 MHz. Faster
clocks require using PLL1's R output, though PLL1 can serve other
functions besides using the R output for the system clock. This commit
extracts a public `PllConfig` struct, primarily to place associated
constructors on that type, but also with an eye towards enabling the P
and Q outputs in a later commit.

STM32U5 PLLs have various frequency requirements on each stage: after
the `m` prescaler, after the `n` multiplier, and after the `r` divider.
This commit implements the associated checks as assertions.

This commit fixes clock calculation and PLL register configuration
errors in PLL initialization.

STM32U5 has a PWR peripheral which can be configured to push Vcore into
different voltage ranges. System clocks exceeding 55 MHz require range
2, and system clocks exceeding 110 MHz require range 1. This commit
adds `voltage_range` to `Config` and configures PWR as directed.

The voltage range implies different performance limits on various clock
signals, including inside a PLL. This commit implements voltage range
<-> frequency range checks as assertions, and extracts the
otherwise-repeated MSIS, HSI16, and HSE initialization into private
methods on `Config`.

STM32U5 frequencies above 55 MHz require using the PWR EPOD booster.
The EPOD booster requires configuring a second `m` term for PLL1,
`mboost`, such that it falls in a particular range. (Recall that >50
MHz cannot be reached without PLL1, so there is no scenario where EPOD
is needed but PLL1 is not.) This commit configures and enables the EPOD
booster automatically as required.
2023-10-05 22:13:27 -05:00
65ed19aae2 Merge pull request #2014 from bugadani/udp
Reexport IpListenEndpoint for TCP
2023-10-05 16:13:10 +00:00
be9c05fbc9 Reexport IpListenEndpoint for TCP 2023-10-05 17:02:25 +02:00
42176b1a3a Merge pull request #2013 from xoviat/opamp
stm32: update metapac and fix opamp ch
2023-10-04 21:20:42 +00:00
e1a0635ca3 stm32: update metapac and fix opamp ch 2023-10-04 16:15:08 -05:00
b887b7516e Merge pull request #2011 from glaeqen/input-pin
stm32/gpio: Implement `eh1::digital::InputPin` for `OutputOpenDrain`
2023-10-04 17:36:26 +00:00
c6513f93fe stm32/gpio: Implement eh1::digital::InputPin for OutputOpenDrain
Pins in open-drain mode are outputs and inputs simultaneously.
2023-10-04 18:20:25 +02:00
59f706ee2f Merge pull request #2006 from embassy-rs/update-eio
update embedded-io, embedded-nal-async.
2023-10-03 22:27:06 +00:00
ba7d74ac16 tests/stm32: increase tickrate for better precision. 2023-10-04 00:17:33 +02:00
0324cee0ca update embedded-io, embedded-nal-async. 2023-10-04 00:10:55 +02:00
8ac5c1a963 Merge pull request #1973 from xoviat/opamp
stm32: add opamp
2023-10-03 22:01:46 +00:00
e7ab044935 ci: remove wpan tests again 2023-10-03 16:59:18 -05:00
0c4cddfafb Merge branch 'main' of github.com:embassy-rs/embassy into opamp 2023-10-03 16:44:44 -05:00
e561e673c2 stm32: add opamp mod and update pac 2023-10-03 16:34:13 -05:00
09dfcd6b66 Merge pull request #2008 from xoviat/wpan
wpan: re-enable HIL tests
2023-10-03 21:02:48 +00:00
bb8a1b7f1f wpan: re-enable HIL tests 2023-10-03 15:53:22 -05:00
b012a67df7 Merge pull request #2007 from embassy-rs/unverbose
Remove a few ultra-verbose logs.
2023-10-03 20:28:44 +00:00
40f30fa4cd Remove a few ultra-verbose logs.
They're heavily spamming logs for HIL tests, and I don't believe
they're valuable now that the thing they helped debug in their young
age is now solid and mature.
2023-10-03 22:22:16 +02:00
f197aa9419 Merge pull request #2005 from embassy-rs/minor-doc-improvs
docs: minor doc improvements and cleanup
2023-10-03 19:37:39 +00:00
80a740bc72 docs: minor doc improvements and cleanup 2023-10-03 21:35:31 +02:00
ad524373ed Merge pull request #1926 from m5p3nc3r/async_dtr
Add a signal for when the CDC control state changes
2023-10-03 02:13:12 +00:00
9badf740d8 Merge pull request #2001 from embassy-rs/stm32-more-hil
stm32/hil: add f2, f3, f7, l49
2023-10-03 02:07:00 +00:00
6e901846df Merge pull request #1995 from JuliDi/quadspi
[STM32] QUADSPI support bank 2
2023-10-03 01:55:27 +00:00
c0a6c78a14 stm32/hil: add f2, f3, f7, l49 2023-10-03 02:11:58 +02:00
58280048e3 Merge pull request #2002 from embassy-rs/fix-stop
stm32: fix stop
2023-10-02 23:56:33 +00:00
00824af82b ci: remove wpan tests 2023-10-02 18:55:31 -05:00
adf9ffb109 tests/stm32: use default clock config 2023-10-02 18:51:59 -05:00
bc203ebe4b Merge branch 'main' of github.com:embassy-rs/embassy into fix-stop 2023-10-02 18:30:41 -05:00
e042b3056d stm32: fix stop 2023-10-02 18:11:03 -05:00
9dc927250c Merge pull request #1959 from embassy-rs/test-eth
stm32: add eth tests
2023-10-02 20:41:31 +00:00
b856d760f4 stm32/rcc: reset backup domain before enabling LSE. 2023-10-02 22:12:50 +02:00
a742a80171 Merge pull request #1999 from KingCol13/rp-wifi-examples-fixes
cyw43: Update examples
2023-10-02 20:07:45 +00:00
90ade1b311 Add wait for DHCP in rp wifi_tcp_server 2023-10-02 20:10:52 +01:00
a931dfd9ad Update firmware size in rp wifi examples 2023-10-02 20:10:45 +01:00
eff61648fe tests/stm32: add eth test. 2023-10-02 20:40:11 +02:00
9228a6334b Merge pull request #1996 from embassy-rs/update-nightly
Update Nightly.
2023-10-02 17:29:21 +00:00
3c9dfbbc9d enable wifi_esp_hosted_perf test, disable stm32f4 stop test. 2023-10-02 19:05:41 +02:00
ce0add61f8 Merge pull request #1997 from dzamlo/main
stm32: avoid useless endian conversion in rng
2023-10-02 15:31:13 +00:00
bf6e06060b stm32: avoid useless endian conversion in rng 2023-10-02 17:20:58 +02:00
eb12114345 Remove impl_trait_projections. 2023-10-02 14:00:49 +02:00
4b252586e5 Update Nightly. 2023-10-02 13:51:13 +02:00
5f6a915a32 Merge pull request #1994 from jcdickinson/pin_params
feat (rp2040): allow schmitt, slew, and drive strength be set from Flex, Input, Output
2023-10-02 10:44:19 +00:00
923f1851ee remove debug logging in build.rs 2023-10-02 09:36:11 +02:00
bd267a6479 move stm32h7 specific import 2023-10-02 09:34:59 +02:00
f3aa0cfe5a remove debug code, add some comments 2023-10-02 09:33:10 +02:00
6ea5aa347d feature-gate errata workaround for h7 2023-10-02 09:30:58 +02:00
8c13126cff make push/pull settings for pins explicit 2023-10-02 09:30:58 +02:00
81da9ca621 Bump stm32-metapac, add flash selection 2023-10-02 09:30:58 +02:00
729338875c support QSPI BK2 2023-10-02 09:30:57 +02:00
f98c8886b2 feat: allow schmitt, slew, and drive strength be set from Flex, Input, Output
Allows the schmitt, slew and drive strength to be set from Flex. Input and Output[OpenDrain] also expose the appropriate setters.
2023-10-01 21:49:14 -04:00
a1036e111e Merge pull request #1990 from embassy-rs/stm32f4-rcc-fix
stm32f4: fix rcc build on stm32f446
2023-10-01 21:16:09 +00:00
2af97e7595 rcc/f4: fix build on stm32f446
fixes #1989
2023-10-01 23:01:58 +02:00
2008030a8b ci: add all stm32f4 2023-10-01 23:01:35 +02:00
480328d07e Merge pull request #1984 from xoviat/set-config
stm32: require use of setconfig to set config
2023-10-01 14:41:52 +00:00
05218a52e6 stm32: update set_config 2023-10-01 09:39:10 -05:00
d2a2734752 nrf, rp: update set_config 2023-10-01 09:37:42 -05:00
5ad34404af eh: update set_config and add get_config 2023-10-01 09:37:20 -05:00
a7b1e51650 Merge pull request #1987 from tyler-gilbert/issue-1986-add-sai-receiver-driver
Issue 1986 add sai receiver driver
2023-10-01 14:06:25 +00:00
70005c3956 Merge pull request #1988 from JuliDi/expose-analog-switch-pins-rebased
[STM32] Handle STM32H7 "_C" pins (rebased)
2023-10-01 12:36:21 +00:00
93adbb9922 update stm32-metapac 2023-10-01 12:41:08 +02:00
e80df91e02 update stm32-metapac revision 2023-10-01 12:34:26 +02:00
5cb58754d4 skip _C pins for pin impls if split_feature not enabled. 2023-10-01 12:32:47 +02:00
5c83179071 change split_features from array to Vec 2023-10-01 12:32:47 +02:00
49608714aa cleanup, fix pushing to pins_table 2023-10-01 12:32:47 +02:00
f116ca83e0 check whether split-feature is valid 2023-10-01 12:32:47 +02:00
6e5f3f9515 update to testing pr #1889 2023-10-01 12:32:46 +02:00
5924cc8b49 handle _C pins 2023-10-01 12:30:34 +02:00
0d49aaf8ca Issue #1986 fix ci build errors 2023-09-30 22:51:23 -05:00
5dd9e9b3b7 issue #1986 separate blocks to prevent unsafe user code 2023-09-30 22:48:49 -05:00
d42cfda2db Issue #1986 add PartialEq to SyncEnable to fix build error on sai_v4 2023-09-30 19:51:00 -05:00
d1f4511cd1 Issue #1986 update the SAI driver with receiver capability 2023-09-30 19:43:44 -05:00
fa8d5da4a5 Merge pull request #5 from embassy-rs/main
Merge latest including SAI driver
2023-09-30 16:06:11 -06:00
7bc57ca3f7 Merge pull request #1975 from tyler-gilbert/issue-1974-add-sai-driver
Issue 1974 add sai driver
2023-09-30 20:04:26 +00:00
7ad102695d Merge pull request #1981 from xoviat/fix-traits
Fix traits
2023-09-30 17:57:22 +00:00
4999de6f82 rustfmt 2023-09-30 12:53:17 -05:00
9b8bdad403 Fix clippy error exposed by moving out of macros 2023-09-30 13:07:11 -04:00
3c3fb0a529 Remove unused imports 2023-09-30 12:20:31 -04:00
dc4c27aead Move one more method out of macros 2023-09-30 12:16:47 -04:00
74eb519810 Move trait impls out of macros 2023-09-30 12:14:20 -04:00
61dc36b1f2 Fix small formatting issue 2023-09-30 11:36:32 -04:00
55a0a15be2 Fix trait inconsistency between sealed traits and implementations 2023-09-30 11:19:09 -04:00
fc8f96fea5 Merge pull request #1976 from elasticdotventures/feature/examples
fix typo / update wasm example
2023-09-30 10:55:08 +00:00
08175f191a bump wasm-pack version 2023-09-30 05:42:59 +00:00
8da987cfbb typo 2023-09-30 05:34:22 +00:00
1be5f193c3 #Issue 1974 more whitespace fixes 2023-09-29 21:53:01 -05:00
4a632e08b7 #Issue 1974 fix extra whitespace 2023-09-29 21:46:19 -05:00
6cdee93934 #Issue 1974 fix more warnings treated as errors 2023-09-29 21:27:15 -05:00
5c8c1b2146 #Issue 1974 fix warnings 2023-09-29 21:16:20 -05:00
2addfc4b86 Merge branch 'issue-1974-add-sai-driver' of https://github.com/tyler-gilbert/embassy into issue-1974-add-sai-driver 2023-09-29 21:08:21 -05:00
92df87781d Issue 1974 add sai/mod file 2023-09-29 21:08:07 -05:00
a35d149cb1 Revert metapac change in Cargo.toml 2023-09-29 21:07:09 -05:00
c52320f467 Merge pull request #4 from embassy-rs/main
Pull latest from embassy main
2023-09-29 20:03:31 -06:00
2f9b59c5cf Merge branch 'main' into issue-1974-add-sai-driver 2023-09-29 20:02:24 -06:00
ce91fb2bfc Issue #1974 add SAI driver 2023-09-29 20:57:59 -05:00
95b3d9eb3b Merge pull request #1972 from embassy-rs/rtc-lse-fix
stm32/rtc: enable lse in examples.
2023-09-29 22:23:42 +00:00
f1e7205055 stm32/rtc: enable lse in examples. 2023-09-30 00:18:30 +02:00
6627824c02 Merge pull request #1970 from dberlin/revert-1969-main
Revert "Forgot set_count_direction and set_clock_division in 32 bit instance"
2023-09-29 17:32:37 +00:00
d62533879c Merge pull request #1971 from oro-os/enc28j60-mac-addr
enc28j60: expose a the MAC address via `address()` getter
2023-09-29 15:49:07 +00:00
e1a8caffa4 enc28j60: expose a the MAC address via address() getter 2023-09-29 17:23:39 +02:00
dffdb9268b Revert "Forgot set_count_direction and set_clock_division in 32 bit instance" 2023-09-28 21:56:18 -04:00
22e820b743 Merge pull request #1969 from dberlin/main
Forgot set_count_direction and set_clock_division in 32 bit instance
2023-09-29 00:38:45 +00:00
aa14f18d3f Merge pull request #1968 from xoviat/sbs
update metapac and rename sbs
2023-09-29 00:25:55 +00:00
39f1b26a39 stm32: update metapac and remove sbs 2023-09-28 19:21:02 -05:00
e70143ef8f Forgot set_count_direction and set_clock_division in 32 bit instance 2023-09-28 20:01:04 -04:00
d6654bf8b5 Merge pull request #1966 from xoviat/hrtim
stm32/hrtim: move traits out of macro def'n
2023-09-28 20:53:55 +00:00
322a4a8401 stm32/hrtim: move traits out of macro def'n 2023-09-28 15:48:46 -05:00
ee5591017b Merge pull request #1964 from dberlin/main
Add support for STM32 input capture filter
2023-09-28 20:37:48 +00:00
b1b32f079b Merge pull request #1962 from bugadani/esp32s2
Add 80MHz tick rate
2023-09-28 17:07:26 +00:00
e8a462768e Add more tick rates 2023-09-28 19:06:38 +02:00
ce0d787781 Merge pull request #1965 from oro-os/return-len-receive-enc28j60
enc28j60: return packet length from receive() instead of mut slice
2023-09-28 16:32:22 +00:00
fa2e63f74b enc28j60: return packet length from receive() instead of mut slice 2023-09-28 18:28:46 +02:00
23f3889167 Add support for STM32 input capture filter 2023-09-28 09:35:43 -04:00
a72a91ab06 Merge pull request #1963 from Mirror0/restore-f7-rtc
Restore RTC configuration for `STM32F7` boards
2023-09-28 11:32:50 +00:00
b9ef831ff7 Add 80MHz tick rate 2023-09-28 09:41:35 +02:00
e538aeacc8 Merge pull request #1960 from embassy-rs/test-eth-2
Net fixes
2023-09-28 03:39:10 +00:00
6b3745fc47 temporarily disable wifi_esp_hosted_perf test. 2023-09-28 05:34:19 +02:00
6200d22438 stm32/eth: fix receiving large frames on v2. 2023-09-28 05:12:35 +02:00
901d31e8f8 Merge pull request #1933 from xoviat/adc
stm32: more adc cleanup
2023-09-28 01:59:51 +00:00
79146c4bd5 stm32/adc: cleanup f1, f3, v1, and v2 2023-09-27 20:58:46 -05:00
d9eae79f3e test: deduplicate net perf test code. 2023-09-28 03:47:14 +02:00
3d1b4116ec test: set DEFMT_LOG not too verbose so net perf tests pass with cargo run. 2023-09-28 03:47:14 +02:00
901f0257bd net: allow non-'static drivers. 2023-09-28 03:47:14 +02:00
fec4194ae6 Merge pull request #1958 from dberlin/main
Add support for input capture function
2023-09-28 01:00:36 +00:00
f866735802 Add support for input capture function 2023-09-27 20:15:57 -04:00
20ea76c19c Merge pull request #1953 from embassy-rs/stm32l-tests
tests/stm32: add L0, L1, L4, L4+, L5
2023-09-27 19:37:04 +00:00
e1951f3ddf feat(stm32f7): restore rtc configuration for stm32f7 series 2023-09-27 16:08:05 +02:00
8b5fb254c0 tests/stm32: add L0, L1, L4, L4+, L5 2023-09-26 05:30:50 +02:00
624f786203 Merge pull request #1952 from embassy-rs/stm32-test-cleanup
stm32 rcc fixes.
2023-09-26 03:24:53 +00:00
a57e48459e stm32/rcc: remove bad limits on l5. 2023-09-26 05:15:09 +02:00
c604d8a8f1 stm32/rcc: add voltage_scale, flash waitstates. 2023-09-26 05:15:09 +02:00
be0c52bf5e Merge pull request #1951 from embassy-rs/stm32-test-cleanup
stm32/usart: enable fifo mode on usartv4.
2023-09-26 02:42:11 +00:00
44bb405683 stm32/usart: enable fifo mode on usartv4. 2023-09-26 04:38:53 +02:00
e8587e2fba Merge pull request #1950 from embassy-rs/stm32-test-cleanup
stm32/usart: return error instead of panicking on bad baudrate.
2023-09-25 22:21:29 +00:00
5d8817d109 stm32/usart: return error instead of panicking on bad baudrate. 2023-09-26 00:19:27 +02:00
c79a84a98a Merge pull request #1949 from xoviat/rtc
stm32/rtc: cleanup and fixes
2023-09-25 21:40:05 +00:00
96edbd84fb rtc: use enable on known working chips only 2023-09-25 16:38:30 -05:00
dc400a0539 stm32/rtc: always set wakeup alarm 2023-09-25 16:27:08 -05:00
04b09a2acb stm32/rtc: use rccperi enable 2023-09-25 16:26:29 -05:00
481d2998ef Merge pull request #1948 from embassy-rs/stm32-test-cleanup
tests/stm32: centralize pin configuration.
2023-09-25 20:44:57 +00:00
4b695120fc tests/stm32: centralize pin configuration. 2023-09-25 22:41:22 +02:00
bd9021ca1d Make irq token Copy+Clone 2023-09-25 22:35:31 +02:00
6e63c8d4bf Merge pull request #1947 from ceekdee/rust-lorawan-lora-phy-v2
Update rust-lorawan and embassy to use lora-phy version 2
2023-09-25 16:20:50 +00:00
70acc093dd Update rust-lorawan crate versions. 2023-09-25 10:45:53 -05:00
f7c2db245f Merge branch 'embassy-rs:main' into rust-lorawan-lora-phy-v2 2023-09-24 19:09:04 -05:00
2543bcafaf Merge pull request #1945 from xoviat/bd-2
stm32: fix bd lsi
2023-09-24 23:41:04 +00:00
9f2fc04caa stm32: fix bd lsi 2023-09-24 18:37:09 -05:00
f32bfafa61 Merge pull request #1943 from embassy-rs/centralize-pwr-syscfg
stm32: centralize enabling pwr, syscfg, flash.
2023-09-24 23:15:25 +00:00
e03239e88d stm32: centralize enabling pwr, syscfg, flash. 2023-09-25 01:07:55 +02:00
7d5e62d4a7 Update for rust-lorawan and lora-phy version 2. 2023-09-24 10:33:03 -05:00
65d36f9f99 Merge pull request #1940 from luveti/patch-1
stm32: fix rtc example
2023-09-24 09:30:08 +00:00
347ff18644 stm32: fix rtc example
lsi must be enabled otherwise a assertion fails
2023-09-24 01:11:58 -04:00
1e80fd81f7 Merge pull request #1939 from nilfit/spim-anomaly-109
spim: Fix nRF52832 SPIM with polling executors
2023-09-23 11:14:16 +00:00
52e269edbb Merge pull request #1938 from xoviat/low-power
stm32/lp: clamp requested_duration
2023-09-22 20:39:54 +00:00
c849620cd6 stm32/lp: clamp requested_duration to avoid overflow 2023-09-22 15:35:20 -05:00
6f83acc010 Add separate work-around specific flag for DMA errata on NRF52832 2023-09-22 17:02:21 +02:00
2b7b7a917d spim: Fix SPIM with polling executors
Co-authored-by: Priit Laes <plaes@plaes.org>
2023-09-22 17:02:21 +02:00
f1488864eb Merge pull request #1937 from xoviat/low-power
stm32/low-power: create one critical-section for all time ops
2023-09-22 00:36:21 +00:00
7cf327130e stm32/low-power: create one critical-section for all time ops 2023-09-21 19:32:48 -05:00
02b0523199 Merge pull request #1935 from embassy-rs/stm32-update-metapacgc
stm32: update metapac.
2023-09-21 22:26:53 +00:00
47175198c0 stm32: update metapac. 2023-09-22 00:13:57 +02:00
4b20e6c258 Merge pull request #1927 from embassy-rs/stm32-rcc-unify-h
stm32/rcc: unify h5 and h7.
2023-09-21 22:05:01 +00:00
83b4c01273 stm32/rcc: unify h5 and h7. 2023-09-21 23:47:56 +02:00
e313ca4ae8 Merge pull request #1934 from chrenderle/low-power-l0
fix low-power: APB1 needed for LSE
2023-09-21 17:40:11 +00:00
ad64d7b20b fix low-power: APB1 needed for LSE 2023-09-21 17:17:58 +02:00
5626a28af2 Merge pull request #1930 from xoviat/adc
stm32/adc: make v1 async
2023-09-20 22:45:51 +00:00
766ae724cb Merge pull request #1932 from embassy-rs/h7fix
stm32/h7: fix bad PWR reg versions.
2023-09-20 22:28:09 +00:00
00b9f9acef stm32/h7: fix bad PWR reg versions. 2023-09-21 00:23:56 +02:00
d46920dce6 stm32/adc: make v1 async and leave en 2023-09-20 16:07:35 -05:00
e1ed492577 Merge pull request #1929 from sgoll/exti-level
stm32/exti: Add get_level() to ExtiInput
2023-09-19 22:44:19 +00:00
2405aff11f Add get_level() to ExtiInput 2023-09-20 00:03:39 +02:00
a402aed3d1 Add async interface for CDC control changes
Signed-off-by: Matt Spencer <matthew@thespencers.me.uk>
2023-09-19 15:42:26 +01:00
c573959a95 Merge pull request #1928 from sgoll/fix-r2-voltage-range
stm32/f2: Fix typo in RCC voltage range docs
2023-09-19 12:03:40 +00:00
561696dfad Fix typo in F2 RCC voltage ranges 2023-09-19 10:20:25 +02:00
b1abaa380f Merge pull request #1919 from xoviat/adc
adc/f3: add async conversion
2023-09-18 21:32:59 +00:00
e640933e2f stm32/adc: add async conversion 2023-09-18 16:31:20 -05:00
183824fbdd Merge pull request #1924 from embassy-rs/rp-remove-paste
rp: remove paste macro.
2023-09-18 01:33:55 +00:00
5d0c40f61d rp: remove paste macro. 2023-09-18 03:30:17 +02:00
fdfe12fe1c Merge pull request #1923 from embassy-rs/pac-vos
stm32: use PAC enums for VOS.
2023-09-18 01:23:40 +00:00
4bfbcd6c72 stm32: use PAC enums for VOS. 2023-09-18 03:15:15 +02:00
0da793e5de Merge pull request #1921 from xoviat/rtc
stm32: update configure_ls and misc cleanup
2023-09-18 00:04:32 +00:00
0dcb34fc7d ci: fix tests 2023-09-17 19:03:45 -05:00
feaeee1e83 stm32: misc. cleanup 2023-09-17 18:47:22 -05:00
a6ef314be1 stm32: update configure_ls as agreed 2023-09-17 18:41:45 -05:00
daeb497045 Merge pull request #1917 from MabezDev/set-config-uart
stm32: Implement `set_config` for Uart structs
2023-09-17 21:33:18 +00:00
88eb5cca71 stm32: Implement set_config for Uart structs 2023-09-17 18:38:03 +01:00
cd128c20fa Merge pull request #1920 from MabezDev/rtc-time-provider
stm32: Add RtcTimeProvider struct to Rtc module
2023-09-17 17:32:56 +00:00
087ef918bf stm32: Add RtcTimeProvider struct to Rtc module
This struct allows users to acquire the current time without putting `Rtc`
in a mutex and passing that around. This is allowed because reading from the
rtc registers is atomic.
2023-09-17 18:04:05 +01:00
75cae09e79 Merge pull request #1918 from embassy-rs/stm32wba
stm32/rcc: use AHBPrescaler div impls in stm32wba
2023-09-17 00:39:26 +00:00
bbe1d96045 stm32/rcc: use AHBPrescaler div impls in stm32wba 2023-09-17 02:30:50 +02:00
3ddc9cd110 Merge pull request #1915 from xoviat/rcc
stm32/rcc: convert bus prescalers to pac enums
2023-09-16 22:59:26 +00:00
de2773afdd stm32/rcc: convert bus prescalers to pac enums 2023-09-16 17:41:11 -05:00
2930be5e17 Merge pull request #1916 from wkf/main
Update stm32wb examples to use ble/mac firmware.
2023-09-16 20:43:02 +00:00
09f087e53e Update stm32wb examples to use ble/mac firmware. 2023-09-16 16:32:25 -04:00
044b837caa Merge pull request #1914 from xoviat/fix-wpan
stm32: fix  wpan_ble test
2023-09-16 15:20:55 +00:00
ad0a306ea5 stm32: fix wpan_ble test 2023-09-16 10:19:09 -05:00
b5fffbf66f Merge pull request #1913 from xoviat/doc
update docs
2023-09-16 13:20:39 +00:00
537e2f3b44 update docs 2023-09-16 08:19:49 -05:00
80d7193b5b Merge pull request #1911 from embassy-rs/stm32wba
stm32: add stm32wba support.
2023-09-16 02:06:22 +00:00
8315cf064e stm32: add stm32wba support. 2023-09-16 04:04:45 +02:00
a2a26f489b ci: set net.git-fetch-with-cli=true 2023-09-16 02:16:33 +02:00
f27620cc0b Merge pull request #1909 from xoviat/adc
stm32: generate adc_common and misc.
2023-09-15 23:49:41 +00:00
2911774849 Merge pull request #1910 from xoviat/rtc
stm32: rtc/low-power cleanup
2023-09-15 23:49:36 +00:00
6da75ea285 stm32: rtc/low-power cleanup 2023-09-15 18:41:33 -05:00
aa2fa29b89 stm32: fix adc f3 startup time
closes #1888.
2023-09-15 17:36:21 -05:00
c28a6bdd0b stm32: generate adc_common 2023-09-15 17:35:53 -05:00
5a158b94bd Merge pull request #1896 from haileys/inline-never-for-rvo
Write to TaskStorage::future via never-inlined fn to encourage RVO
2023-09-15 18:45:21 +00:00
c091ed2f63 Merge pull request #1908 from chrenderle/low-power-l0
Fix low-power feature for STM32L0
2023-09-15 14:50:19 +00:00
45e9e51bdc Fix low-power feature for STM32L0 2023-09-15 16:36:51 +02:00
7c77d2bd94 ci: reenable stm32 docs. 2023-09-15 03:43:46 +02:00
f76d94098d Merge pull request #1906 from xoviat/pwr-l0
update metapac and add low-power for l0
2023-09-15 00:21:24 +00:00
07233ca5b4 ci: build low-power on l0 2023-09-14 19:09:35 -05:00
9fb14379c3 stm32: add lp to l0 2023-09-14 18:53:27 -05:00
309c3d6b47 update metapac 2023-09-14 18:36:03 -05:00
f1f4943ca5 Merge pull request #1903 from embassy-rs/bump-embassy-sync
feat: bump embassy-sync version to 0.3.0
2023-09-14 16:36:59 +00:00
1b20ba27b1 feat: bump embassy-sync version to 0.3.0
Update changelog in preparation for release
2023-09-14 18:26:00 +02:00
f5e96a9d60 Merge pull request #1902 from diondokter/gpiote-fix
Fix gpiote when waking up from systemoff
2023-09-14 16:02:14 +00:00
e8b961232b Fix gpiote when waking up from systemoff 2023-09-14 17:24:28 +02:00
85a9f5816f Merge pull request #1901 from FuzzyLitchi/patch-1
Fix doc typo
2023-09-14 14:10:21 +00:00
7bcc7e8962 Fix doc typo 2023-09-14 16:08:37 +02:00
b118c4cc1b Merge pull request #1899 from tarfu/bump-fmc
stm32: bump fmc version
2023-09-14 12:34:19 +00:00
f090a38dde Merge pull request #1898 from MathiasKoch/embassy-stm32/uart-blocking-embedded-io
feature(embassy-stm32): implement blocking embedded-io::Write for Uart & UartTx
2023-09-14 12:33:51 +00:00
dcd1a91966 stm32: bump fmc version 2023-09-14 14:07:15 +02:00
49847ff432 Implement blocking embedded-io::Write for Uart & UartTx 2023-09-14 10:09:09 +02:00
b9d4b18f14 update UninitCell::write call in arch::wasm too 2023-09-14 13:59:24 +10:00
3a1ed823f8 write to TaskStorage::future via inline(never) fn to encourage RVO 2023-09-14 13:42:11 +10:00
9c647dd0e8 Merge pull request #1892 from cumthugo/usart-not-wakeup
stm32/usart: fix read_until_idle not wake up issue
2023-09-13 17:29:13 +00:00
582ef90994 stm32/usart: fix usart not wake up issue 2023-09-13 23:47:46 +08:00
5e381d49da Merge pull request #1893 from ceekdee/main
Wait for high for DIO1 for rp2040-based LoRa boards
2023-09-12 23:00:25 +00:00
af59fa0a7e Wait for high for DIO1 for rp2040-based LoRa boards. 2023-09-12 17:53:27 -05:00
4907ccaa4d Merge pull request #1839 from Frostie314159/embassy-time-next
embassy-time: Introduce reset function for Ticker.
2023-09-12 22:11:21 +00:00
2c38dd17b9 Merge pull request #1887 from xoviat/adc
adc/f3: fix delay calculation
2023-09-11 23:54:26 +00:00
d36e7abb71 adc/f3: fix delay calculation 2023-09-11 18:52:52 -05:00
e11db9fa59 ci: disable stm32 docs build temporarily because it's bringing CI down for some reason. 2023-09-12 01:43:57 +02:00
f877a5889d ci: fix colliding files warning. 2023-09-12 01:43:19 +02:00
db54edf56c Merge pull request #1886 from xoviat/adc
add g4 adc345, adc etc.
2023-09-11 22:50:53 +00:00
4072a16af6 ci: remove wpan_ble for hil 2023-09-11 17:50:08 -05:00
44a5c32ea4 adc/f3: fix startup bug 2023-09-11 17:27:47 -05:00
b9889ad3b5 stm32: add g4 adc345 and misc. 2023-09-11 17:12:54 -05:00
527bdc57b9 Fixed formating. 2023-09-11 08:04:06 +02:00
1133cbf90e Merge pull request #1834 from dave-andersen/main
Fix timing on RP2040 pio_ws2812.rs example
2023-09-10 21:21:06 +00:00
77c357e744 Merge pull request #1870 from plaes/nrf-setconfig-trait-internally
nrf: Use SetConfig trait internally where possible
2023-09-10 21:19:15 +00:00
521970535e nrf: twim: Use SetConfig trait to reduce code duplication 2023-09-10 23:17:30 +02:00
93d4cfe7c1 nrf: spis: Use SetConfig trait internally to reduce duplication 2023-09-10 23:17:30 +02:00
8413a89752 nrf: spim: Use SetConfig trait internally to reduce duplication 2023-09-10 23:17:30 +02:00
db717d9c81 nrf: Remove unneeded include from Temp's example
Fixes doctest when `time` feature is not enabled.
2023-09-10 23:17:30 +02:00
808fa9dce6 Merge pull request #1871 from plaes/dma-anomaly-109-spim-workaround
nrf: spim: Anomaly 109 workaround for SPIM peripheral (#460)
2023-09-10 21:12:02 +00:00
ceb13def19 Merge pull request #1850 from CBJamo/i2cdev
rp2040: I2cDevice
2023-09-10 21:02:32 +00:00
5cf494113f tests/rp: add teleprobe meta. 2023-09-10 23:01:15 +02:00
8edb7bb012 Test cleanup 2023-09-10 23:01:15 +02:00
8900f5f52b Fixing my git-based mistakes 2023-09-10 23:01:15 +02:00
8201979d71 Add example, fix small bug in respond_and_fill 2023-09-10 23:01:15 +02:00
2d9f50addc I2c slave take 2
refactored to split modules
renamed to match upstream docs
slight improvement to slave error handling
2023-09-10 23:01:15 +02:00
18da91e252 Rename to match upstream docs 2023-09-10 23:01:15 +02:00
28e2570533 Remove debug prints 2023-09-10 23:01:15 +02:00
26e0823c35 rp2040 I2cDevice
Move i2c to mod, split device and controller

Remove mode generic:
I don't think it's reasonable to use the i2c in device mode while
blocking, so I'm cutting the generic.
2023-09-10 23:01:15 +02:00
ceca8b4336 Merge pull request #1883 from JuliDi/net-socket-bind-error
embassy-net: Improve error when socket is not bound
2023-09-10 20:33:29 +00:00
e308286f3c Merge pull request #1881 from MabezDev/sdmmc-stbiterr
Handle stbiterr in 4bit wide mode for sdmmc_v1
2023-09-10 19:52:47 +00:00
268da2fcde Handle stbiterr in 4bit wide mode for sdmmc_v1 2023-09-10 20:27:38 +01:00
a992d4895d Merge pull request #1884 from xoviat/doc
stm32: fix docs
2023-09-10 18:52:42 +00:00
1bae34d37c stm32: fix docs 2023-09-10 13:50:28 -05:00
aac42e3209 Merge pull request #1882 from xoviat/rcc-f3
stm32/f3: add high res for hrtim and misc.
2023-09-10 18:35:33 +00:00
08415e001e stm32/f3: add high res for hrtim and misc. 2023-09-10 13:33:17 -05:00
d6a1b567ee add SocketNotBound error message 2023-09-10 20:13:56 +02:00
a47fb42962 Merge pull request #1878 from xoviat/adc
stm32: fix adc f3 and example
2023-09-10 03:02:42 +00:00
70a4a193c5 stm32: fix adc f3 and example 2023-09-09 22:01:51 -05:00
2132afb48b Merge pull request #1874 from JuliDi/eth-getstatus-async
embassy-net: add async wait_config_up
2023-09-09 20:06:52 +00:00
0e9131fd14 yield -> return
Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
2023-09-09 12:36:57 +02:00
40a18b075d improve docstring 2023-09-09 09:50:24 +02:00
f17f09057d Merge pull request #1877 from xoviat/rcc
rcc: more cleanup
2023-09-08 23:22:39 +00:00
11a78fb1e4 rcc: more cleanup 2023-09-08 18:20:58 -05:00
48154e18bf Merge pull request #1873 from vDorst/adin1110-pr3
Adin1110: documents and comment fixes
2023-09-08 18:11:47 +00:00
cf2d4eca7c add wait_config_up to examples 2023-09-08 17:40:20 +02:00
3e0b752bef fix poll_fn, add documentation 2023-09-08 17:26:01 +02:00
6070d61d8c fix typos 2023-09-08 15:59:46 +02:00
a4f8d82ef5 wait_config_up first steps 2023-09-08 15:58:47 +02:00
c27b0296fe Add more documentation and comment 2023-09-07 22:32:20 +02:00
336ae54a56 mdio: reenable and async the tests 2023-09-07 21:25:53 +02:00
d6a1118406 fix some spelling 2023-09-07 21:02:33 +02:00
9de08d56a0 nrf: spim: Anomaly 109 workaround for SPIM peripheral (#460)
This implements SPIM TX workaround suggested from section 3.8.1
from Anomaly 109 addendum.

In workaround case we first keep track of original maxcnt values,
then initiate "fake" transfer with zero-length maxcnt values.
Once the "fake" transfer is triggered, we handle it, fill in the
original maxcnt values and restart the transmission.
2023-09-07 18:58:22 +03:00
26740bb3ef Merge pull request #1869 from xoviat/rcc-bd
add rcc bd lsi/lse abstraction
2023-09-06 23:24:24 +00:00
4550452f43 rustfmt 2023-09-06 17:53:02 -05:00
08410432b5 stm32: fix rcc merge 2023-09-06 17:51:40 -05:00
3cf3caa3ab Merge branch 'main' into rcc-bd 2023-09-06 17:49:29 -05:00
c21ad04c2e stm32: extract lse/lsi into bd mod 2023-09-06 17:48:12 -05:00
d097c99719 stm32/rcc: add lsi and lse bd abstraction 2023-09-06 17:33:56 -05:00
af7c93abba Merge pull request #1864 from oll3/feat/stm32wl-adc
ADC support for STM32WLx
2023-09-06 16:32:12 +00:00
c356585a59 update metapac tag 2023-09-06 11:49:18 +02:00
0d3ff34d80 adc: enable ADC and clock selection for STM32WLx 2023-09-06 06:57:30 +02:00
bb2d6c8542 adc_v3: replace cfg(stm32g0) + friends with cfg(adc_g0)
Since any MCU (not just STM32G0) using adc_g0 should probably be handled the same way.
2023-09-06 06:57:28 +02:00
a05afc5426 Merge pull request #1867 from xoviat/adc-g4
Adc g4
2023-09-05 23:31:03 +00:00
50116e5b27 remove paste dependency 2023-09-05 18:20:17 -05:00
a80acf686e Merge pull request #1868 from MabezDev/f2-rtc-clocks
[F2] Allow the RTC clock source to be configured with the new RTC mechanism
2023-09-05 23:13:57 +00:00
6770d8e8a6 Allow the RTC clock source to be configured with the new RTC mechanism 2023-09-06 00:04:09 +01:00
7307098780 stm32: don't generate adc5 2023-09-05 17:50:45 -05:00
f4601af2a4 stm32: don't generate adc4 for g4 2023-09-05 17:48:20 -05:00
fd22f4fac5 stm32: remove paste and use refcount statics 2023-09-05 17:45:52 -05:00
7622d2eb61 stm32: fix merge issues 2023-09-05 17:10:15 -05:00
7573160077 Merge branch 'main' of https://github.com/embassy-rs/embassy into adc-g4 2023-09-05 17:02:28 -05:00
7e18e5e0c1 Merge branch 'stm32g4_adc' of https://github.com/daehyeok/embassy into adc-g4 2023-09-05 16:50:33 -05:00
9d76a6e933 Merge pull request #1849 from xoviat/adc-f3
Add adc f3
2023-09-05 21:48:44 +00:00
f502271940 stm32: add initial adc f3 impl 2023-09-05 16:46:57 -05:00
e2f8bf19ea Merge pull request #1865 from embassy-rs/esp-hosted-status
net-esp-hosted: add get_status()
2023-09-05 18:33:22 +00:00
1180e1770d net-esp-hosted: add get_status() 2023-09-05 19:50:21 +02:00
49ba9c3da2 initial support for STM32G4 ADC 2023-09-04 23:36:41 -07:00
ce662766be Merge pull request #1771 from rubdos/zero-copy-channel
embassy_sync::zero_copy_channel
2023-09-04 23:38:11 +02:00
a03b6be693 Merge pull request #1862 from xoviat/rcc-refcount
stm32: refcount peripheral enable/disable
2023-09-04 23:37:59 +02:00
87d3086533 Merge pull request #1863 from embassy-rs/reenable-test
Revert "ci: remove failing tests"
2023-09-04 23:20:00 +02:00
d19e1c1dd1 stm32: only refcount usart and use kind direclty 2023-09-04 16:18:31 -05:00
8a55adbfd8 Revert "ci: remove failing tests"
This reverts commit c5732ce285.
2023-09-04 23:16:48 +02:00
6dc56d2b35 stm32: include uart-named peripherals 2023-09-04 16:04:29 -05:00
394503ab69 ci: run HIL 2023-09-04 15:54:23 -05:00
bfb4cf775a remove adc refcount 2023-09-04 15:54:00 -05:00
274f63a879 stm32: fix refcounts for usart, spi, and i2c 2023-09-04 15:47:33 -05:00
615882ebd6 Rename zero_copy -> zerocopy. 2023-09-04 22:16:28 +02:00
6e38b07642 Add docs to zero-copy-channel 2023-09-04 22:13:27 +02:00
1eb03dc41a Prefer receive over recv 2023-09-04 22:13:27 +02:00
a2656f402b Move embassy-net-driver-channel::zerocopy_channel to embassy_sync::zero_copy_channel 2023-09-04 22:13:27 +02:00
3466c9cfa9 stm32: refcount peripheral enable/disable 2023-09-04 13:47:02 -05:00
3295ec94e5 Merge pull request #1858 from xoviat/psc-cleanup
stm32: cleanup psc design
2023-09-03 16:49:27 +00:00
c5732ce285 ci: remove failing tests 2023-09-03 11:48:41 -05:00
2e6f4237f2 stm32: cleanup psc design 2023-09-03 11:40:34 -05:00
ac11635b0b Merge pull request #1856 from embassy-rs/teleprobe-cache
Add teleprobe cache.
2023-09-03 01:45:28 +02:00
9dd58660c3 Add teleprobe cache. 2023-09-03 01:41:52 +02:00
9baa3bafb0 Merge pull request #1854 from bugadani/str
embassy-{net, sync, time}: Use fmt::unwrap
2023-09-03 00:35:21 +02:00
360286e67c Fix bootloader application examples 2023-09-02 08:50:03 +02:00
0c66636d00 Use fmt::unwrap 2023-09-02 08:39:52 +02:00
9d8c527308 Merge pull request #1831 from vDorst/adin1110-part2
embassy-net-adin1110 more improvements
2023-09-02 00:49:17 +02:00
1d87ec9cc3 stm32/qei: fix struct naming (#1852)
Co-authored-by: xoviat <xoviat@users.noreply.github.com>
2023-09-02 00:30:27 +02:00
b74645e259 Delete .github/bors.toml 2023-09-01 00:21:01 +02:00
56351cedcb Merge pull request #1844 from xoviat/rtc
stm32/rtc: autocompute prescalers
2023-08-30 23:28:00 +00:00
0823d9dc93 Merge pull request #1845 from xoviat/qei
stm32: add qei
2023-08-30 23:16:33 +00:00
c10fb7c1c4 stm32: implement qei 2023-08-30 18:10:26 -05:00
a2ce3aa1a1 Merge pull request #1848 from kalkyl/rp-write-size
rp: Fix write size in embassy-boot example app
2023-08-30 21:34:34 +00:00
3769447382 rp: Fix write size in embassy-boot example app 2023-08-30 23:20:38 +02:00
2c6b428ed4 Merge pull request #1847 from mvniekerk/main
RP2040: XOSC delay multiplier
2023-08-30 20:00:40 +00:00
83a976cf4b RP2040: Fixes as per PR 2023-08-30 21:59:41 +02:00
a76ff53fb3 RP2040: Fixes as per PR 2023-08-30 21:58:36 +02:00
f69e8459c9 RP2040: Fixes as per PR 2023-08-30 21:52:03 +02:00
891f1758bc RP2040: XOSC delay multiplier 2023-08-30 21:43:57 +02:00
ae174fd0e0 RP2040: XOSC delay multiplier 2023-08-30 21:42:27 +02:00
5c936d33d4 Merge pull request #1846 from diondokter/stm32-timer-prevent-hardfault
Stm32 timer prevent hardfault when frequency is 0
2023-08-30 17:40:06 +00:00
36ec9bcc1d Stm32 timer prevent hardfault 2023-08-30 19:35:15 +02:00
5adc80f6d9 Merge pull request #1838 from Frostie314159/cyw43-next
cyw43: Add utility functions.
2023-08-30 14:04:27 +00:00
98f55fa54d Reverted patch for lint fix. 2023-08-30 09:59:47 +02:00
416ecc73d8 add qei draft 2023-08-29 20:06:53 -05:00
27dfced285 stm32: fix rcc wb 2023-08-29 19:51:21 -05:00
21681d8b4e rustfmt 2023-08-29 19:44:43 -05:00
989c98f316 stm32/rtc: autocompute prescalers 2023-08-29 19:41:03 -05:00
fdb2c4946a Merge pull request #1843 from embassy-rs/fmt-sync
Sync all fmt.rs files.
2023-08-29 23:42:59 +00:00
5e613d9abb Sync all fmt.rs files. 2023-08-30 01:37:18 +02:00
40b576584e Merge pull request #1832 from embassy-rs/pipe-bufread
sync/pipe: impl BufRead.
2023-08-29 23:12:06 +00:00
aa7752020e Merge pull request #1842 from embassy-rs/ppp-terminate
net-ppp: return error when PPP link gets terminated by the peer.
2023-08-29 23:09:30 +00:00
6c165f8dc0 sync/pipe: impl BufRead. 2023-08-30 01:06:41 +02:00
975f2f23c0 net-ppp: return error when PPP link gets terminated by the peer. 2023-08-30 01:04:43 +02:00
0eeefd3dbf cyw43: Make Scanner public. 2023-08-29 23:05:05 +02:00
de01fe352b Removed unnecessary newline. 2023-08-29 08:35:29 +02:00
70662ec4ba embassy-time: Introduced reset function for Ticker 2023-08-29 08:29:38 +02:00
a4d78a6552 Merge pull request #1835 from oll3/fix/stm32-rng
stm32: fix wait for RNG data
2023-08-28 21:38:54 +00:00
f503417f4c Merge pull request #1833 from xoviat/rtc
stm32: misc rtc fixes
2023-08-28 21:18:42 +00:00
6b8b145266 stm32: revert changes to rcc f4 2023-08-28 16:17:42 -05:00
e07f943562 rustfmt 2023-08-28 15:52:13 -05:00
70a5221b2e stm32/bd: consolidate enable_rtc 2023-08-28 15:34:08 -05:00
b315c28d4e stm32/rtc: remove rtc-debug and asbtract exti wakeup 2023-08-28 15:30:29 -05:00
e025693914 cyw43: Create leave function on Control struct.
Create a function, which disassociates us, from the currently connected infra.
2023-08-28 21:34:14 +02:00
05ee02b593 cyw43: Introduce seperate up/down functions.
Create two helper functions, for setting the interface up/down.
2023-08-28 21:32:31 +02:00
4098a61ef0 cyw43: Fix warning in event.rs.
Allow non_upper_case_globals, to prevent the compiler from spitting out a warning about the Event enum.
2023-08-28 21:02:38 +02:00
1db00f5439 embassy-net-adin1110: Add basic benchmark results. 2023-08-28 20:11:56 +02:00
7fc17bc150 embassy-net-adin1110 bump deps. 2023-08-28 19:29:32 +02:00
6e616a6fe6 Update comment about turn around byte. 2023-08-28 19:23:15 +02:00
d02886786e Show the error type 2023-08-28 19:00:00 +02:00
2db4d01198 Merge branch 'embassy-rs:main' into adin1110-part2 2023-08-28 16:45:17 +00:00
a36ee75d19 Merge pull request #1836 from jessebraham/feature/release
Release embassy-time v0.1.3
2023-08-28 15:05:11 +00:00
1f63bf4153 Release embassy-time v0.1.3 2023-08-28 08:00:18 -07:00
fd739250ea stm32: fix wait for RNG data
If no data was available to read then the loop would wait for an interrupt and skip to the next chunk without writing the current one.
This could cause the given slice to only be partially filled with random data.

Fixed by moving the wait to before actually writing data to the chunk.
2023-08-28 11:44:05 +02:00
71c4e7e4d2 Fix timing on RP2040 pio_ws2812.rs example
The example spins too fast so it doesn't appear to change;
it's delaying for microseconds instead of milliseconds.
This commit slows it down and adds a comment noting the pin
mapping for the Adafruit feather rp2040+RFM95 LoRA module,
which has its Neopixel on pin 4 instead of 16.
2023-08-27 22:39:44 -04:00
2c80784fe6 stm32/rtc: feature-gate instant 2023-08-27 21:26:29 -05:00
538001a4bc stm32/rtc: fix psc div 2023-08-27 21:24:16 -05:00
e981cd4968 stm32: fix rtc wakeup timing and add dbg 2023-08-27 21:15:57 -05:00
91bb3aae3f stm32l4: bump embassy-net-adin1110 to v0.2.0 2023-08-28 00:32:05 +02:00
e08dbcd027 embassy-net-adin1110: bump version v0.2.0 2023-08-28 00:32:05 +02:00
5c27265a21 Add fmt.rs to improve log/debug and embbed and PC
Also add `defmt` to the features list.
2023-08-28 00:31:51 +02:00
2c36199dea stm32l4: Update adin1110 example add FCS option 2023-08-28 00:28:45 +02:00
13a0be6289 Validate FCS in fifo_read() and refactor tests.
Adding TestHarnass to declutter the tests.
Also added a test for FCS and SPI_CRC.
2023-08-28 00:28:40 +02:00
9f928010a8 stm32/rtc: use psc to compute instants 2023-08-27 16:06:33 -05:00
88146eb53e Merge pull request #1830 from xoviat/rtc
stm32: move backup domain in rcc mod
2023-08-27 20:26:41 +00:00
326e78757b rustfmt 2023-08-27 15:25:12 -05:00
f77a7fe4bf Merge branch 'main' of https://github.com/aidant/embassy into rtc 2023-08-27 15:23:25 -05:00
cbc92dce05 stm32/bd: fix errors 2023-08-27 15:18:34 -05:00
531f51d0eb rcc/bd: consolidate mod 2023-08-27 15:01:09 -05:00
f28ab18d7b stm32: fix l4 re-export 2023-08-27 09:50:02 -05:00
3bf6081eb5 stm32: fix wl re-export 2023-08-27 09:41:31 -05:00
fb942e6675 stm32: re-export rtcclocksource 2023-08-27 09:25:14 -05:00
10ea068027 stm32/bd: allow dead code 2023-08-27 09:12:04 -05:00
4caa8497fc stm32: extract backupdomain into mod 2023-08-27 09:07:34 -05:00
48085939e7 stm32/rcc: rename common to bus 2023-08-27 08:35:13 -05:00
7f7256050c Don't let the MAC add FCS when it is done by app
The application can append FSC to outgoing packets and the MAC can detect
and report when a bitflip has occurred.

But the MAC can also add FSC if we want, but we can´t do both.
When adding FSC by the application and MAC results in the packet drop by
the MAC when the TX packet size > (MTU - 4).
Having the application append the FSC is preferred.

So set the right config bits.
2023-08-27 10:37:45 +02:00
4b6538c8a8 Fix read_fifo() better readout and more checks
read_fifo() used part of the frame buffer to readout non-frame data.
This results in incorrect readout of the fifo buffer but also the full
MTU could not be used.

Also added some more tests to check this and that the readout is a
multipule of 4 bytes.
2023-08-27 10:37:45 +02:00
db6f9afa2e fix hanging on rtc example 2023-08-27 18:37:10 +10:00
59a5e84df5 fix day of the week conversion 2023-08-27 18:36:35 +10:00
13f0501673 Merge pull request #1822 from xoviat/rtc-lp
stm32: get stop mode working
2023-08-27 01:47:46 +00:00
94de1a5353 stm32: feature-gate wakeup alarm 2023-08-26 20:40:21 -05:00
db71887817 tests/stm32: add stop and cleanpu 2023-08-26 20:37:01 -05:00
1e430f7413 stm32: complete stop impl. 2023-08-26 20:31:12 -05:00
2897670f24 stm32: get the basic lp working 2023-08-26 19:23:25 -05:00
ca738d6c99 Merge pull request #1826 from bugadani/warn
Avoid dead code warning
2023-08-26 11:05:03 +00:00
d33246b072 Add new feature/arch combinations to executor CI check 2023-08-26 12:54:23 +02:00
54e2e17520 Avoid dead code warning 2023-08-26 12:53:39 +02:00
3023e70ccf stm32: clenaup lp executor 2023-08-25 18:41:51 -05:00
cda4047310 stm32: flesh out lp executor 2023-08-24 19:29:11 -05:00
f033089625 Merge pull request #3 from embassy-rs/main
Update to embassy head
2023-08-24 17:38:04 -06:00
6d8a5c6c20 Merge pull request #2 from embassy-rs/main
Pull changes from base embassy repo
2023-07-16 19:08:01 -05:00
3aedbce5c2 Merge pull request #1 from embassy-rs/main
Pull changes from embassy main
2023-07-01 15:41:11 -05:00
536 changed files with 14858 additions and 10743 deletions

4
.github/bors.toml vendored
View File

@ -1,4 +0,0 @@
status = [
"all",
]
delete_merged_branches = true

View File

@ -8,6 +8,10 @@ export RUSTUP_HOME=/ci/cache/rustup
export CARGO_HOME=/ci/cache/cargo
export CARGO_TARGET_DIR=/ci/cache/target
# needed for "dumb HTTP" transport support
# used when pointing stm32-metapac to a CI-built one.
export CARGO_NET_GIT_FETCH_WITH_CLI=true
hashtime restore /ci/cache/filetime.json || true
hashtime save /ci/cache/filetime.json

5
.github/ci/build.sh vendored
View File

@ -11,8 +11,13 @@ if [ -f /ci/secrets/teleprobe-token.txt ]; then
echo Got teleprobe token!
export TELEPROBE_HOST=https://teleprobe.embassy.dev
export TELEPROBE_TOKEN=$(cat /ci/secrets/teleprobe-token.txt)
export TELEPROBE_CACHE=/ci/cache/teleprobe_cache.json
fi
# needed for "dumb HTTP" transport support
# used when pointing stm32-metapac to a CI-built one.
export CARGO_NET_GIT_FETCH_WITH_CLI=true
hashtime restore /ci/cache/filetime.json || true
hashtime save /ci/cache/filetime.json

2
.github/ci/doc.sh vendored
View File

@ -48,8 +48,8 @@ kubectl cp webroot/static $POD:/data
# build and upload stm32 last
# so that it doesn't prevent other crates from getting docs updates when it breaks.
rm -rf webroot
docserver-builder -i ./embassy-stm32 -o webroot/crates/embassy-stm32/git.zup
POD=$(kubectl -n embassy get po -l app=docserver -o jsonpath={.items[0].metadata.name})
kubectl cp webroot/crates $POD:/data

4
.github/ci/test.sh vendored
View File

@ -8,6 +8,10 @@ export RUSTUP_HOME=/ci/cache/rustup
export CARGO_HOME=/ci/cache/cargo
export CARGO_TARGET_DIR=/ci/cache/target
# needed for "dumb HTTP" transport support
# used when pointing stm32-metapac to a CI-built one.
export CARGO_NET_GIT_FETCH_WITH_CLI=true
hashtime restore /ci/cache/filetime.json || true
hashtime save /ci/cache/filetime.json

View File

@ -62,9 +62,9 @@ async fn blink(pin: AnyPin) {
loop {
// Timekeeping is globally available, no need to mess with hardware timers.
led.set_high();
Timer::after(Duration::from_millis(150)).await;
Timer::after_millis(150).await;
led.set_low();
Timer::after(Duration::from_millis(150)).await;
Timer::after_millis(150).await;
}
}

135
ci.sh
View File

@ -1,9 +1,12 @@
#!/bin/bash
set -euo pipefail
set -eo pipefail
export RUSTFLAGS=-Dwarnings
export DEFMT_LOG=trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info
if [[ -z "${CARGO_TARGET_DIR}" ]]; then
export CARGO_TARGET_DIR=target_ci
fi
TARGET=$(rustc -vV | sed -n 's|host: ||p')
@ -19,11 +22,24 @@ cargo batch \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,log \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt \
--- build --release --manifest-path embassy-executor/Cargo.toml --target thumbv7em-none-eabi --features nightly,arch-cortex-m,executor-thread,executor-interrupt,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32 \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,integrated-timers \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread \
--- build --release --manifest-path embassy-executor/Cargo.toml --target riscv32imac-unknown-none-elf --features nightly,arch-riscv32,executor-thread,integrated-timers \
--- build --release --manifest-path embassy-sync/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt \
--- build --release --manifest-path embassy-time/Cargo.toml --target thumbv6m-none-eabi --features nightly,defmt,defmt-timestamp-uptime,tick-hz-32_768,generic-queue-8 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,dhcpv4,medium-ethernet,nightly,dhcpv4-hostname \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ieee802154 \
--- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv6,medium-ethernet,medium-ieee802154 \
@ -53,46 +69,68 @@ cargo batch \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,intrinsics \
--- build --release --manifest-path embassy-rp/Cargo.toml --target thumbv6m-none-eabi --features nightly,qspi-as-gpio \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,exti,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt,exti,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze,nightly,defmt \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f401ve,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f405zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f407zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f411ce,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f412zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f413vh,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f415zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f417zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f423zh,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f427zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f429zi,log,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f437zi,log,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f439zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f446ze,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f469zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f479zi,defmt,exti,time-driver-any,unstable-traits,embedded-sdmmc,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32f730i8,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h753zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h735zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32h7b3ai,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32l422cb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wb15cc,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l041f6,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32l073cz,defmt,exti,time-driver-any,unstable-traits,low-power,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f398ve,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f378cc,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32g0c1ve,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features nightly,stm32l552ze,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features nightly,stm32wl54jc-cm0p,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32wle5jb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features nightly,stm32g474pe,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f107vc,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f103re,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32f100c4,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h503rb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features nightly,stm32h562ag,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features ''\
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'log' \
--- build --release --manifest-path cyw43/Cargo.toml --target thumbv6m-none-eabi --features 'defmt' \
@ -131,9 +169,10 @@ cargo batch \
--- build --release --manifest-path examples/stm32l5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32l5 \
--- build --release --manifest-path examples/stm32u5/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32u5 \
--- build --release --manifest-path examples/stm32wb/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wb \
--- build --release --manifest-path examples/stm32wba/Cargo.toml --target thumbv8m.main-none-eabihf --out-dir out/examples/stm32wba \
--- build --release --manifest-path examples/stm32wl/Cargo.toml --target thumbv7em-none-eabihf --out-dir out/examples/stm32wl \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv7em-none-eabi --features embassy-nrf/nrf52840,skip-include --out-dir out/examples/boot/nrf52840 \
--- build --release --manifest-path examples/boot/application/nrf/Cargo.toml --target thumbv8m.main-none-eabihf --features embassy-nrf/nrf9160-ns,skip-include --out-dir out/examples/boot/nrf9160 \
--- build --release --manifest-path examples/boot/application/rp/Cargo.toml --target thumbv6m-none-eabi --features skip-include --out-dir out/examples/boot/rp \
--- build --release --manifest-path examples/boot/application/stm32f3/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f3 \
--- build --release --manifest-path examples/boot/application/stm32f7/Cargo.toml --target thumbv7em-none-eabi --features skip-include --out-dir out/examples/boot/stm32f7 \
@ -156,12 +195,26 @@ cargo batch \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55rg --out-dir out/tests/stm32wb55rg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h563zi --out-dir out/tests/stm32h563zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585ai --out-dir out/tests/stm32u585ai \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l073rz --out-dir out/tests/stm32l073rz \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l152re --out-dir out/tests/stm32l152re \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4a6zg --out-dir out/tests/stm32l4a6zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r5zi --out-dir out/tests/stm32l4r5zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv8m.main-none-eabihf --features stm32l552ze --out-dir out/tests/stm32l552ze \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f767zi --out-dir out/tests/stm32f767zi \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f207zg --out-dir out/tests/stm32f207zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303ze --out-dir out/tests/stm32f303ze \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l496zg --out-dir out/tests/stm32l496zg \
--- build --release --manifest-path tests/stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55jc --out-dir out/tests/stm32wl55jc \
--- build --release --manifest-path tests/rp/Cargo.toml --target thumbv6m-none-eabi --out-dir out/tests/rpi-pico \
--- build --release --manifest-path tests/nrf/Cargo.toml --target thumbv7em-none-eabi --out-dir out/tests/nrf52840-dk \
--- build --release --manifest-path tests/riscv32/Cargo.toml --target riscv32imac-unknown-none-elf \
$BUILD_EXTRA
rm out/tests/stm32wb55rg/wpan_mac
rm out/tests/stm32wb55rg/wpan_ble
rm out/tests/stm32f207zg/eth
if [[ -z "${TELEPROBE_TOKEN-}" ]]; then
echo No teleprobe token found, skipping running HIL tests
exit

View File

@ -40,33 +40,38 @@ cargo batch \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g473cc,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32g491re,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32u585zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wb55vy,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32wl55cc-cm4,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l4r9zi,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f303vc,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f411ce,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f410tb,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32f429zi,log,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32h755zi-cm7,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7em-none-eabi --features stm32l476vg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv6m-none-eabi --features stm32l072cz,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32l151cb-a,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,time \
--- build --release --manifest-path embassy-stm32/Cargo.toml --target thumbv7m-none-eabi --features stm32f217zg,defmt,exti,time-driver-any,unstable-traits,time \
--- build --release --manifest-path examples/nrf52840/Cargo.toml --target thumbv7em-none-eabi --no-default-features --out-dir out/examples/nrf52840 --bin raw_spawn \
--- build --release --manifest-path examples/stm32l0/Cargo.toml --target thumbv6m-none-eabi --no-default-features --out-dir out/examples/stm32l0 --bin raw_spawn \

View File

@ -11,11 +11,10 @@ log = ["dep:log"]
firmware-logs = []
[dependencies]
embassy-time = { version = "0.1.2", path = "../embassy-time"}
embassy-sync = { version = "0.2.0", path = "../embassy-sync"}
embassy-time = { version = "0.1.5", path = "../embassy-time"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"}
atomic-polyfill = "0.1.5"
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"}
defmt = { version = "0.3", optional = true }
log = { version = "0.4.17", optional = true }
@ -31,4 +30,4 @@ num_enum = { version = "0.5.7", default-features = false }
src_base = "https://github.com/embassy-rs/embassy/blob/cyw43-v$VERSION/cyw43/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/cyw43/src/"
target = "thumbv6m-none-eabi"
features = ["defmt", "firmware-logs"]
features = ["defmt", "firmware-logs"]

View File

@ -1,5 +1,5 @@
use embassy_futures::yield_now;
use embassy_time::{Duration, Timer};
use embassy_time::Timer;
use embedded_hal_1::digital::OutputPin;
use futures::FutureExt;
@ -51,9 +51,9 @@ where
pub async fn init(&mut self) {
// Reset
self.pwr.set_low().unwrap();
Timer::after(Duration::from_millis(20)).await;
Timer::after_millis(20).await;
self.pwr.set_high().unwrap();
Timer::after(Duration::from_millis(250)).await;
Timer::after_millis(250).await;
while self
.read32_swapped(REG_BUS_TEST_RO)

View File

@ -96,6 +96,7 @@ 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;

View File

@ -1,8 +1,8 @@
use core::cmp::{max, min};
use ch::driver::LinkState;
use embassy_net_driver_channel as ch;
use embassy_time::{Duration, Timer};
use embassy_net_driver_channel::driver::{HardwareAddress, LinkState};
use embassy_time::Timer;
pub use crate::bus::SpiBusCyw43;
use crate::consts::*;
@ -87,22 +87,22 @@ impl<'a> Control<'a> {
self.set_iovar("country", &country_info.to_bytes()).await;
// set country takes some time, next ioctls fail if we don't wait.
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
// Set antenna to chip antenna
self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await;
self.set_iovar_u32("bus:txglom", 0).await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
//self.set_iovar_u32("apsta", 1).await; // this crashes, also we already did it before...??
//Timer::after(Duration::from_millis(100)).await;
//Timer::after_millis(100).await;
self.set_iovar_u32("ampdu_ba_wsize", 8).await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
self.set_iovar_u32("ampdu_mpdu", 4).await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
//self.set_iovar_u32("ampdu_rx_factor", 0).await; // this crashes
//Timer::after(Duration::from_millis(100)).await;
//Timer::after_millis(100).await;
// evts
let mut evts = EventMask {
@ -121,23 +121,33 @@ impl<'a> Control<'a> {
self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
// set wifi up
self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await;
self.up().await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto
self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
self.state_ch.set_ethernet_address(mac_addr);
self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr));
debug!("INIT DONE");
}
/// Set the WiFi interface up.
async fn up(&mut self) {
self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await;
}
/// Set the interface down.
async fn down(&mut self) {
self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await;
}
pub async fn set_power_management(&mut self, mode: PowerManagementMode) {
// power save mode
let mode_num = mode.mode();
@ -175,7 +185,7 @@ impl<'a> Control<'a> {
self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await;
self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await;
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
let mut pfi = PassphraseInfo {
len: passphrase.len() as _,
@ -256,13 +266,13 @@ impl<'a> Control<'a> {
}
// Temporarily set wifi down
self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await;
self.down().await;
// Turn off APSTA mode
self.set_iovar_u32("apsta", 0).await;
// Set wifi up again
self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await;
self.up().await;
// Turn on AP mode
self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 1).await;
@ -287,7 +297,7 @@ impl<'a> Control<'a> {
if security != Security::OPEN {
self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
// Set passphrase
let mut pfi = PassphraseInfo {
@ -423,6 +433,11 @@ impl<'a> Control<'a> {
events: &self.events,
}
}
/// Leave the wifi, with which we are currently associated.
pub async fn leave(&mut self) {
self.ioctl(IoctlType::Set, IOCTL_CMD_DISASSOC, 0, &mut []).await;
info!("Disassociated")
}
}
pub struct Scanner<'a> {

View File

@ -83,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -226,7 +229,8 @@ impl<T, E> Try for Result<T, E> {
}
}
pub struct Bytes<'a>(pub &'a [u8]);
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

View File

@ -27,7 +27,7 @@ use ioctl::IoctlState;
use crate::bus::Bus;
pub use crate::bus::SpiBusCyw43;
pub use crate::control::{Control, Error as ControlError};
pub use crate::control::{Control, Error as ControlError, Scanner};
pub use crate::runner::Runner;
pub use crate::structs::BssInfo;

View File

@ -555,14 +555,14 @@ where
self.bus.bp_write8(base + AI_RESETCTRL_OFFSET, 0).await;
Timer::after(Duration::from_millis(1)).await;
Timer::after_millis(1).await;
self.bus
.bp_write8(base + AI_IOCTRL_OFFSET, AI_IOCTRL_BIT_CLOCK_EN)
.await;
let _ = self.bus.bp_read8(base + AI_IOCTRL_OFFSET).await;
Timer::after(Duration::from_millis(1)).await;
Timer::after_millis(1).await;
}
async fn core_is_up(&mut self, core: Core) -> bool {

View File

@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
embassy-executor = { version = "0.3.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] }
embassy-time = { version = "0.1.0", path = "../../../../../embassy-time", features = ["defmt", "nightly"] }
embassy-time = { version = "0.1.4", path = "../../../../../embassy-time", features = ["defmt", "nightly"] }
embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] }
defmt = "0.3"

View File

@ -1,6 +1,6 @@
* xref:getting_started.adoc[Getting started]
** xref:basic_application.adoc[Basic application]
** xref:layer_by_layer.adoc[Layer by Layer]
* xref:layer_by_layer.adoc[Bare metal to async]
* xref:runtime.adoc[Executor]
* xref:hal.adoc[HAL]
** xref:nrf.adoc[nRF]
@ -8,3 +8,5 @@
* xref:bootloader.adoc[Bootloader]
* xref:examples.adoc[Examples]
* xref:developer.adoc[Developer]
** xref:developer_stm32.adoc[Developer: STM32]

View File

@ -48,7 +48,7 @@ The `Spawner` is the way the main application spawns other tasks. The `Periphera
include::example$basic/src/main.rs[lines="22..-1"]
----
What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy::main]` macro. The macro does the following:
What happens when the `blinker` task has been spawned and main returns? Well, the main entry point is actually just like any other task, except that you can only have one and it takes some specific type arguments. The magic lies within the `#[embassy_executor::main]` macro. The macro does the following:
. Creates an Embassy Executor
. Initializes the microcontroller HAL to get the `Peripherals`

View File

@ -0,0 +1 @@
= Developer Documentation

View File

@ -0,0 +1,79 @@
= Developer Documentation: STM32
== Understanding metapac
When a project that imports `embassy-stm32` is compiled, that project selects the feature corresponding to the chip that project is using. Based on that feature, `embassy-stm32` selects supported link:https://anysilicon.com/ip-intellectual-property-core-semiconductors/[IP] for the chip, and enables the corresponding HAL implementations. But how does `embassy-stm32` know what IP the chip contains, out of the hundreds of chips that we support? It's a long story that starts with `stm32-data-sources`.
== `stm32-data-sources`
link:https://github.com/embassy-rs/stm32-data-sources[`stm32-data-sources`] is as mostly barren repository. It has no README, no documentation, and few watchers. But it's the core of what makes `embassy-stm32` possible. The data for every chip that we support is taken in part from a corresponding XML file like link:https://github.com/embassy-rs/stm32-data-sources/blob/b8b85202e22a954d6c59d4a43d9795d34cff05cf/cubedb/mcu/STM32F051K4Ux.xml[`STM32F051K4Ux.xml`]. In that file, you'll see lines like the following:
[source,xml]
----
<IP InstanceName="I2C1" Name="I2C" Version="i2c2_v1_1_Cube"/>
<!-- snip -->
<IP ConfigFile="TIM-STM32F0xx" InstanceName="TIM1" Name="TIM1_8F0" Version="gptimer2_v2_x_Cube"/>
----
These lines indicate that this chip has an i2c, and that it's version is "v1_1". It also indicates that it has a general purpose timer that with a version of "v2_x". From this data, it's possible to determine which implementations should be included in `embassy-stm32`. But actually doing that is another matter.
== `stm32-data`
While all users of this project are familiar with `embassy-stm32`, fewer are familiar with the project that powers it: `stm32-data`. This project doesn't just aim to generate data for `embassy-stm32`, but for machine consumption in general. To acheive this, information from multiple files from the `stm32-data-sources` project are combined and parsed to assign register block implementations for each supported IP. The core of this matching resides in `chips.rs`:
[source,rust]
----
(".*:I2C:i2c2_v1_1", ("i2c", "v2", "I2C")),
// snip
(r".*TIM\d.*:gptimer.*", ("timer", "v1", "TIM_GP16")),
----
In this case, the i2c version corresponds to our "v2" and the general purpose timer version corresponds to our "v1". Therefore, the `i2c_v2.yaml` and `timer_v1.yaml` register block implementations are assigned to those IP, respectively. The result is that these lines arr generated in `STM32F051K4.json`:
[source,json]
----
{
"name": "I2C1",
"address": 1073763328,
"registers": {
"kind": "i2c",
"version": "v2",
"block": "I2C"
},
// snip
}
// snip
{
"name": "TIM1",
"address": 1073818624,
"registers": {
"kind": "timer",
"version": "v1",
"block": "TIM_ADV"
},
// snip
}
----
In addition to register blocks, data for pin and RCC mapping is also generated and consumed by `embassy-stm32`. `stm32-metapac-gen` is used to package and publish the data as a crate.
== `embassy-stm32`
In the `lib.rs` file located in the root of `embassy-stm32`, you'll see this line:
[source,rust]
----
#[cfg(i2c)]
pub mod i2c;
----
And in the `mod.rs` of the i2c mod, you'll see this:
[source,rust]
----
#[cfg_attr(i2c_v2, path = "v2.rs")]
----
Because i2c is supported for STM32F051K4 and its version corresponds to our "v2", the `i2c` and `i2c_v2`, configuration directives will be present, and `embassy-stm32` will include these files, respectively. This and other configuration directives and tables are generated from the data for chip, allowing `embassy-stm32` to expressively and clearly adapt logic and implementations to what is required for each chip. Compared to other projects across the embedded ecosystem, `embassy-stm32` is the only project that can re-use code across the entire stm32 lineup and remove difficult-to-implement unsafe logic to the HAL.

View File

@ -3,7 +3,7 @@
So you want to try Embassy, great! To get started, there are a few tools you need to install:
* link:https://rustup.rs/[rustup] - the Rust toolchain is needed to compile Rust code.
* link:https://crates.io/crates/probe-run[probe-run] - to flash the firmware on your device. If you already have other tools like `OpenOCD` setup, you can use that as well.
* link:https://crates.io/crates/probe-rs[probe-rs] - to flash the firmware on your device. If you already have other tools like `OpenOCD` setup, you can use that as well.
If you don't have any supported board, don't worry: you can also run embassy on your PC using the `std` examples.
@ -30,6 +30,10 @@ Embassy supports many microcontroller families, but the easiest ways to get star
* link:https://www.raspberrypi.com/products/raspberry-pi-pico/[Raspberry Pi Pico]
=== ESP32
* link:https://github.com/esp-rs/esp-rust-board[ESP32C3]
== Running an example
First you need to clone the [github repository];
@ -38,7 +42,6 @@ First you need to clone the [github repository];
----
git clone https://github.com/embassy-rs/embassy.git
cd embassy
git submodule update --init
----
You can run an example by opening a terminal and entering the following commands:

View File

@ -7,4 +7,6 @@ Embassy provides HALs for several microcontroller families:
* `embassy-rp` for the Raspberry Pi RP2040 microcontrollers
These HALs implement async/await functionality for most peripherals while also implementing the
async traits in `embedded-hal-async`. You can also use these HALs with another executor.
async traits in `embedded-hal` and `embedded-hal-async`. You can also use these HALs with another executor.
For the ESP32 series, there is an link:https://github.com/esp-rs/esp-hal[esp-hal] which you can use.

View File

@ -4,14 +4,9 @@ Embassy is a project to make async/await a first-class option for embedded devel
== What is async?
Software written without async may block on I/O operations. In an std environment, such as a PC, software can handle this either by using threads or non-blocking operations.
When handling I/O, software must call functions that block program execution until the I/O operation completes. When running inside of an OS such as Linux, such functions generally transfer control to the kernel so that another task, known as a thread, can be executed if available, or the CPU can be put to sleep until another such task is ready to perform more work. Because an OS cannot presume that threads will behave cooperatively, threads are relatively resource-intensive, and may be forcibly interrupted they do not transfer control back to the kernel within an allotted time. But if tasks could be presumed to behave cooperatively, or at least not maliciously, it would be possible to create tasks that appear to be almost free when compared to a traditional OS thread. In Rust, these lightweight tasks, known as 'coroutines' or 'goroutines' in other languages, are implemented with async.
With threads, one thread blocks on an I/O operation, another is able to take its place. However, even on a PC, threads are relatively heavy, and therefore some programming languages, such as Go, have implemented a concept called coroutines or 'goroutines' that are much lighter and less-intensive than threads.
The other way to handle blocking I/O operations is to support polling the state of the underlying peripherals to check whether it is available to perform the requested operation. In programming languages without builtin async support,
this requires building a complex loop checking for events.
In Rust, non-blocking operations can be implemented using async-await. Async-await works by transforming each async function into an object called a future. When a future blocks on I/O the future yields, and the scheduler, called an executor, can select a different future to execute. Compared to alternatives such as an RTOS, async can yield better performance and lower power consumption because the executor doesn't have to guess when a future is ready to execute. However, program size may be higher than other alternatives, which may be a problem for certain space-constrained devices with very low memory. On the devices Embassy supports, such as stm32 and nrf, memory is generally large enough to accommodate the modestly-increased program size.
Async-await works by transforming each async function into an object called a future. When a future blocks on I/O the future yields, and the scheduler, called an executor, can select a different future to execute. Compared to alternatives such as an RTOS, async can yield better performance and lower power consumption because the executor doesn't have to guess when a future is ready to execute. However, program size may be higher than other alternatives, which may be a problem for certain space-constrained devices with very low memory. On the devices Embassy supports, such as stm32 and nrf, memory is generally large enough to accommodate the modestly-increased program size.
== What is Embassy?
@ -22,13 +17,26 @@ The Embassy project consists of several crates that you can use together or inde
* **Hardware Abstraction Layers** - HALs implement safe, idiomatic Rust APIs to use the hardware capabilities, so raw register manipulation is not needed. The Embassy project maintains HALs for select hardware, but you can still use HALs from other projects with Embassy.
** link:https://docs.embassy.dev/embassy-stm32/[embassy-stm32], for all STM32 microcontroller families.
** link:https://docs.embassy.dev/embassy-nrf/[embassy-nrf], for the Nordic Semiconductor nRF52, nRF53, nRF91 series.
** link:https://docs.embassy.dev/embassy-rp/[embassy-rp], for the Raspberry Pi RP2040 microcontroller.
** link:https://github.com/esp-rs[esp-rs], for the Espressif Systems ESP32 series of chips.
+
NOTE: A common question is if one can use the Embassy HALs standalone. Yes, it is possible! There are no dependency on the executor within the HALs. You can even use them without async,
as they implement both the link:https://github.com/rust-embedded/embedded-hal[Embedded HAL] blocking and async traits.
* **Networking** - The link:https://docs.embassy.dev/embassy-net/[embassy-net] network stack implements extensive networking functionality, including Ethernet, IP, TCP, UDP, ICMP and DHCP. Async drastically simplifies managing timeouts and serving multiple connections concurrently.
* **Networking** - The link:https://docs.embassy.dev/embassy-net/[embassy-net] network stack implements extensive networking functionality, including Ethernet, IP, TCP, UDP, ICMP and DHCP. Async drastically simplifies managing timeouts and serving multiple connections concurrently. Several drivers for WiFi and Ethernet chips can be found.
* **Bluetooth** - The link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate provides Bluetooth Low Energy 4.x and 5.x support for nRF52 microcontrollers.
* **LoRa** - link:https://docs.embassy.dev/embassy-lora/[embassy-lora] supports LoRa networking on STM32WL wireless microcontrollers and Semtech SX127x transceivers.
* **LoRa** - link:https://github.com/embassy-rs/lora-phy[lora-phy] and link:https://docs.embassy.dev/embassy-lora/[embassy-lora] supports LoRa networking on a wide range of LoRa radios, fully integrated with a Rust link:https://github.com/ivajloip/rust-lorawan[LoRaWAN] implementation.
* **USB** - link:https://docs.embassy.dev/embassy-usb/[embassy-usb] implements a device-side USB stack. Implementations for common classes such as USB serial (CDC ACM) and USB HID are available, and a rich builder API allows building your own.
* **Bootloader and DFU** - link:https://github.com/embassy-rs/embassy/tree/master/embassy-boot[embassy-boot] is a lightweight bootloader supporting firmware application upgrades in a power-fail-safe way, with trial boots and rollbacks.
== Resources
For more reading material on async Rust and Embassy:
* link:https://tweedegolf.nl/en/blog/65/async-rust-vs-rtos-showdown[Comparsion of FreeRTOS and Embassy]
* link:https://dev.to/apollolabsbin/series/20707[Tutorials]
* link:https://blog.drogue.io/firmware-updates-part-1/[Firmware Updates with Embassy]

View File

@ -1,4 +1,4 @@
= Embassy layer by layer
= From bare metal to async Rust
If you're new to Embassy, it can be overwhelming to grasp all the terminology and concepts. This guide aims to clarify the different layers in Embassy, which problem each layer solves for the application writer.
@ -8,8 +8,7 @@ The application we'll write is a simple 'push button, blink led' application, wh
== PAC version
The PAC is the lowest API for accessing peripherals and registers, if you don't count reading/writing directly to memory addresses. It provides distinct types
to make accessing peripheral registers easier, but it does not prevent you from writing unsafe code.
The PAC is the lowest API for accessing peripherals and registers, if you don't count reading/writing directly to memory addresses. It provides distinct types to make accessing peripheral registers easier, but it does not prevent you from writing unsafe code.
Writing an application using the PAC directly is therefore not recommended, but if the functionality you want to use is not exposed in the upper layers, that's what you need to use.

View File

@ -8,7 +8,7 @@ The nRF timer driver operates at 32768 Hz by default.
== Peripherals
The following peripherals have a HAL implementation at present:
The following peripherals have a HAL implementation at present
* PWM
* SPIM
@ -23,3 +23,7 @@ The following peripherals have a HAL implementation at present:
* UARTE
* TWIM
* SAADC
== Bluetooth
For bluetooth, you can use the link:https://github.com/embassy-rs/nrf-softdevice[nrf-softdevice] crate.

View File

@ -6,11 +6,11 @@ The Embassy executor is an async/await executor designed for embedded usage alon
* No `alloc`, no heap needed. Task are statically allocated.
* No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
* Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
* Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`.
* No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
* Efficient polling: a wake will only poll the woken task, not all of them.
* Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.
* Creating multiple executor instances is supported, to run tasks with multiple priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
* Creating multiple executor instances is supported, to run tasks at different priority levels. This allows higher-priority tasks to preempt lower-priority tasks.
== Executor

View File

@ -28,7 +28,7 @@ digest = "0.10"
log = { version = "0.4", optional = true }
ed25519-dalek = { version = "1.0.1", default_features = false, features = ["u32_backend"], optional = true }
embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" }
embassy-sync = { version = "0.2.0", path = "../../embassy-sync" }
embassy-sync = { version = "0.3.0", path = "../../embassy-sync" }
embedded-storage = "0.3.0"
embedded-storage-async = { version = "0.4.0", optional = true }
salty = { git = "https://github.com/ycrypto/salty.git", rev = "a9f17911a5024698406b75c0fac56ab5ccf6a8c7", optional = true }

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -20,8 +20,8 @@ default = ["time"]
[dependencies]
embassy-futures = { version = "0.1.0", path = "../embassy-futures", optional = true }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = [
"unproven",
] }

View File

@ -11,7 +11,7 @@ pub use asynch::Partition;
pub use blocking::BlockingPartition;
/// Partition error
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error<T> {
/// The requested flash area is outside the partition

View File

@ -1,5 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections, try_blocks))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, try_blocks))]
#![warn(missing_docs)]
//! Utilities to use `embedded-hal` traits with Embassy.
@ -26,6 +26,18 @@ pub trait SetConfig {
/// The configuration type used by this driver.
type Config;
/// The error type that can occur if `set_config` fails.
type ConfigError;
/// Set the configuration of the driver.
fn set_config(&mut self, config: &Self::Config);
fn set_config(&mut self, config: &Self::Config) -> Result<(), Self::ConfigError>;
}
/// Get the configuration of a peripheral driver.
pub trait GetConfig {
/// The configuration type used by this driver.
type Config;
/// Get the configuration of the driver.
fn get_config(&self) -> Self::Config;
}

View File

@ -125,14 +125,14 @@ where
{
async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
let mut bus = self.bus.lock().await;
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
Ok(())
}
async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
let mut bus = self.bus.lock().await;
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
Ok(())
}
@ -144,7 +144,7 @@ where
rd_buffer: &mut [u8],
) -> Result<(), I2cDeviceError<BUS::Error>> {
let mut bus = self.bus.lock().await;
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.write_read(address, wr_buffer, rd_buffer)
.await
.map_err(I2cDeviceError::I2c)?;
@ -153,7 +153,7 @@ where
async fn transaction(&mut self, address: u8, operations: &mut [i2c::Operation<'_>]) -> Result<(), Self::Error> {
let mut bus = self.bus.lock().await;
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.transaction(address, operations)
.await
.map_err(I2cDeviceError::I2c)?;

View File

@ -76,9 +76,7 @@ where
#[cfg(not(feature = "time"))]
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
#[cfg(feature = "time")]
Operation::DelayUs(us) => {
embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await
}
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
}
}
};
@ -130,7 +128,7 @@ where
{
async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
let mut bus = self.bus.lock().await;
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
let op_res: Result<(), BUS::Error> = try {
@ -143,9 +141,7 @@ where
#[cfg(not(feature = "time"))]
Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported),
#[cfg(feature = "time")]
Operation::DelayUs(us) => {
embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await
}
Operation::DelayUs(us) => embassy_time::Timer::after_micros(*us as _).await,
}
}
};

View File

@ -148,7 +148,7 @@ where
fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), Self::Error> {
self.bus.lock(|bus| {
let mut bus = bus.borrow_mut();
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.read(address, buffer).map_err(I2cDeviceError::I2c)
})
}
@ -156,7 +156,7 @@ where
fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), Self::Error> {
self.bus.lock(|bus| {
let mut bus = bus.borrow_mut();
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.write(address, bytes).map_err(I2cDeviceError::I2c)
})
}
@ -164,7 +164,7 @@ where
fn write_read(&mut self, address: u8, wr_buffer: &[u8], rd_buffer: &mut [u8]) -> Result<(), Self::Error> {
self.bus.lock(|bus| {
let mut bus = bus.borrow_mut();
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| I2cDeviceError::Config)?;
bus.write_read(address, wr_buffer, rd_buffer)
.map_err(I2cDeviceError::I2c)
})

View File

@ -163,7 +163,7 @@ where
fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
self.bus.lock(|bus| {
let mut bus = bus.borrow_mut();
bus.set_config(&self.config);
bus.set_config(&self.config).map_err(|_| SpiDeviceError::Config)?;
self.cs.set_low().map_err(SpiDeviceError::Cs)?;
let op_res = operations.iter_mut().try_for_each(|op| match op {

View File

@ -14,6 +14,8 @@ pub mod blocking;
pub enum I2cDeviceError<BUS> {
/// An operation on the inner I2C bus failed.
I2c(BUS),
/// Configuration of the inner I2C bus failed.
Config,
}
impl<BUS> i2c::Error for I2cDeviceError<BUS>
@ -23,6 +25,7 @@ where
fn kind(&self) -> i2c::ErrorKind {
match self {
Self::I2c(e) => e.kind(),
Self::Config => i2c::ErrorKind::Other,
}
}
}
@ -38,6 +41,8 @@ pub enum SpiDeviceError<BUS, CS> {
Cs(CS),
/// DelayUs operations are not supported when the `time` Cargo feature is not enabled.
DelayUsNotSupported,
/// The SPI bus could not be configured.
Config,
}
impl<BUS, CS> spi::Error for SpiDeviceError<BUS, CS>
@ -50,6 +55,7 @@ where
Self::Spi(e) => e.kind(),
Self::Cs(_) => spi::ErrorKind::Other,
Self::DelayUsNotSupported => spi::ErrorKind::Other,
Self::Config => spi::ErrorKind::Other,
}
}
}

View File

@ -59,7 +59,7 @@ rtos-trace = { version = "0.1.2", optional = true }
futures-util = { version = "0.3.17", default-features = false }
embassy-macros = { version = "0.2.1", path = "../embassy-macros" }
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true}
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true}
atomic-polyfill = "1.0.1"
critical-section = "1.1"
static_cell = "1.1"

View File

@ -4,7 +4,7 @@ An async/await executor designed for embedded usage.
- No `alloc`, no heap needed. Task futures are statically allocated.
- No "fixed capacity" data structures, executor works with 1 or 1000 tasks without needing config/tuning.
- Integrated timer queue: sleeping is easy, just do `Timer::after(Duration::from_secs(1)).await;`.
- Integrated timer queue: sleeping is easy, just do `Timer::after_secs(1).await;`.
- No busy-loop polling: CPU sleeps when there's no work to do, using interrupts or `WFE/SEV`.
- Efficient polling: a wake will only poll the woken task, not all of them.
- Fair: a task can't monopolize CPU time even if it's constantly being woken. All other tasks get a chance to run before a given task gets polled for the second time.

View File

@ -1,5 +1,3 @@
const THREAD_PENDER: usize = usize::MAX;
#[export_name = "__pender"]
#[cfg(any(feature = "executor-thread", feature = "executor-interrupt"))]
fn __pender(context: *mut ()) {
@ -48,13 +46,14 @@ fn __pender(context: *mut ()) {
pub use thread::*;
#[cfg(feature = "executor-thread")]
mod thread {
pub(super) const THREAD_PENDER: usize = usize::MAX;
use core::arch::asm;
use core::marker::PhantomData;
#[cfg(feature = "nightly")]
pub use embassy_macros::main_cortex_m as main;
use crate::arch::THREAD_PENDER;
use crate::{raw, Spawner};
/// Thread mode executor, using WFE/SEV.

View File

@ -73,9 +73,10 @@ mod thread {
pub fn start(&'static mut self, init: impl FnOnce(Spawner)) {
unsafe {
let executor = &self.inner;
self.ctx.closure.write(Closure::new(move |_| {
let future = Closure::new(move |_| {
executor.poll();
}));
});
self.ctx.closure.write_in_place(|| future);
init(self.inner.spawner());
}
}

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -203,7 +203,7 @@ impl<F: Future + 'static> AvailableTask<F> {
fn initialize_impl<S>(self, future: impl FnOnce() -> F) -> SpawnToken<S> {
unsafe {
self.task.raw.poll_fn.set(Some(TaskStorage::<F>::poll));
self.task.future.write(future());
self.task.future.write_in_place(future);
let task = TaskRef::new(self.task);

View File

@ -17,8 +17,9 @@ impl<T> UninitCell<T> {
&mut *self.as_mut_ptr()
}
pub unsafe fn write(&self, val: T) {
ptr::write(self.as_mut_ptr(), val)
#[inline(never)]
pub unsafe fn write_in_place(&self, func: impl FnOnce() -> T) {
ptr::write(self.as_mut_ptr(), func())
}
pub unsafe fn drop_in_place(&self) {

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -1,4 +1,4 @@
# embassy-macros
# embassy-hal-internal
An [Embassy](https://embassy.dev) project.

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -4,6 +4,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
use cortex_m::interrupt::InterruptNumber;
use cortex_m::peripheral::NVIC;
use critical_section::CriticalSection;
/// Generate a standard `mod interrupt` for a HAL.
#[macro_export]
@ -91,6 +92,12 @@ macro_rules! interrupt_mod {
fn set_priority(prio: crate::interrupt::Priority) {
Self::IRQ.set_priority(prio)
}
/// Set the interrupt priority with an already-acquired critical section
#[inline]
fn set_priority_with_cs(cs: critical_section::CriticalSection, prio: crate::interrupt::Priority) {
Self::IRQ.set_priority_with_cs(cs, prio)
}
}
$(
@ -195,10 +202,29 @@ pub unsafe trait InterruptExt: InterruptNumber + Copy {
/// Set the interrupt priority.
#[inline]
fn set_priority(self, prio: Priority) {
critical_section::with(|_| unsafe {
unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(self, prio.into())
})
// On thumbv6, set_priority must do a RMW to change 8bit in a 32bit reg.
#[cfg(armv6m)]
critical_section::with(|_| nvic.set_priority(self, prio.into()));
// On thumbv7+, set_priority does an atomic 8bit write, so no CS needed.
#[cfg(not(armv6m))]
nvic.set_priority(self, prio.into());
}
}
/// Set the interrupt priority with an already-acquired critical section
///
/// Equivalent to `set_priority`, except you pass a `CriticalSection` to prove
/// you've already acquired a critical section. This prevents acquiring another
/// one, which saves code size.
#[inline]
fn set_priority_with_cs(self, _cs: CriticalSection, prio: Priority) {
unsafe {
let mut nvic: cortex_m::peripheral::NVIC = mem::transmute(());
nvic.set_priority(self, prio.into());
}
}
}

View File

@ -10,7 +10,6 @@ pub mod drop;
mod macros;
mod peripheral;
pub mod ratio;
pub mod ring_buffer;
pub use peripheral::{Peripheral, PeripheralRef};
#[cfg(feature = "cortex-m")]

View File

@ -48,17 +48,23 @@ macro_rules! peripherals_struct {
///Returns all the peripherals *once*
#[inline]
pub(crate) fn take() -> Self {
critical_section::with(Self::take_with_cs)
}
///Returns all the peripherals *once*
#[inline]
pub(crate) fn take_with_cs(_cs: critical_section::CriticalSection) -> Self {
#[no_mangle]
static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
critical_section::with(|_| unsafe {
// safety: OK because we're inside a CS.
unsafe {
if _EMBASSY_DEVICE_PERIPHERALS {
panic!("init called more than once!")
}
_EMBASSY_DEVICE_PERIPHERALS = true;
Self::steal()
})
}
}
}

View File

@ -1,136 +0,0 @@
pub struct RingBuffer<'a> {
buf: &'a mut [u8],
start: usize,
end: usize,
empty: bool,
}
impl<'a> RingBuffer<'a> {
pub fn new(buf: &'a mut [u8]) -> Self {
Self {
buf,
start: 0,
end: 0,
empty: true,
}
}
pub fn push_buf(&mut self) -> &mut [u8] {
if self.start == self.end && !self.empty {
trace!(" ringbuf: push_buf empty");
return &mut self.buf[..0];
}
let n = if self.start <= self.end {
self.buf.len() - self.end
} else {
self.start - self.end
};
trace!(" ringbuf: push_buf {:?}..{:?}", self.end, self.end + n);
&mut self.buf[self.end..self.end + n]
}
pub fn push(&mut self, n: usize) {
trace!(" ringbuf: push {:?}", n);
if n == 0 {
return;
}
self.end = self.wrap(self.end + n);
self.empty = false;
}
pub fn pop_buf(&mut self) -> &mut [u8] {
if self.empty {
trace!(" ringbuf: pop_buf empty");
return &mut self.buf[..0];
}
let n = if self.end <= self.start {
self.buf.len() - self.start
} else {
self.end - self.start
};
trace!(" ringbuf: pop_buf {:?}..{:?}", self.start, self.start + n);
&mut self.buf[self.start..self.start + n]
}
pub fn pop(&mut self, n: usize) {
trace!(" ringbuf: pop {:?}", n);
if n == 0 {
return;
}
self.start = self.wrap(self.start + n);
self.empty = self.start == self.end;
}
pub fn is_full(&self) -> bool {
self.start == self.end && !self.empty
}
pub fn is_empty(&self) -> bool {
self.empty
}
pub fn clear(&mut self) {
self.start = 0;
self.end = 0;
self.empty = true;
}
fn wrap(&self, n: usize) -> usize {
assert!(n <= self.buf.len());
if n == self.buf.len() {
0
} else {
n
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn push_pop() {
let mut b = [0; 4];
let mut rb = RingBuffer::new(&mut b);
let buf = rb.push_buf();
assert_eq!(4, buf.len());
buf[0] = 1;
buf[1] = 2;
buf[2] = 3;
buf[3] = 4;
rb.push(4);
let buf = rb.pop_buf();
assert_eq!(4, buf.len());
assert_eq!(1, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(3, buf.len());
assert_eq!(2, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(2, buf.len());
assert_eq!(3, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(1, buf.len());
assert_eq!(4, buf[0]);
rb.pop(1);
let buf = rb.pop_buf();
assert_eq!(0, buf.len());
let buf = rb.push_buf();
assert_eq!(4, buf.len());
}
}

View File

@ -20,15 +20,12 @@ defmt = ["dep:defmt", "lorawan-device/defmt"]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-stm32 = { version = "0.1.0", path = "../embassy-stm32", default-features = false, optional = true }
embedded-hal-async = { version = "=1.0.0-rc.1" }
embedded-hal = { version = "0.2", features = ["unproven"] }
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
lora-phy = { version = "1" }
lorawan-device = { version = "0.10.0", default-features = false, features = ["async"], optional = true }
[patch.crates-io]
lora-phy = { git = "https://github.com/embassy-rs/lora-phy", rev = "1323eccc1c470d4259f95f4f315d1be830d572a3"}
lora-phy = { version = "2" }
lorawan-device = { version = "0.11.0", default-features = false, features = ["async"], optional = true }

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -67,24 +67,20 @@ where
self.board_type = board_type;
}
async fn set_nss_low(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR;
pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::LOW));
pac::PWR.subghzspicr().modify(|w| w.set_nss(false));
Ok(())
}
async fn set_nss_high(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR;
pwr.subghzspicr().modify(|w| w.set_nss(pac::pwr::vals::Nss::HIGH));
pac::PWR.subghzspicr().modify(|w| w.set_nss(true));
Ok(())
}
async fn reset(&mut self, _delay: &mut impl DelayUs) -> Result<(), RadioError> {
let rcc = pac::RCC;
rcc.csr().modify(|w| w.set_rfrst(true));
rcc.csr().modify(|w| w.set_rfrst(false));
pac::RCC.csr().modify(|w| w.set_rfrst(true));
pac::RCC.csr().modify(|w| w.set_rfrst(false));
Ok(())
}
async fn wait_on_busy(&mut self) -> Result<(), RadioError> {
let pwr = pac::PWR;
while pwr.sr2().read().rfbusys() == pac::pwr::vals::Rfbusys::BUSY {}
while pac::PWR.sr2().read().rfbusys() {}
Ok(())
}
@ -284,11 +280,7 @@ where
self.busy.wait_for_low().await.map_err(|_| Busy)
}
async fn await_irq(&mut self) -> Result<(), RadioError> {
if self.board_type != BoardType::RpPicoWaveshareSx1262 {
self.dio1.wait_for_high().await.map_err(|_| DIO1)?;
} else {
self.dio1.wait_for_rising_edge().await.map_err(|_| DIO1)?;
}
self.dio1.wait_for_high().await.map_err(|_| DIO1)?;
Ok(())
}

View File

@ -1,5 +1,5 @@
#![no_std]
#![feature(async_fn_in_trait, impl_trait_projections)]
#![feature(async_fn_in_trait)]
//! embassy-lora holds LoRa-specific functionality.
pub(crate) mod fmt;
@ -34,6 +34,6 @@ impl lorawan_device::async_device::radio::Timer for LoraTimer {
}
async fn delay_ms(&mut self, millis: u64) {
Timer::after(Duration::from_millis(millis)).await
Timer::after_millis(millis).await
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-net-adin1110"
version = "0.1.0"
version = "0.2.0"
description = "embassy-net driver for the ADIN1110 ethernet chip"
keywords = ["embedded", "ADIN1110", "embassy-net", "embedded-hal-async", "ethernet", "async"]
categories = ["embedded", "hardware-support", "no-std", "network-programming", "async"]
@ -12,30 +12,31 @@ edition = "2021"
[dependencies]
heapless = "0.7.16"
defmt = { version = "0.3", optional = true }
log = { version = "0.4.4", default-features = false, optional = true }
log = { version = "0.4", default-features = false, optional = true }
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" }
embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] }
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.0" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
bitfield = "0.14.0"
[dev-dependencies]
# reenable when https://github.com/dbrgn/embedded-hal-mock/pull/86 is merged.
#embedded-hal-mock = { git = "https://github.com/dbrgn/embedded-hal-mock", branch = "1-alpha", features = ["embedded-hal-async", "eh1"] }] }
embedded-hal-mock = { git = "https://github.com/newAM/embedded-hal-mock", branch = "eh1-rc.1", features = ["embedded-hal-async", "eh1"] }
crc = "3.0.1"
env_logger = "0.10"
critical-section = { version = "1.1.1", features = ["std"] }
futures-test = "0.3.17"
critical-section = { version = "1.1.2", features = ["std"] }
futures-test = "0.3.28"
[features]
default = [ ]
defmt = [ "dep:defmt" ]
defmt = [ "dep:defmt", "embedded-hal-1/defmt-03" ]
log = ["dep:log"]
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-adin1110-v$VERSION/embassy-net-adin1110/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-adin1110/src/"
target = "thumbv7em-none-eabi"
features = ["defmt"]

View File

@ -30,8 +30,8 @@ Currently only `Generic` SPI with or without CRC is supported.
## Hardware
- Tested on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html) with an `STM32L4S5QII3P`, see [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) dor an example.
- [`SparkFun MicroMod Single Pair Ethernet Function Board`](https://www.sparkfun.com/products/19038) or [`SparkFun MicroMod Single Pair Ethernet Kit`](https://www.sparkfun.com/products/19628), supporting multiple microcontrollers. **Make sure to check if it's a microcontroller that is supported by Embassy!**
- Tested on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html) with an `STM32L4S5QII3P`, see [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) for an example.
- [`SparkFun MicroMod Single Pair Ethernet Function Board`](https://www.sparkfun.com/products/19038) or [`SparkFun MicroMod Single Pair Ethernet Kit (End Of Life)`](https://www.sparkfun.com/products/19628), supporting multiple microcontrollers. **Make sure to check if it's a microcontroller that is supported by Embassy!**
## Other SPE chips
@ -44,6 +44,39 @@ ADIN1110 library can tested on the host with a mock SPI driver.
$ `cargo test --target x86_64-unknown-linux-gnu`
## Benchmark
- Benchmarked on [`Analog Devices EVAL-ADIN1110EBZ`](https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/eval-adin1110.html), with [`spe_adin1110_http_server`](../examples/stm32l4/src/bin/spe_adin1110_http_server.rs) example.
Basic `ping` benchmark
```rust,ignore
# ping <IP> -c 60
60 packets transmitted, 60 received, 0% packet loss, time 59066ms
rtt min/avg/max/mdev = 1.089/1.161/1.237/0.018 ms
# ping <IP> -s 1472 -M do -c 60
60 packets transmitted, 60 received, 0% packet loss, time 59066ms
rtt min/avg/max/mdev = 5.122/5.162/6.177/0.133 ms
```
HTTP load generator benchmark with [`oha`](https://github.com/hatoo/oha)
```rust,ignore
# oha -c 1 http://<IP> -z 60s
Summary:
Success rate: 50.00%
Total: 60.0005 secs
Slowest: 0.0055 secs
Fastest: 0.0033 secs
Average: 0.0034 secs
Requests/sec: 362.1971
Total data: 2.99 MiB
Size/request: 289 B
Size/sec: 51.11 KiB
```
## License
This work is licensed under either of

View File

@ -257,29 +257,30 @@ pub const CRC32R_LOOKUP_TABLE: [u32; 256] = [
0x2D02_EF8D,
];
/// Generate Ethernet Frame Check Sequence
#[allow(non_camel_case_types)]
#[derive(Debug)]
pub struct ETH_FSC(pub u32);
pub struct ETH_FCS(pub u32);
impl ETH_FSC {
impl ETH_FCS {
pub const CRC32_OK: u32 = 0x2144_df1c;
#[must_use]
pub fn new(data: &[u8]) -> Self {
let fsc = data.iter().fold(u32::MAX, |crc, byte| {
let fcs = data.iter().fold(u32::MAX, |crc, byte| {
let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
}) ^ u32::MAX;
Self(fsc)
Self(fcs)
}
#[must_use]
pub fn update(self, data: &[u8]) -> Self {
let fsc = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
let fcs = data.iter().fold(self.0 ^ u32::MAX, |crc, byte| {
let idx = u8::try_from(crc & 0xFF).unwrap() ^ byte;
CRC32R_LOOKUP_TABLE[usize::from(idx)] ^ (crc >> 8)
}) ^ u32::MAX;
Self(fsc)
Self(fcs)
}
#[must_use]
@ -319,24 +320,24 @@ mod tests {
];
// Packet A
let own_crc = ETH_FSC::new(&packet_a[0..60]);
let own_crc = ETH_FCS::new(&packet_a[0..60]);
let crc_bytes = own_crc.hton_bytes();
println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
assert_eq!(&crc_bytes, &packet_a[60..64]);
let own_crc = ETH_FSC::new(packet_a);
let own_crc = ETH_FCS::new(packet_a);
println!("{:08x}", own_crc.0);
assert_eq!(own_crc.0, ETH_FSC::CRC32_OK);
assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
// Packet B
let own_crc = ETH_FSC::new(&packet_b[0..60]);
let own_crc = ETH_FCS::new(&packet_b[0..60]);
let crc_bytes = own_crc.hton_bytes();
println!("{:08x} {:02x?}", own_crc.0, crc_bytes);
assert_eq!(&crc_bytes, &packet_b[60..64]);
let own_crc = ETH_FSC::new(packet_b);
let own_crc = ETH_FCS::new(packet_b);
println!("{:08x}", own_crc.0);
assert_eq!(own_crc.0, ETH_FSC::CRC32_OK);
assert_eq!(own_crc.0, ETH_FCS::CRC32_OK);
}
#[test]
@ -349,9 +350,9 @@ mod tests {
];
let (part_a, part_b) = full_data.split_at(16);
let crc_partially = ETH_FSC::new(part_a).update(part_b);
let crc_partially = ETH_FCS::new(part_a).update(part_b);
let crc_full = ETH_FSC::new(full_data);
let crc_full = ETH_FCS::new(full_data);
assert_eq!(crc_full.0, crc_partially.0);
}

View File

@ -0,0 +1,254 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
macro_rules! assert {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert!($($x)*);
}
};
}
macro_rules! assert_eq {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert_eq!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert_eq!($($x)*);
}
};
}
macro_rules! assert_ne {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::assert_ne!($($x)*);
#[cfg(feature = "defmt")]
::defmt::assert_ne!($($x)*);
}
};
}
macro_rules! debug_assert {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert!($($x)*);
}
};
}
macro_rules! debug_assert_eq {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert_eq!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert_eq!($($x)*);
}
};
}
macro_rules! debug_assert_ne {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::debug_assert_ne!($($x)*);
#[cfg(feature = "defmt")]
::defmt::debug_assert_ne!($($x)*);
}
};
}
macro_rules! todo {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::todo!($($x)*);
#[cfg(feature = "defmt")]
::defmt::todo!($($x)*);
}
};
}
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
};
}
macro_rules! panic {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::panic!($($x)*);
#[cfg(feature = "defmt")]
::defmt::panic!($($x)*);
}
};
}
macro_rules! trace {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::trace!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::trace!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ignored = ($( & $x ),*);
}
};
}
macro_rules! debug {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::debug!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::debug!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ignored = ($( & $x ),*);
}
};
}
macro_rules! info {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::info!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::info!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ignored = ($( & $x ),*);
}
};
}
macro_rules! warn {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::warn!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::warn!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ignored = ($( & $x ),*);
}
};
}
macro_rules! error {
($s:literal $(, $x:expr)* $(,)?) => {
{
#[cfg(feature = "log")]
::log::error!($s $(, $x)*);
#[cfg(feature = "defmt")]
::defmt::error!($s $(, $x)*);
#[cfg(not(any(feature = "log", feature="defmt")))]
let _ignored = ($( & $x ),*);
}
};
}
#[cfg(feature = "defmt")]
macro_rules! unwrap {
($($x:tt)*) => {
::defmt::unwrap!($($x)*)
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unwrap {
($arg:expr) => {
match $crate::fmt::Try::into_result($arg) {
::core::result::Result::Ok(t) => t,
::core::result::Result::Err(e) => {
::core::panic!("unwrap of `{}` failed: {:?}", ::core::stringify!($arg), e);
}
}
};
($arg:expr, $($msg:expr),+ $(,)? ) => {
match $crate::fmt::Try::into_result($arg) {
::core::result::Result::Ok(t) => t,
::core::result::Result::Err(e) => {
::core::panic!("unwrap of `{}` failed: {}: {:?}", ::core::stringify!($arg), ::core::format_args!($($msg,)*), e);
}
}
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct NoneError;
pub trait Try {
type Ok;
type Error;
fn into_result(self) -> Result<Self::Ok, Self::Error>;
}
impl<T> Try for Option<T> {
type Ok = T;
type Error = NoneError;
#[inline]
fn into_result(self) -> Result<T, NoneError> {
self.ok_or(NoneError)
}
}
impl<T, E> Try for Result<T, E> {
type Ok = T;
type Error = E;
#[inline]
fn into_result(self) -> Self {
self
}
}
pub struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -32,11 +32,12 @@ enum Reg13Op {
PostReadIncAddr = 0b10 << 14,
Read = 0b11 << 14,
}
/// `MdioBus` trait
/// Driver needs to implement the Clause 22
/// Optional Clause 45 is the device supports this.
///
/// Claus 45 methodes are bases on <https://www.ieee802.org/3/efm/public/nov02/oam/pannell_oam_1_1102.pdf>
/// Clause 45 methodes are bases on <https://www.ieee802.org/3/efm/public/nov02/oam/pannell_oam_1_1102.pdf>
pub trait MdioBus {
type Error;
@ -87,89 +88,89 @@ pub trait MdioBus {
}
}
// #[cfg(test)]
// mod tests {
// use core::convert::Infallible;
#[cfg(test)]
mod tests {
use core::convert::Infallible;
// use super::{MdioBus, PhyAddr, RegC22, RegVal};
use super::{MdioBus, PhyAddr, RegC22, RegVal};
// #[derive(Debug, PartialEq, Eq)]
// enum A {
// Read(PhyAddr, RegC22),
// Write(PhyAddr, RegC22, RegVal),
// }
#[derive(Debug, PartialEq, Eq)]
enum A {
Read(PhyAddr, RegC22),
Write(PhyAddr, RegC22, RegVal),
}
// struct MockMdioBus(Vec<A>);
struct MockMdioBus(Vec<A>);
// impl MockMdioBus {
// pub fn clear(&mut self) {
// self.0.clear();
// }
// }
impl MockMdioBus {
pub fn clear(&mut self) {
self.0.clear();
}
}
// impl MdioBus for MockMdioBus {
// type Error = Infallible;
impl MdioBus for MockMdioBus {
type Error = Infallible;
// fn write_cl22(
// &mut self,
// phy_id: super::PhyAddr,
// reg: super::RegC22,
// reg_val: super::RegVal,
// ) -> Result<(), Self::Error> {
// self.0.push(A::Write(phy_id, reg, reg_val));
// Ok(())
// }
async fn write_cl22(
&mut self,
phy_id: super::PhyAddr,
reg: super::RegC22,
reg_val: super::RegVal,
) -> Result<(), Self::Error> {
self.0.push(A::Write(phy_id, reg, reg_val));
Ok(())
}
// fn read_cl22(
// &mut self,
// phy_id: super::PhyAddr,
// reg: super::RegC22,
// ) -> Result<super::RegVal, Self::Error> {
// self.0.push(A::Read(phy_id, reg));
// Ok(0)
// }
// }
async fn read_cl22(
&mut self,
phy_id: super::PhyAddr,
reg: super::RegC22,
) -> Result<super::RegVal, Self::Error> {
self.0.push(A::Read(phy_id, reg));
Ok(0)
}
}
// #[test]
// fn read_test() {
// let mut mdiobus = MockMdioBus(Vec::with_capacity(20));
#[futures_test::test]
async fn read_test() {
let mut mdiobus = MockMdioBus(Vec::with_capacity(20));
// mdiobus.clear();
// mdiobus.read_cl22(0x01, 0x00).unwrap();
// assert_eq!(mdiobus.0, vec![A::Read(0x01, 0x00)]);
mdiobus.clear();
mdiobus.read_cl22(0x01, 0x00).await.unwrap();
assert_eq!(mdiobus.0, vec![A::Read(0x01, 0x00)]);
// mdiobus.clear();
// mdiobus.read_cl45(0x01, (0xBB, 0x1234)).unwrap();
// assert_eq!(
// mdiobus.0,
// vec![
// #[allow(clippy::identity_op)]
// A::Write(0x01, 13, (0b00 << 14) | 27),
// A::Write(0x01, 14, 0x1234),
// A::Write(0x01, 13, (0b11 << 14) | 27),
// A::Read(0x01, 14)
// ]
// );
// }
mdiobus.clear();
mdiobus.read_cl45(0x01, (0xBB, 0x1234)).await.unwrap();
assert_eq!(
mdiobus.0,
vec![
#[allow(clippy::identity_op)]
A::Write(0x01, 13, (0b00 << 14) | 27),
A::Write(0x01, 14, 0x1234),
A::Write(0x01, 13, (0b11 << 14) | 27),
A::Read(0x01, 14)
]
);
}
// #[test]
// fn write_test() {
// let mut mdiobus = MockMdioBus(Vec::with_capacity(20));
#[futures_test::test]
async fn write_test() {
let mut mdiobus = MockMdioBus(Vec::with_capacity(20));
// mdiobus.clear();
// mdiobus.write_cl22(0x01, 0x00, 0xABCD).unwrap();
// assert_eq!(mdiobus.0, vec![A::Write(0x01, 0x00, 0xABCD)]);
mdiobus.clear();
mdiobus.write_cl22(0x01, 0x00, 0xABCD).await.unwrap();
assert_eq!(mdiobus.0, vec![A::Write(0x01, 0x00, 0xABCD)]);
// mdiobus.clear();
// mdiobus.write_cl45(0x01, (0xBB, 0x1234), 0xABCD).unwrap();
// assert_eq!(
// mdiobus.0,
// vec![
// A::Write(0x01, 13, 27),
// A::Write(0x01, 14, 0x1234),
// A::Write(0x01, 13, (0b01 << 14) | 27),
// A::Write(0x01, 14, 0xABCD)
// ]
// );
// }
// }
mdiobus.clear();
mdiobus.write_cl45(0x01, (0xBB, 0x1234), 0xABCD).await.unwrap();
assert_eq!(
mdiobus.0,
vec![
A::Write(0x01, 13, 27),
A::Write(0x01, 14, 0x1234),
A::Write(0x01, 13, (0b01 << 14) | 27),
A::Write(0x01, 14, 0xABCD)
]
);
}
}

View File

@ -111,6 +111,7 @@ pub mod RegsC45 {
}
}
/// 10-BASE-T1x PHY functions.
pub struct Phy10BaseT1x(u8);
impl Default for Phy10BaseT1x {

View File

@ -1,3 +1,5 @@
use core::fmt::{Debug, Display};
use bitfield::{bitfield, bitfield_bitrange, bitfield_fields};
#[allow(non_camel_case_types)]
@ -34,6 +36,12 @@ pub enum SpiRegisters {
RX = 0x91,
}
impl Display for SpiRegisters {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{self:?}")
}
}
impl From<SpiRegisters> for u16 {
fn from(val: SpiRegisters) -> Self {
val as u16
@ -68,7 +76,7 @@ impl From<u16> for SpiRegisters {
0x73 => Self::ADDR_MSK_UPR1,
0x90 => Self::RX_FSIZE,
0x91 => Self::RX,
e => panic!("Unknown value {e}"),
e => panic!("Unknown value {}", e),
}
}
}
@ -174,7 +182,7 @@ bitfield! {
pub sdf_detect_src, set_sdf_detect_src : 7;
/// Statistics Clear on Reading
pub stats_clr_on_rd, set_stats_clr_on_rd : 6;
/// Enable CRC Append
/// Enable SPI CRC
pub crc_append, set_crc_append : 5;
/// Admit Frames with IFG Errors on Port 1 (P1)
pub p1_rcv_ifg_err_frm, set_p1_rcv_ifg_err_frm : 4;
@ -313,7 +321,7 @@ impl From<u8> for LedFunc {
26 => LedFunc::Clk25Ref,
27 => LedFunc::TxTCLK,
28 => LedFunc::Clk120MHz,
e => panic!("Invalid value {e}"),
e => panic!("Invalid value {}", e),
}
}
}
@ -369,7 +377,7 @@ impl From<u8> for LedPol {
0 => LedPol::AutoSense,
1 => LedPol::ActiveHigh,
2 => LedPol::ActiveLow,
e => panic!("Invalid value {e}"),
e => panic!("Invalid value {}", e),
}
}
}

View File

@ -0,0 +1,16 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-18
- Update `embassy-net-driver` to v0.2
- `Runner::new` now takes an `embassy_net_driver::HardwareAddress` parameter.
- `Runner::set_ethernet_address` is now `set_hardware_address`.
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-net-driver-channel"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "High-level channel-based driver for the `embassy-net` async TCP/IP network stack."
@ -24,6 +24,6 @@ features = ["defmt"]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }

View File

@ -7,7 +7,9 @@ The `embassy-net-driver` trait is polling-based. To implement it, you must write
hand, and hook up the `Waker`s provided by `embassy-net` to the right interrupt handlers so that `embassy-net`
knows when to poll your driver again to make more progress.
With `embassy-net-driver-channel`
With `embassy-net-driver-channel` you get a "channel-like" interface instead, where you can send/receive packets
to/from embassy-net. The intended usage is to spawn a "driver task" in the background that does this, passing
packets between the hardware and the channel.
## A note about deadlocks
@ -18,19 +20,19 @@ loop {
// Wait for either..
match select(
// ... the chip signaling an interrupt, indicating a packet is available to receive, or
irq_pin.wait_for_low(),
irq_pin.wait_for_low(),
// ... a TX buffer becoming available, i.e. embassy-net wants to send a packet
tx_chan.tx_buf(),
).await {
Either::First(_) => {
// a packet is ready to be received!
let buf = rx_chan.rx_buf().await; // allocate a rx buf from the packet queue
let n = receive_packet_over_spi(buf).await;
let n = receive_packet_over_spi(buf).await;
rx_chan.rx_done(n);
}
Either::Second(buf) => {
// a packet is ready to be sent!
send_packet_over_spi(buf).await;
send_packet_over_spi(buf).await;
tx_chan.tx_done();
}
}
@ -41,7 +43,7 @@ However, this code has a latent deadlock bug. The symptom is it can hang at `rx_
The reason is that, under load, both the TX and RX queues can get full at the same time. When this happens, the `embassy-net` task stalls trying to send because the TX queue is full, therefore it stops processing packets in the RX queue. Your driver task also stalls because the RX queue is full, therefore it stops processing packets in the TX queue.
The fix is to make sure to always service the TX queue while you're waiting for space to become available in the TX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available":
The fix is to make sure to always service the TX queue while you're waiting for space to become available in the RX queue. For example, select on either "tx_chan.tx_buf() available" or "INT is low AND rx_chan.rx_buf() available":
```rust,ignore
loop {
@ -58,12 +60,12 @@ loop {
).await {
Either::First(buf) => {
// a packet is ready to be received!
let n = receive_packet_over_spi(buf).await;
let n = receive_packet_over_spi(buf).await;
rx_chan.rx_done(n);
}
Either::Second(buf) => {
// a packet is ready to be sent!
send_packet_over_spi(buf).await;
send_packet_over_spi(buf).await;
tx_chan.tx_done();
}
}
@ -79,12 +81,10 @@ These `embassy-net` drivers are implemented using this crate. You can look at th
- [`embassy-net-wiznet`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-wiznet) for Wiznet SPI Ethernet MAC+PHY chips.
- [`embassy-net-esp-hosted`](https://github.com/embassy-rs/embassy/tree/main/embassy-net-esp-hosted) for using ESP32 chips with the [`esp-hosted`](https://github.com/espressif/esp-hosted) firmware as WiFi adapters for another non-ESP32 MCU.
## Interoperability
This crate can run on any executor.
## License
This work is licensed under either of

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -8,12 +8,12 @@ use core::cell::RefCell;
use core::mem::MaybeUninit;
use core::task::{Context, Poll};
use driver::HardwareAddress;
pub use embassy_net_driver as driver;
use embassy_net_driver::{Capabilities, LinkState, Medium};
use embassy_net_driver::{Capabilities, LinkState};
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
use embassy_sync::blocking_mutex::Mutex;
use embassy_sync::waitqueue::WakerRegistration;
use embassy_sync::zerocopy_channel;
pub struct State<const MTU: usize, const N_RX: usize, const N_TX: usize> {
rx: [PacketBuf<MTU>; N_RX],
@ -130,24 +130,24 @@ impl<'d, const MTU: usize> Runner<'d, MTU> {
}
pub async fn tx_buf(&mut self) -> &mut [u8] {
let p = self.tx_chan.recv().await;
let p = self.tx_chan.receive().await;
&mut p.buf[..p.len]
}
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
let p = self.tx_chan.try_recv()?;
let p = self.tx_chan.try_receive()?;
Some(&mut p.buf[..p.len])
}
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
match self.tx_chan.poll_recv(cx) {
match self.tx_chan.poll_receive(cx) {
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
Poll::Pending => Poll::Pending,
}
}
pub fn tx_done(&mut self) {
self.tx_chan.recv_done();
self.tx_chan.receive_done();
}
}
@ -160,18 +160,10 @@ impl<'d> StateRunner<'d> {
});
}
pub fn set_ethernet_address(&self, address: [u8; 6]) {
pub fn set_hardware_address(&self, address: driver::HardwareAddress) {
self.shared.lock(|s| {
let s = &mut *s.borrow_mut();
s.hardware_address = driver::HardwareAddress::Ethernet(address);
s.waker.wake();
});
}
pub fn set_ieee802154_address(&self, address: [u8; 8]) {
self.shared.lock(|s| {
let s = &mut *s.borrow_mut();
s.hardware_address = driver::HardwareAddress::Ieee802154(address);
s.hardware_address = address;
s.waker.wake();
});
}
@ -204,24 +196,24 @@ impl<'d, const MTU: usize> RxRunner<'d, MTU> {
impl<'d, const MTU: usize> TxRunner<'d, MTU> {
pub async fn tx_buf(&mut self) -> &mut [u8] {
let p = self.tx_chan.recv().await;
let p = self.tx_chan.receive().await;
&mut p.buf[..p.len]
}
pub fn try_tx_buf(&mut self) -> Option<&mut [u8]> {
let p = self.tx_chan.try_recv()?;
let p = self.tx_chan.try_receive()?;
Some(&mut p.buf[..p.len])
}
pub fn poll_tx_buf(&mut self, cx: &mut Context) -> Poll<&mut [u8]> {
match self.tx_chan.poll_recv(cx) {
match self.tx_chan.poll_receive(cx) {
Poll::Ready(p) => Poll::Ready(&mut p.buf[..p.len]),
Poll::Pending => Poll::Pending,
}
}
pub fn tx_done(&mut self) {
self.tx_chan.recv_done();
self.tx_chan.receive_done();
}
}
@ -231,11 +223,6 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>(
) -> (Runner<'d, MTU>, Device<'d, MTU>) {
let mut caps = Capabilities::default();
caps.max_transmission_unit = MTU;
caps.medium = match &hardware_address {
HardwareAddress::Ethernet(_) => Medium::Ethernet,
HardwareAddress::Ieee802154(_) => Medium::Ieee802154,
HardwareAddress::Ip => Medium::Ip,
};
// safety: this is a self-referential struct, however:
// - it can't move while the `'d` borrow is active.
@ -293,7 +280,7 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> {
type TxToken<'a> = TxToken<'a, MTU> where Self: 'a ;
fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
if self.rx.poll_recv(cx).is_ready() && self.tx.poll_send(cx).is_ready() {
if self.rx.poll_receive(cx).is_ready() && self.tx.poll_send(cx).is_ready() {
Some((RxToken { rx: self.rx.borrow() }, TxToken { tx: self.tx.borrow() }))
} else {
None
@ -337,9 +324,9 @@ impl<'a, const MTU: usize> embassy_net_driver::RxToken for RxToken<'a, MTU> {
F: FnOnce(&mut [u8]) -> R,
{
// NOTE(unwrap): we checked the queue wasn't full when creating the token.
let pkt = unwrap!(self.rx.try_recv());
let pkt = unwrap!(self.rx.try_receive());
let r = f(&mut pkt.buf[..pkt.len]);
self.rx.recv_done();
self.rx.receive_done();
r
}
}
@ -361,215 +348,3 @@ impl<'a, const MTU: usize> embassy_net_driver::TxToken for TxToken<'a, MTU> {
r
}
}
mod zerocopy_channel {
use core::cell::RefCell;
use core::future::poll_fn;
use core::marker::PhantomData;
use core::task::{Context, Poll};
use embassy_sync::blocking_mutex::raw::RawMutex;
use embassy_sync::blocking_mutex::Mutex;
use embassy_sync::waitqueue::WakerRegistration;
pub struct Channel<'a, M: RawMutex, T> {
buf: *mut T,
phantom: PhantomData<&'a mut T>,
state: Mutex<M, RefCell<State>>,
}
impl<'a, M: RawMutex, T> Channel<'a, M, T> {
pub fn new(buf: &'a mut [T]) -> Self {
let len = buf.len();
assert!(len != 0);
Self {
buf: buf.as_mut_ptr(),
phantom: PhantomData,
state: Mutex::new(RefCell::new(State {
len,
front: 0,
back: 0,
full: false,
send_waker: WakerRegistration::new(),
recv_waker: WakerRegistration::new(),
})),
}
}
pub fn split(&mut self) -> (Sender<'_, M, T>, Receiver<'_, M, T>) {
(Sender { channel: self }, Receiver { channel: self })
}
}
pub struct Sender<'a, M: RawMutex, T> {
channel: &'a Channel<'a, M, T>,
}
impl<'a, M: RawMutex, T> Sender<'a, M, T> {
pub fn borrow(&mut self) -> Sender<'_, M, T> {
Sender { channel: self.channel }
}
pub fn try_send(&mut self) -> Option<&mut T> {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.push_index() {
Some(i) => Some(unsafe { &mut *self.channel.buf.add(i) }),
None => None,
}
})
}
pub fn poll_send(&mut self, cx: &mut Context) -> Poll<&mut T> {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.push_index() {
Some(i) => Poll::Ready(unsafe { &mut *self.channel.buf.add(i) }),
None => {
s.recv_waker.register(cx.waker());
Poll::Pending
}
}
})
}
pub async fn send(&mut self) -> &mut T {
let i = poll_fn(|cx| {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.push_index() {
Some(i) => Poll::Ready(i),
None => {
s.recv_waker.register(cx.waker());
Poll::Pending
}
}
})
})
.await;
unsafe { &mut *self.channel.buf.add(i) }
}
pub fn send_done(&mut self) {
self.channel.state.lock(|s| s.borrow_mut().push_done())
}
}
pub struct Receiver<'a, M: RawMutex, T> {
channel: &'a Channel<'a, M, T>,
}
impl<'a, M: RawMutex, T> Receiver<'a, M, T> {
pub fn borrow(&mut self) -> Receiver<'_, M, T> {
Receiver { channel: self.channel }
}
pub fn try_recv(&mut self) -> Option<&mut T> {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.pop_index() {
Some(i) => Some(unsafe { &mut *self.channel.buf.add(i) }),
None => None,
}
})
}
pub fn poll_recv(&mut self, cx: &mut Context) -> Poll<&mut T> {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.pop_index() {
Some(i) => Poll::Ready(unsafe { &mut *self.channel.buf.add(i) }),
None => {
s.send_waker.register(cx.waker());
Poll::Pending
}
}
})
}
pub async fn recv(&mut self) -> &mut T {
let i = poll_fn(|cx| {
self.channel.state.lock(|s| {
let s = &mut *s.borrow_mut();
match s.pop_index() {
Some(i) => Poll::Ready(i),
None => {
s.send_waker.register(cx.waker());
Poll::Pending
}
}
})
})
.await;
unsafe { &mut *self.channel.buf.add(i) }
}
pub fn recv_done(&mut self) {
self.channel.state.lock(|s| s.borrow_mut().pop_done())
}
}
struct State {
len: usize,
/// Front index. Always 0..=(N-1)
front: usize,
/// Back index. Always 0..=(N-1).
back: usize,
/// Used to distinguish "empty" and "full" cases when `front == back`.
/// May only be `true` if `front == back`, always `false` otherwise.
full: bool,
send_waker: WakerRegistration,
recv_waker: WakerRegistration,
}
impl State {
fn increment(&self, i: usize) -> usize {
if i + 1 == self.len {
0
} else {
i + 1
}
}
fn is_full(&self) -> bool {
self.full
}
fn is_empty(&self) -> bool {
self.front == self.back && !self.full
}
fn push_index(&mut self) -> Option<usize> {
match self.is_full() {
true => None,
false => Some(self.back),
}
}
fn push_done(&mut self) {
assert!(!self.is_full());
self.back = self.increment(self.back);
if self.back == self.front {
self.full = true;
}
self.send_waker.wake();
}
fn pop_index(&mut self) -> Option<usize> {
match self.is_empty() {
true => None,
false => Some(self.front),
}
}
fn pop_done(&mut self) {
assert!(!self.is_empty());
self.front = self.increment(self.front);
self.full = false;
self.recv_waker.wake();
}
}
}

View File

@ -0,0 +1,17 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-18
- Added support for IEEE 802.15.4 mediums.
- Added `Driver::hardware_address()`, `HardwareAddress`.
- Removed `Medium` enum. The medium is deduced out of the hardware address.
- Removed `Driver::ethernet_address()`. Replacement is `hardware_address()`.
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-net-driver"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "Driver trait for the `embassy-net` async TCP/IP network stack."

View File

@ -7,12 +7,23 @@ use core::task::Context;
/// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub enum HardwareAddress {
/// A six-octet Ethernet address
/// Ethernet medium, with a A six-octet Ethernet address.
///
/// Devices of this type send and receive Ethernet frames,
/// and interfaces using it must do neighbor discovery via ARP or NDISC.
///
/// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode.
Ethernet([u8; 6]),
/// An eight-octet IEEE802.15.4 address
/// 6LoWPAN over IEEE802.15.4, with an eight-octet address.
Ieee802154([u8; 8]),
/// Indicates that a Driver is IP-native, and has no hardware address
/// Indicates that a Driver is IP-native, and has no hardware address.
///
/// Devices of this type send and receive IP frames, without an
/// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done.
///
/// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode.
Ip,
}
@ -64,6 +75,10 @@ pub trait Driver {
fn capabilities(&self) -> Capabilities;
/// Get the device's hardware address.
///
/// The returned hardware address also determines the "medium" of this driver. This indicates
/// what kind of packet the sent/received bytes are, and determines some behaviors of
/// the interface. For example, ARP/NDISC address resolution is only done for Ethernet mediums.
fn hardware_address(&self) -> HardwareAddress;
}
@ -124,13 +139,6 @@ pub trait TxToken {
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[non_exhaustive]
pub struct Capabilities {
/// Medium of the device.
///
/// This indicates what kind of packet the sent/received bytes are, and determines
/// some behaviors of Interface. For example, ARP/NDISC address resolution is only done
/// for Ethernet mediums.
pub medium: Medium,
/// Maximum transmission unit.
///
/// The network device is unable to send or receive frames larger than the value returned
@ -161,32 +169,6 @@ pub struct Capabilities {
pub checksum: ChecksumCapabilities,
}
/// Type of medium of a device.
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Medium {
/// Ethernet medium. Devices of this type send and receive Ethernet frames,
/// and interfaces using it must do neighbor discovery via ARP or NDISC.
///
/// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode.
Ethernet,
/// IP medium. Devices of this type send and receive IP frames, without an
/// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done.
///
/// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode.
Ip,
/// IEEE 802_15_4 medium
Ieee802154,
}
impl Default for Medium {
fn default() -> Medium {
Medium::Ethernet
}
}
/// A description of checksum behavior for every supported protocol.
#[derive(Debug, Clone, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]

View File

@ -10,8 +10,8 @@ edition = "2021"
[dependencies]
embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" }
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.2", path = "../embassy-time" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
defmt = { version = "0.3", optional = true }
@ -20,4 +20,4 @@ log = { version = "0.4.14", optional = true }
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-enc28j60-v$VERSION/embassy-net-enc28j60/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-enc28j60/src/"
target = "thumbv7em-none-eabi"
target = "thumbv7em-none-eabi"

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -19,7 +19,7 @@ mod traits;
use core::cmp;
use core::convert::TryInto;
use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium};
use embassy_net_driver::{Capabilities, HardwareAddress, LinkState};
use embassy_time::Duration;
use embedded_hal::digital::OutputPin;
use embedded_hal::spi::{Operation, SpiDevice};
@ -194,10 +194,15 @@ where
self.bit_field_set(common::Register::ECON1, common::ECON1::mask().rxen());
}
/// Returns the device's MAC address
pub fn address(&self) -> [u8; 6] {
self.mac_addr
}
/// Flushes the transmit buffer, ensuring all pending transmissions have completed
/// NOTE: The returned packet *must* be `read` or `ignore`-d, otherwise this method will always
/// return `None` on subsequent invocations
pub fn receive<'a>(&mut self, buf: &'a mut [u8]) -> Option<&'a mut [u8]> {
pub fn receive(&mut self, buf: &mut [u8]) -> Option<usize> {
if self.pending_packets() == 0 {
// Errata #6: we can't rely on PKTIF so we check PKTCNT
return None;
@ -241,7 +246,7 @@ where
self.next_packet = next_packet;
Some(&mut buf[..len as usize])
Some(len as usize)
}
fn wait_tx_ready(&mut self) {
@ -642,9 +647,8 @@ where
fn receive(&mut self, cx: &mut core::task::Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
let rx_buf = unsafe { &mut RX_BUF };
let tx_buf = unsafe { &mut TX_BUF };
if let Some(pkt) = self.receive(rx_buf) {
let n = pkt.len();
Some((RxToken { buf: &mut pkt[..n] }, TxToken { buf: tx_buf, eth: self }))
if let Some(n) = self.receive(rx_buf) {
Some((RxToken { buf: &mut rx_buf[..n] }, TxToken { buf: tx_buf, eth: self }))
} else {
cx.waker().wake_by_ref();
None
@ -667,7 +671,6 @@ where
fn capabilities(&self) -> Capabilities {
let mut caps = Capabilities::default();
caps.max_transmission_unit = MTU;
caps.medium = Medium::Ethernet;
caps
}

View File

@ -7,10 +7,10 @@ edition = "2021"
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embassy-time = { version = "0.1.2", path = "../embassy-time" }
embassy-sync = { version = "0.2.0", path = "../embassy-sync"}
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync"}
embassy-futures = { version = "0.1.0", path = "../embassy-futures"}
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"}
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel"}
embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" }
@ -23,4 +23,4 @@ heapless = "0.7.16"
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-esp-hosted-v$VERSION/embassy-net-esp-hosted/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-esp-hosted/src/"
target = "thumbv7em-none-eabi"
features = ["defmt"]
features = ["defmt"]

View File

@ -1,5 +1,5 @@
use ch::driver::LinkState;
use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::{HardwareAddress, LinkState};
use heapless::String;
use crate::ioctl::Shared;
@ -19,6 +19,8 @@ pub struct Control<'a> {
}
#[allow(unused)]
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
enum WifiMode {
None = 0,
Sta = 1,
@ -26,6 +28,18 @@ enum WifiMode {
ApSta = 3,
}
pub use proto::CtrlWifiSecProt as Security;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Status {
pub ssid: String<32>,
pub bssid: [u8; 6],
pub rssi: i32,
pub channel: u32,
pub security: Security,
}
macro_rules! ioctl {
($self:ident, $req_variant:ident, $resp_variant:ident, $req:ident, $resp:ident) => {
let mut msg = proto::CtrlMsg {
@ -34,7 +48,9 @@ macro_rules! ioctl {
payload: Some(proto::CtrlMsgPayload::$req_variant($req)),
};
$self.ioctl(&mut msg).await?;
let Some(proto::CtrlMsgPayload::$resp_variant($resp)) = msg.payload else {
#[allow(unused_mut)]
let Some(proto::CtrlMsgPayload::$resp_variant(mut $resp)) = msg.payload
else {
warn!("unexpected response variant");
return Err(Error::Internal);
};
@ -61,11 +77,24 @@ impl<'a> Control<'a> {
let mac_addr = self.get_mac_addr().await?;
debug!("mac addr: {:02x}", mac_addr);
self.state_ch.set_ethernet_address(mac_addr);
self.state_ch.set_hardware_address(HardwareAddress::Ethernet(mac_addr));
Ok(())
}
pub async fn get_status(&mut self) -> Result<Status, Error> {
let req = proto::CtrlMsgReqGetApConfig {};
ioctl!(self, ReqGetApConfig, RespGetApConfig, req, resp);
trim_nulls(&mut resp.ssid);
Ok(Status {
ssid: resp.ssid,
bssid: parse_mac(&resp.bssid)?,
rssi: resp.rssi as _,
channel: resp.chnl,
security: resp.sec_prot,
})
}
pub async fn connect(&mut self, ssid: &str, password: &str) -> Result<(), Error> {
let req = proto::CtrlMsgReqConnectAp {
ssid: String::from(ssid),
@ -98,27 +127,7 @@ impl<'a> Control<'a> {
mode: WifiMode::Sta as _,
};
ioctl!(self, ReqGetMacAddress, RespGetMacAddress, req, resp);
// WHY IS THIS A STRING? WHYYYY
fn nibble_from_hex(b: u8) -> u8 {
match b {
b'0'..=b'9' => b - b'0',
b'a'..=b'f' => b + 0xa - b'a',
b'A'..=b'F' => b + 0xa - b'A',
_ => panic!("invalid hex digit {}", b),
}
}
let mac = resp.mac.as_bytes();
let mut res = [0; 6];
if mac.len() != 17 {
warn!("unexpected MAC respnse length");
return Err(Error::Internal);
}
for (i, b) in res.iter_mut().enumerate() {
*b = (nibble_from_hex(mac[i * 3]) << 4) | nibble_from_hex(mac[i * 3 + 1])
}
Ok(res)
parse_mac(&resp.mac)
}
async fn set_wifi_mode(&mut self, mode: u32) -> Result<(), Error> {
@ -167,3 +176,35 @@ impl<'a> Control<'a> {
Ok(())
}
}
// WHY IS THIS A STRING? WHYYYY
fn parse_mac(mac: &str) -> Result<[u8; 6], Error> {
fn nibble_from_hex(b: u8) -> Result<u8, Error> {
match b {
b'0'..=b'9' => Ok(b - b'0'),
b'a'..=b'f' => Ok(b + 0xa - b'a'),
b'A'..=b'F' => Ok(b + 0xa - b'A'),
_ => {
warn!("invalid hex digit {}", b);
Err(Error::Internal)
}
}
}
let mac = mac.as_bytes();
let mut res = [0; 6];
if mac.len() != 17 {
warn!("unexpected MAC length");
return Err(Error::Internal);
}
for (i, b) in res.iter_mut().enumerate() {
*b = (nibble_from_hex(mac[i * 3])? << 4) | nibble_from_hex(mac[i * 3 + 1])?
}
Ok(res)
}
fn trim_nulls<const N: usize>(s: &mut String<N>) {
while s.chars().rev().next() == Some(0 as char) {
s.pop();
}
}

View File

@ -93,7 +93,7 @@ macro_rules! unreachable {
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*)
};
}
@ -229,7 +229,8 @@ impl<T, E> Try for Result<T, E> {
}
}
pub struct Bytes<'a>(pub &'a [u8]);
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

View File

@ -169,9 +169,9 @@ where
pub async fn run(mut self) -> ! {
debug!("resetting...");
self.reset.set_low().unwrap();
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
self.reset.set_high().unwrap();
Timer::after(Duration::from_millis(1000)).await;
Timer::after_millis(1000).await;
let mut tx_buf = [0u8; MAX_SPI_BUFFER_SIZE];
let mut rx_buf = [0u8; MAX_SPI_BUFFER_SIZE];

View File

@ -15,11 +15,11 @@ log = ["dep:log", "ppproto/log"]
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }
embedded-io-async = { version = "0.5.0" }
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embedded-io-async = { version = "0.6.0" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
ppproto = { version = "0.1.1"}
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
ppproto = { version = "0.1.2"}
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
[package.metadata.embassy_docs]
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-ppp-v$VERSION/embassy-net-ppp/src/"

View File

@ -93,7 +93,7 @@ macro_rules! unreachable {
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*);
::defmt::unreachable!($($x)*)
};
}
@ -229,7 +229,8 @@ impl<T, E> Try for Result<T, E> {
}
}
pub struct Bytes<'a>(pub &'a [u8]);
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {

View File

@ -11,7 +11,7 @@ use core::mem::MaybeUninit;
use embassy_futures::select::{select, Either};
use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::LinkState;
use embedded_io_async::{BufRead, Write, WriteAllError};
use embedded_io_async::{BufRead, Write};
use ppproto::pppos::{BufferFullError, PPPoS, PPPoSAction};
pub use ppproto::{Config, Ipv4Status};
@ -49,19 +49,10 @@ pub enum RunError<E> {
Read(E),
/// Writing to the serial port failed.
Write(E),
/// Writing to the serial port wrote zero bytes, indicating it can't accept more data.
WriteZero,
/// Writing to the serial got EOF.
Eof,
}
impl<E> From<WriteAllError<E>> for RunError<E> {
fn from(value: WriteAllError<E>) -> Self {
match value {
WriteAllError::Other(e) => Self::Write(e),
WriteAllError::WriteZero => Self::WriteZero,
}
}
/// PPP protocol was terminated by the peer
Terminated,
}
impl<'d> Runner<'d> {
@ -123,11 +114,14 @@ impl<'d> Runner<'d> {
buf[..pkt.len()].copy_from_slice(pkt);
rx_chan.rx_done(pkt.len());
}
PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await?,
PPPoSAction::Transmit(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?,
}
let status = ppp.status();
match status.phase {
ppproto::Phase::Dead => {
return Err(RunError::Terminated);
}
ppproto::Phase::Open => {
if !was_up {
on_ipv4_up(status.ipv4.unwrap());
@ -143,7 +137,7 @@ impl<'d> Runner<'d> {
}
Either::Second(pkt) => {
match ppp.send(pkt, &mut tx_buf) {
Ok(n) => rw.write_all(&tx_buf[..n]).await?,
Ok(n) => rw.write_all(&tx_buf[..n]).await.map_err(RunError::Write)?,
Err(BufferFullError) => unreachable!(),
}
tx_chan.tx_done();

View File

@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0"
edition = "2021"
[dependencies]
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
async-io = "1.6.0"
log = "0.4.14"
libc = "0.2.101"

View File

@ -10,8 +10,8 @@ edition = "2021"
[dependencies]
embedded-hal = { version = "1.0.0-rc.1" }
embedded-hal-async = { version = "=1.0.0-rc.1" }
embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.2", path = "../embassy-time" }
embassy-net-driver-channel = { version = "0.2.0", path = "../embassy-net-driver-channel" }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-futures = { version = "0.1.0", path = "../embassy-futures" }
defmt = { version = "0.3", optional = true }
@ -19,4 +19,4 @@ defmt = { version = "0.3", optional = true }
src_base = "https://github.com/embassy-rs/embassy/blob/embassy-net-wiznet-v$VERSION/embassy-net-wiznet/src/"
src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-net-wiznet/src/"
target = "thumbv7em-none-eabi"
features = ["defmt"]
features = ["defmt"]

View File

@ -8,7 +8,7 @@ mod device;
use embassy_futures::select::{select, Either};
use embassy_net_driver_channel as ch;
use embassy_net_driver_channel::driver::LinkState;
use embassy_time::{Duration, Timer};
use embassy_time::Timer;
use embedded_hal::digital::OutputPin;
use embedded_hal_async::digital::Wait;
use embedded_hal_async::spi::SpiDevice;
@ -95,12 +95,12 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, C: Chip, SPI: SpiDevi
// Reset the chip.
reset.set_low().ok();
// Ensure the reset is registered.
Timer::after(Duration::from_millis(1)).await;
Timer::after_millis(1).await;
reset.set_high().ok();
// Wait for PLL lock. Some chips are slower than others.
// Slowest is w5100s which is 100ms, so let's just wait that.
Timer::after(Duration::from_millis(100)).await;
Timer::after_millis(100).await;
let mac = WiznetDevice::new(spi_dev, mac_addr).await.unwrap();

29
embassy-net/CHANGELOG.md Normal file
View File

@ -0,0 +1,29 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.2.0 - 2023-10-18
- Re-export `smoltcp::wire::IpEndpoint`
- Add poll functions on UdpSocket
- Make dual-stack work in embassy-net
- Fix multicast support
- Allow ethernet and 802.15.4 to coexist
- Add IEEE802.15.4 address to embassy net Stack
- Use HardwareAddress in Driver
- Add async versions of smoltcp's `send` and `recv` closure based API
- add error translation to tcp errors
- Forward TCP/UDP socket capacity impls
- allow changing IP config at runtime
- allow non-'static drivers
- Remove impl_trait_projections
- update embedded-io, embedded-nal-async
- add support for dhcp hostname option
- Wake stack's task after queueing a DNS query
## 0.1.0 - 2023-06-29
- First release

View File

@ -1,6 +1,6 @@
[package]
name = "embassy-net"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "Async TCP/IP network stack for embedded systems"
@ -33,6 +33,7 @@ udp = ["smoltcp/socket-udp"]
tcp = ["smoltcp/socket-tcp"]
dns = ["smoltcp/socket-dns", "smoltcp/proto-dns"]
dhcpv4 = ["proto-ipv4", "medium-ethernet", "smoltcp/socket-dhcpv4"]
dhcpv4-hostname = ["dhcpv4"]
proto-ipv4 = ["smoltcp/proto-ipv4"]
proto-ipv6 = ["smoltcp/proto-ipv6"]
medium-ethernet = ["smoltcp/medium-ethernet"]
@ -50,10 +51,10 @@ smoltcp = { version = "0.10.0", default-features = false, features = [
"async",
] }
embassy-net-driver = { version = "0.1.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.2", path = "../embassy-time" }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embedded-io-async = { version = "0.5.0", optional = true }
embassy-net-driver = { version = "0.2.0", path = "../embassy-net-driver" }
embassy-time = { version = "0.1.5", path = "../embassy-time" }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embedded-io-async = { version = "0.6.0", optional = true }
managed = { version = "0.8.0", default-features = false, features = [ "map" ] }
heapless = { version = "0.7.5", default-features = false }
@ -62,5 +63,4 @@ generic-array = { version = "0.14.4", default-features = false }
stable_deref_trait = { version = "1.2.0", default-features = false }
futures = { version = "0.3.17", default-features = false, features = [ "async-await" ] }
atomic-pool = "1.0"
embedded-nal-async = { version = "0.5.0", optional = true }
atomic-polyfill = { version = "1.0" }
embedded-nal-async = { version = "0.6.0", optional = true }

View File

@ -1,7 +1,7 @@
use core::task::Context;
use embassy_net_driver::{Capabilities, Checksum, Driver, Medium, RxToken, TxToken};
use smoltcp::phy;
use embassy_net_driver::{Capabilities, Checksum, Driver, RxToken, TxToken};
use smoltcp::phy::{self, Medium};
use smoltcp::time::Instant;
pub(crate) struct DriverAdapter<'d, 'c, T>
@ -11,6 +11,7 @@ where
// must be Some when actually using this to rx/tx
pub cx: Option<&'d mut Context<'c>>,
pub inner: &'d mut T,
pub medium: Medium,
}
impl<'d, 'c, T> phy::Device for DriverAdapter<'d, 'c, T>
@ -22,13 +23,13 @@ where
fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
self.inner
.receive(self.cx.as_deref_mut().unwrap())
.receive(unwrap!(self.cx.as_deref_mut()))
.map(|(rx, tx)| (RxTokenAdapter(rx), TxTokenAdapter(tx)))
}
/// Construct a transmit token.
fn transmit(&mut self, _timestamp: Instant) -> Option<Self::TxToken<'_>> {
self.inner.transmit(self.cx.as_deref_mut().unwrap()).map(TxTokenAdapter)
self.inner.transmit(unwrap!(self.cx.as_deref_mut())).map(TxTokenAdapter)
}
/// Get a description of device capabilities.
@ -46,19 +47,7 @@ where
smolcaps.max_transmission_unit = caps.max_transmission_unit;
smolcaps.max_burst_size = caps.max_burst_size;
smolcaps.medium = match caps.medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => phy::Medium::Ethernet,
#[cfg(feature = "medium-ip")]
Medium::Ip => phy::Medium::Ip,
#[cfg(feature = "medium-ieee802154")]
Medium::Ieee802154 => phy::Medium::Ieee802154,
#[allow(unreachable_patterns)]
_ => panic!(
"Unsupported medium {:?}. Make sure to enable it in embassy-net's Cargo features.",
caps.medium
),
};
smolcaps.medium = self.medium;
smolcaps.checksum.ipv4 = convert(caps.checksum.ipv4);
smolcaps.checksum.tcp = convert(caps.checksum.tcp);
smolcaps.checksum.udp = convert(caps.checksum.udp);

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -1,5 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![warn(missing_docs)]
#![doc = include_str!("../README.md")]
@ -33,13 +33,14 @@ use heapless::Vec;
pub use smoltcp::iface::MulticastError;
#[allow(unused_imports)]
use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage};
use smoltcp::phy::Medium;
#[cfg(feature = "dhcpv4")]
use smoltcp::socket::dhcpv4::{self, RetryConfig};
#[cfg(feature = "medium-ethernet")]
pub use smoltcp::wire::EthernetAddress;
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154", feature = "medium-ip"))]
pub use smoltcp::wire::HardwareAddress;
#[cfg(feature = "udp")]
#[cfg(any(feature = "udp", feature = "tcp"))]
pub use smoltcp::wire::IpListenEndpoint;
#[cfg(feature = "medium-ieee802154")]
pub use smoltcp::wire::{Ieee802154Address, Ieee802154Frame};
@ -56,12 +57,22 @@ const LOCAL_PORT_MIN: u16 = 1025;
const LOCAL_PORT_MAX: u16 = 65535;
#[cfg(feature = "dns")]
const MAX_QUERIES: usize = 4;
#[cfg(feature = "dhcpv4-hostname")]
const MAX_HOSTNAME_LEN: usize = 32;
/// Memory resources needed for a network stack.
pub struct StackResources<const SOCK: usize> {
sockets: [SocketStorage<'static>; SOCK],
#[cfg(feature = "dns")]
queries: [Option<dns::DnsQuery>; MAX_QUERIES],
#[cfg(feature = "dhcpv4-hostname")]
hostname: core::cell::UnsafeCell<HostnameResources>,
}
#[cfg(feature = "dhcpv4-hostname")]
struct HostnameResources {
option: smoltcp::wire::DhcpOption<'static>,
data: [u8; MAX_HOSTNAME_LEN],
}
impl<const SOCK: usize> StackResources<SOCK> {
@ -73,6 +84,11 @@ impl<const SOCK: usize> StackResources<SOCK> {
sockets: [SocketStorage::EMPTY; SOCK],
#[cfg(feature = "dns")]
queries: [INIT; MAX_QUERIES],
#[cfg(feature = "dhcpv4-hostname")]
hostname: core::cell::UnsafeCell::new(HostnameResources {
option: smoltcp::wire::DhcpOption { kind: 0, data: &[] },
data: [0; MAX_HOSTNAME_LEN],
}),
}
}
}
@ -104,6 +120,7 @@ pub struct StaticConfigV6 {
/// DHCP configuration.
#[cfg(feature = "dhcpv4")]
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct DhcpConfig {
/// Maximum lease duration.
///
@ -120,6 +137,9 @@ pub struct DhcpConfig {
pub server_port: u16,
/// Client port. This is almost always 68. Do not change unless you know what you're doing.
pub client_port: u16,
/// Our hostname. This will be sent to the DHCP server as Option 12.
#[cfg(feature = "dhcpv4-hostname")]
pub hostname: Option<heapless::String<MAX_HOSTNAME_LEN>>,
}
#[cfg(feature = "dhcpv4")]
@ -131,6 +151,8 @@ impl Default for DhcpConfig {
ignore_naks: Default::default(),
server_port: smoltcp::wire::DHCP_SERVER_PORT,
client_port: smoltcp::wire::DHCP_CLIENT_PORT,
#[cfg(feature = "dhcpv4-hostname")]
hostname: None,
}
}
}
@ -168,10 +190,11 @@ impl Config {
}
}
/// IPv6 configuration with dynamic addressing.
/// IPv4 configuration with dynamic addressing.
///
/// # Example
/// ```rust
/// # use embassy_net::Config;
/// let _cfg = Config::dhcpv4(Default::default());
/// ```
#[cfg(feature = "dhcpv4")]
@ -226,10 +249,13 @@ struct Inner<D: Driver> {
static_v6: Option<StaticConfigV6>,
#[cfg(feature = "dhcpv4")]
dhcp_socket: Option<SocketHandle>,
config_waker: WakerRegistration,
#[cfg(feature = "dns")]
dns_socket: SocketHandle,
#[cfg(feature = "dns")]
dns_waker: WakerRegistration,
#[cfg(feature = "dhcpv4-hostname")]
hostname: &'static mut core::cell::UnsafeCell<HostnameResources>,
}
pub(crate) struct SocketStack {
@ -239,14 +265,17 @@ pub(crate) struct SocketStack {
next_local_port: u16,
}
fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> HardwareAddress {
fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> (HardwareAddress, Medium) {
match addr {
#[cfg(feature = "medium-ethernet")]
driver::HardwareAddress::Ethernet(eth) => HardwareAddress::Ethernet(EthernetAddress(eth)),
driver::HardwareAddress::Ethernet(eth) => (HardwareAddress::Ethernet(EthernetAddress(eth)), Medium::Ethernet),
#[cfg(feature = "medium-ieee802154")]
driver::HardwareAddress::Ieee802154(ieee) => HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)),
driver::HardwareAddress::Ieee802154(ieee) => (
HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)),
Medium::Ieee802154,
),
#[cfg(feature = "medium-ip")]
driver::HardwareAddress::Ip => HardwareAddress::Ip,
driver::HardwareAddress::Ip => (HardwareAddress::Ip, Medium::Ip),
#[allow(unreachable_patterns)]
_ => panic!(
@ -256,7 +285,7 @@ fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> HardwareAddress
}
}
impl<D: Driver + 'static> Stack<D> {
impl<D: Driver> Stack<D> {
/// Create a new network stack.
pub fn new<const SOCK: usize>(
mut device: D,
@ -264,7 +293,8 @@ impl<D: Driver + 'static> Stack<D> {
resources: &'static mut StackResources<SOCK>,
random_seed: u64,
) -> Self {
let mut iface_cfg = smoltcp::iface::Config::new(to_smoltcp_hardware_address(device.hardware_address()));
let (hardware_addr, medium) = to_smoltcp_hardware_address(device.hardware_address());
let mut iface_cfg = smoltcp::iface::Config::new(hardware_addr);
iface_cfg.random_seed = random_seed;
let iface = Interface::new(
@ -272,6 +302,7 @@ impl<D: Driver + 'static> Stack<D> {
&mut DriverAdapter {
inner: &mut device,
cx: None,
medium,
},
instant_to_smoltcp(Instant::now()),
);
@ -297,6 +328,7 @@ impl<D: Driver + 'static> Stack<D> {
static_v6: None,
#[cfg(feature = "dhcpv4")]
dhcp_socket: None,
config_waker: WakerRegistration::new(),
#[cfg(feature = "dns")]
dns_socket: socket.sockets.add(dns::Socket::new(
&[],
@ -304,6 +336,8 @@ impl<D: Driver + 'static> Stack<D> {
)),
#[cfg(feature = "dns")]
dns_waker: WakerRegistration::new(),
#[cfg(feature = "dhcpv4-hostname")]
hostname: &mut resources.hostname,
};
#[cfg(feature = "proto-ipv4")]
@ -328,7 +362,7 @@ impl<D: Driver + 'static> Stack<D> {
/// Get the hardware address of the network interface.
pub fn hardware_address(&self) -> HardwareAddress {
self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address()))
self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address()).0)
}
/// Get whether the link is up.
@ -363,6 +397,55 @@ impl<D: Driver + 'static> Stack<D> {
v4_up || v6_up
}
/// Wait for the network stack to obtain a valid IP configuration.
///
/// ## Notes:
/// - Ensure [`Stack::run`] has been called before using this function.
///
/// - This function may never return (e.g. if no configuration is obtained through DHCP).
/// The caller is supposed to handle a timeout for this case.
///
/// ## Example
/// ```ignore
/// let config = embassy_net::Config::dhcpv4(Default::default());
///// Init network stack
/// let stack = &*make_static!(embassy_net::Stack::new(
/// device,
/// config,
/// make_static!(embassy_net::StackResources::<2>::new()),
/// seed
/// ));
/// // Launch network task that runs `stack.run().await`
/// spawner.spawn(net_task(stack)).unwrap();
/// // Wait for DHCP config
/// stack.wait_config_up().await;
/// // use the network stack
/// // ...
/// ```
pub async fn wait_config_up(&self) {
// If the config is up already, we can return immediately.
if self.is_config_up() {
return;
}
poll_fn(|cx| {
if self.is_config_up() {
Poll::Ready(())
} else {
// If the config is not up, we register a waker that is woken up
// when a config is applied (static or DHCP).
trace!("Waiting for config up");
self.with_mut(|_, i| {
i.config_waker.register(cx.waker());
});
Poll::Pending
}
})
.await;
}
/// Get the current IPv4 configuration.
///
/// If using DHCP, this will be None if DHCP hasn't been able to
@ -432,7 +515,10 @@ impl<D: Driver + 'static> Stack<D> {
self.with_mut(|s, i| {
let socket = s.sockets.get_mut::<dns::Socket>(i.dns_socket);
match socket.start_query(s.iface.context(), name, qtype) {
Ok(handle) => Poll::Ready(Ok(handle)),
Ok(handle) => {
s.waker.wake();
Poll::Ready(Ok(handle))
}
Err(dns::StartQueryError::NoFreeSlot) => {
i.dns_waker.register(cx.waker());
Poll::Pending
@ -503,7 +589,7 @@ impl<D: Driver + 'static> Stack<D> {
}
#[cfg(feature = "igmp")]
impl<D: Driver + 'static> Stack<D> {
impl<D: Driver> Stack<D> {
/// Join a multicast group.
pub async fn join_multicast_group<T>(&self, addr: T) -> Result<bool, MulticastError>
where
@ -593,7 +679,7 @@ impl SocketStack {
}
}
impl<D: Driver + 'static> Inner<D> {
impl<D: Driver> Inner<D> {
#[cfg(feature = "proto-ipv4")]
pub fn set_config_v4(&mut self, _s: &mut SocketStack, config: ConfigV4) {
// Handle static config.
@ -616,11 +702,30 @@ impl<D: Driver + 'static> Inner<D> {
}
// Configure it
let socket = _s.sockets.get_mut::<dhcpv4::Socket>(self.dhcp_socket.unwrap());
let socket = _s.sockets.get_mut::<dhcpv4::Socket>(unwrap!(self.dhcp_socket));
socket.set_ignore_naks(c.ignore_naks);
socket.set_max_lease_duration(c.max_lease_duration.map(crate::time::duration_to_smoltcp));
socket.set_ports(c.server_port, c.client_port);
socket.set_retry_config(c.retry_config);
socket.set_outgoing_options(&[]);
#[cfg(feature = "dhcpv4-hostname")]
if let Some(h) = c.hostname {
// safety: we just did set_outgoing_options([]) so we know the socket is no longer holding a reference.
let hostname = unsafe { &mut *self.hostname.get() };
// create data
// safety: we know the buffer lives forever, new borrows the StackResources for 'static.
// also we won't modify it until next call to this function.
hostname.data[..h.len()].copy_from_slice(h.as_bytes());
let data: &[u8] = &hostname.data[..h.len()];
let data: &'static [u8] = unsafe { core::mem::transmute(data) };
// set the option.
hostname.option = smoltcp::wire::DhcpOption { data, kind: 12 };
socket.set_outgoing_options(core::slice::from_ref(&hostname.option));
}
socket.reset();
}
_ => {
@ -656,12 +761,12 @@ impl<D: Driver + 'static> Inner<D> {
debug!(" IP address: {:?}", config.address);
debug!(" Default gateway: {:?}", config.gateway);
addrs.push(IpCidr::Ipv4(config.address)).unwrap();
unwrap!(addrs.push(IpCidr::Ipv4(config.address)).ok());
gateway_v4 = config.gateway.into();
#[cfg(feature = "dns")]
for s in &config.dns_servers {
debug!(" DNS server: {:?}", s);
dns_servers.push(s.clone().into()).unwrap();
unwrap!(dns_servers.push(s.clone().into()).ok());
}
} else {
info!("IPv4: DOWN");
@ -673,12 +778,12 @@ impl<D: Driver + 'static> Inner<D> {
debug!(" IP address: {:?}", config.address);
debug!(" Default gateway: {:?}", config.gateway);
addrs.push(IpCidr::Ipv6(config.address)).unwrap();
unwrap!(addrs.push(IpCidr::Ipv6(config.address)).ok());
gateway_v6 = config.gateway.into();
#[cfg(feature = "dns")]
for s in &config.dns_servers {
debug!(" DNS server: {:?}", s);
dns_servers.push(s.clone().into()).unwrap();
unwrap!(dns_servers.push(s.clone().into()).ok());
}
} else {
info!("IPv6: DOWN");
@ -690,13 +795,13 @@ impl<D: Driver + 'static> Inner<D> {
// Apply gateways
#[cfg(feature = "proto-ipv4")]
if let Some(gateway) = gateway_v4 {
s.iface.routes_mut().add_default_ipv4_route(gateway).unwrap();
unwrap!(s.iface.routes_mut().add_default_ipv4_route(gateway));
} else {
s.iface.routes_mut().remove_default_ipv4_route();
}
#[cfg(feature = "proto-ipv6")]
if let Some(gateway) = gateway_v6 {
s.iface.routes_mut().add_default_ipv6_route(gateway).unwrap();
unwrap!(s.iface.routes_mut().add_default_ipv6_route(gateway));
} else {
s.iface.routes_mut().remove_default_ipv6_route();
}
@ -706,23 +811,35 @@ impl<D: Driver + 'static> Inner<D> {
s.sockets
.get_mut::<smoltcp::socket::dns::Socket>(self.dns_socket)
.update_servers(&dns_servers[..]);
self.config_waker.wake();
}
fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) {
s.waker.register(cx.waker());
let (_hardware_addr, medium) = to_smoltcp_hardware_address(self.device.hardware_address());
#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))]
if self.device.capabilities().medium == embassy_net_driver::Medium::Ethernet
|| self.device.capabilities().medium == embassy_net_driver::Medium::Ieee802154
{
s.iface
.set_hardware_addr(to_smoltcp_hardware_address(self.device.hardware_address()));
let do_set = match medium {
#[cfg(feature = "medium-ethernet")]
Medium::Ethernet => true,
#[cfg(feature = "medium-ieee802154")]
Medium::Ieee802154 => true,
#[allow(unreachable_patterns)]
_ => false,
};
if do_set {
s.iface.set_hardware_addr(_hardware_addr);
}
}
let timestamp = instant_to_smoltcp(Instant::now());
let mut smoldev = DriverAdapter {
cx: Some(cx),
inner: &mut self.device,
medium,
};
s.iface.poll(timestamp, &mut smoldev, &mut s.sockets);

View File

@ -440,7 +440,7 @@ impl<'d> TcpIo<'d> {
Poll::Ready(Err(Error::ConnectionReset))
}
} else {
Poll::Ready(match s.send(f.take().unwrap()) {
Poll::Ready(match s.send(unwrap!(f.take())) {
// Connection reset. TODO: this can also be timeouts etc, investigate.
Err(tcp::SendError::InvalidState) => Err(Error::ConnectionReset),
Ok(r) => Ok(r),
@ -468,7 +468,7 @@ impl<'d> TcpIo<'d> {
Poll::Ready(Err(Error::ConnectionReset))
}
} else {
Poll::Ready(match s.recv(f.take().unwrap()) {
Poll::Ready(match s.recv(unwrap!(f.take())) {
// Connection reset. TODO: this can also be timeouts etc, investigate.
Err(tcp::RecvError::Finished) | Err(tcp::RecvError::InvalidState) => {
Err(Error::ConnectionReset)
@ -579,11 +579,10 @@ mod embedded_io_impls {
/// TCP client compatible with `embedded-nal-async` traits.
#[cfg(feature = "nightly")]
pub mod client {
use core::cell::UnsafeCell;
use core::cell::{Cell, UnsafeCell};
use core::mem::MaybeUninit;
use core::ptr::NonNull;
use atomic_polyfill::{AtomicBool, Ordering};
use embedded_nal_async::IpAddr;
use super::*;
@ -702,15 +701,13 @@ pub mod client {
}
}
unsafe impl<const N: usize, const TX_SZ: usize, const RX_SZ: usize> Sync for TcpClientState<N, TX_SZ, RX_SZ> {}
struct Pool<T, const N: usize> {
used: [AtomicBool; N],
used: [Cell<bool>; N],
data: [UnsafeCell<MaybeUninit<T>>; N],
}
impl<T, const N: usize> Pool<T, N> {
const VALUE: AtomicBool = AtomicBool::new(false);
const VALUE: Cell<bool> = Cell::new(false);
const UNINIT: UnsafeCell<MaybeUninit<T>> = UnsafeCell::new(MaybeUninit::uninit());
const fn new() -> Self {
@ -724,7 +721,9 @@ pub mod client {
impl<T, const N: usize> Pool<T, N> {
fn alloc(&self) -> Option<NonNull<T>> {
for n in 0..N {
if self.used[n].swap(true, Ordering::SeqCst) == false {
// this can't race because Pool is not Sync.
if !self.used[n].get() {
self.used[n].set(true);
let p = self.data[n].get() as *mut T;
return Some(unsafe { NonNull::new_unchecked(p) });
}
@ -738,7 +737,7 @@ pub mod client {
let n = p.as_ptr().offset_from(origin);
assert!(n >= 0);
assert!((n as usize) < N);
self.used[n as usize].store(false, Ordering::SeqCst);
self.used[n as usize].set(false);
}
}
}

View File

@ -29,6 +29,8 @@ pub enum BindError {
pub enum Error {
/// No route to host.
NoRoute,
/// Socket not bound to an outgoing port.
SocketNotBound,
}
/// An UDP socket.
@ -155,7 +157,14 @@ impl<'a> UdpSocket<'a> {
s.register_send_waker(cx.waker());
Poll::Pending
}
Err(udp::SendError::Unaddressable) => Poll::Ready(Err(Error::NoRoute)),
Err(udp::SendError::Unaddressable) => {
// If no sender/outgoing port is specified, there is not really "no route"
if s.endpoint().port == 0 {
Poll::Ready(Err(Error::SocketNotBound))
} else {
Poll::Ready(Err(Error::NoRoute))
}
}
})
}

View File

@ -51,7 +51,7 @@ nrf52805 = ["nrf52805-pac", "_nrf52"]
nrf52810 = ["nrf52810-pac", "_nrf52"]
nrf52811 = ["nrf52811-pac", "_nrf52"]
nrf52820 = ["nrf52820-pac", "_nrf52"]
nrf52832 = ["nrf52832-pac", "_nrf52"]
nrf52832 = ["nrf52832-pac", "_nrf52", "_nrf52832_anomaly_109"]
nrf52833 = ["nrf52833-pac", "_nrf52", "_gpio-p1"]
nrf52840 = ["nrf52840-pac", "_nrf52", "_gpio-p1"]
nrf5340-app-s = ["_nrf5340-app", "_s"]
@ -90,9 +90,12 @@ _ppi = []
_dppi = []
_gpio-p1 = []
# Errata workarounds
_nrf52832_anomaly_109 = []
[dependencies]
embassy-time = { version = "0.1.2", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.2.0", path = "../embassy-sync" }
embassy-time = { version = "0.1.5", path = "../embassy-time", optional = true }
embassy-sync = { version = "0.3.0", path = "../embassy-sync" }
embassy-hal-internal = {version = "0.1.0", path = "../embassy-hal-internal", features = ["cortex-m", "prio-bits-3"] }
embassy-embedded-hal = {version = "0.1.0", path = "../embassy-embedded-hal" }
embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optional=true }
@ -100,8 +103,8 @@ embassy-usb-driver = {version = "0.1.0", path = "../embassy-usb-driver", optiona
embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1", optional = true}
embedded-hal-async = { version = "=1.0.0-rc.1", optional = true}
embedded-io = { version = "0.5.0" }
embedded-io-async = { version = "0.5.0", optional = true }
embedded-io = { version = "0.6.0" }
embedded-io-async = { version = "0.6.0", optional = true }
defmt = { version = "0.3", optional = true }
log = { version = "0.4.14", optional = true }

View File

@ -6,10 +6,13 @@ pub mod pac {
// To avoid cfg spam, we remove _ns or _s suffixes here.
pub use nrf5340_app_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf5340_app_pac::interrupt;
#[doc(no_inline)]
pub use nrf5340_app_pac::{
interrupt,
Interrupt,
Peripherals,
@ -60,156 +63,167 @@ pub mod pac {
wdt0_ns as wdt0,
};
#[cfg(feature = "nrf5340-app-ns")]
#[doc(no_inline)]
pub use nrf5340_app_pac::{
CLOCK_NS as CLOCK,
COMP_NS as COMP,
CTRLAP_NS as CTRLAP,
DCNF_NS as DCNF,
DPPIC_NS as DPPIC,
EGU0_NS as EGU0,
EGU1_NS as EGU1,
EGU2_NS as EGU2,
EGU3_NS as EGU3,
EGU4_NS as EGU4,
EGU5_NS as EGU5,
FPU_NS as FPU,
GPIOTE1_NS as GPIOTE1,
I2S0_NS as I2S0,
IPC_NS as IPC,
KMU_NS as KMU,
LPCOMP_NS as LPCOMP,
MUTEX_NS as MUTEX,
NFCT_NS as NFCT,
NVMC_NS as NVMC,
OSCILLATORS_NS as OSCILLATORS,
P0_NS as P0,
P1_NS as P1,
PDM0_NS as PDM0,
POWER_NS as POWER,
PWM0_NS as PWM0,
PWM1_NS as PWM1,
PWM2_NS as PWM2,
PWM3_NS as PWM3,
QDEC0_NS as QDEC0,
QDEC1_NS as QDEC1,
QSPI_NS as QSPI,
REGULATORS_NS as REGULATORS,
RESET_NS as RESET,
RTC0_NS as RTC0,
RTC1_NS as RTC1,
SAADC_NS as SAADC,
SPIM0_NS as SPIM0,
SPIM1_NS as SPIM1,
SPIM2_NS as SPIM2,
SPIM3_NS as SPIM3,
SPIM4_NS as SPIM4,
SPIS0_NS as SPIS0,
SPIS1_NS as SPIS1,
SPIS2_NS as SPIS2,
SPIS3_NS as SPIS3,
TIMER0_NS as TIMER0,
TIMER1_NS as TIMER1,
TIMER2_NS as TIMER2,
TWIM0_NS as TWIM0,
TWIM1_NS as TWIM1,
TWIM2_NS as TWIM2,
TWIM3_NS as TWIM3,
TWIS0_NS as TWIS0,
TWIS1_NS as TWIS1,
TWIS2_NS as TWIS2,
TWIS3_NS as TWIS3,
UARTE0_NS as UARTE0,
UARTE1_NS as UARTE1,
UARTE2_NS as UARTE2,
UARTE3_NS as UARTE3,
USBD_NS as USBD,
USBREGULATOR_NS as USBREGULATOR,
VMC_NS as VMC,
WDT0_NS as WDT0,
WDT1_NS as WDT1,
};
/// Non-Secure mode (NS) peripherals
pub mod ns {
#[cfg(feature = "nrf5340-app-ns")]
#[doc(no_inline)]
pub use nrf5340_app_pac::{
CLOCK_NS as CLOCK,
COMP_NS as COMP,
CTRLAP_NS as CTRLAP,
DCNF_NS as DCNF,
DPPIC_NS as DPPIC,
EGU0_NS as EGU0,
EGU1_NS as EGU1,
EGU2_NS as EGU2,
EGU3_NS as EGU3,
EGU4_NS as EGU4,
EGU5_NS as EGU5,
FPU_NS as FPU,
GPIOTE1_NS as GPIOTE1,
I2S0_NS as I2S0,
IPC_NS as IPC,
KMU_NS as KMU,
LPCOMP_NS as LPCOMP,
MUTEX_NS as MUTEX,
NFCT_NS as NFCT,
NVMC_NS as NVMC,
OSCILLATORS_NS as OSCILLATORS,
P0_NS as P0,
P1_NS as P1,
PDM0_NS as PDM0,
POWER_NS as POWER,
PWM0_NS as PWM0,
PWM1_NS as PWM1,
PWM2_NS as PWM2,
PWM3_NS as PWM3,
QDEC0_NS as QDEC0,
QDEC1_NS as QDEC1,
QSPI_NS as QSPI,
REGULATORS_NS as REGULATORS,
RESET_NS as RESET,
RTC0_NS as RTC0,
RTC1_NS as RTC1,
SAADC_NS as SAADC,
SPIM0_NS as SPIM0,
SPIM1_NS as SPIM1,
SPIM2_NS as SPIM2,
SPIM3_NS as SPIM3,
SPIM4_NS as SPIM4,
SPIS0_NS as SPIS0,
SPIS1_NS as SPIS1,
SPIS2_NS as SPIS2,
SPIS3_NS as SPIS3,
TIMER0_NS as TIMER0,
TIMER1_NS as TIMER1,
TIMER2_NS as TIMER2,
TWIM0_NS as TWIM0,
TWIM1_NS as TWIM1,
TWIM2_NS as TWIM2,
TWIM3_NS as TWIM3,
TWIS0_NS as TWIS0,
TWIS1_NS as TWIS1,
TWIS2_NS as TWIS2,
TWIS3_NS as TWIS3,
UARTE0_NS as UARTE0,
UARTE1_NS as UARTE1,
UARTE2_NS as UARTE2,
UARTE3_NS as UARTE3,
USBD_NS as USBD,
USBREGULATOR_NS as USBREGULATOR,
VMC_NS as VMC,
WDT0_NS as WDT0,
WDT1_NS as WDT1,
};
}
#[cfg(feature = "nrf5340-app-s")]
#[doc(no_inline)]
pub use nrf5340_app_pac::{
CACHEDATA_S as CACHEDATA,
CACHEINFO_S as CACHEINFO,
CACHE_S as CACHE,
CLOCK_S as CLOCK,
COMP_S as COMP,
CRYPTOCELL_S as CRYPTOCELL,
CTI_S as CTI,
CTRLAP_S as CTRLAP,
DCNF_S as DCNF,
DPPIC_S as DPPIC,
EGU0_S as EGU0,
EGU1_S as EGU1,
EGU2_S as EGU2,
EGU3_S as EGU3,
EGU4_S as EGU4,
EGU5_S as EGU5,
FICR_S as FICR,
FPU_S as FPU,
GPIOTE0_S as GPIOTE0,
I2S0_S as I2S0,
IPC_S as IPC,
KMU_S as KMU,
LPCOMP_S as LPCOMP,
MUTEX_S as MUTEX,
NFCT_S as NFCT,
NVMC_S as NVMC,
OSCILLATORS_S as OSCILLATORS,
P0_S as P0,
P1_S as P1,
PDM0_S as PDM0,
POWER_S as POWER,
PWM0_S as PWM0,
PWM1_S as PWM1,
PWM2_S as PWM2,
PWM3_S as PWM3,
QDEC0_S as QDEC0,
QDEC1_S as QDEC1,
QSPI_S as QSPI,
REGULATORS_S as REGULATORS,
RESET_S as RESET,
RTC0_S as RTC0,
RTC1_S as RTC1,
SAADC_S as SAADC,
SPIM0_S as SPIM0,
SPIM1_S as SPIM1,
SPIM2_S as SPIM2,
SPIM3_S as SPIM3,
SPIM4_S as SPIM4,
SPIS0_S as SPIS0,
SPIS1_S as SPIS1,
SPIS2_S as SPIS2,
SPIS3_S as SPIS3,
SPU_S as SPU,
TAD_S as TAD,
TIMER0_S as TIMER0,
TIMER1_S as TIMER1,
TIMER2_S as TIMER2,
TWIM0_S as TWIM0,
TWIM1_S as TWIM1,
TWIM2_S as TWIM2,
TWIM3_S as TWIM3,
TWIS0_S as TWIS0,
TWIS1_S as TWIS1,
TWIS2_S as TWIS2,
TWIS3_S as TWIS3,
UARTE0_S as UARTE0,
UARTE1_S as UARTE1,
UARTE2_S as UARTE2,
UARTE3_S as UARTE3,
UICR_S as UICR,
USBD_S as USBD,
USBREGULATOR_S as USBREGULATOR,
VMC_S as VMC,
WDT0_S as WDT0,
WDT1_S as WDT1,
};
/// Secure mode (S) peripherals
pub mod s {
#[cfg(feature = "nrf5340-app-s")]
#[doc(no_inline)]
pub use nrf5340_app_pac::{
CACHEDATA_S as CACHEDATA,
CACHEINFO_S as CACHEINFO,
CACHE_S as CACHE,
CLOCK_S as CLOCK,
COMP_S as COMP,
CRYPTOCELL_S as CRYPTOCELL,
CTI_S as CTI,
CTRLAP_S as CTRLAP,
DCNF_S as DCNF,
DPPIC_S as DPPIC,
EGU0_S as EGU0,
EGU1_S as EGU1,
EGU2_S as EGU2,
EGU3_S as EGU3,
EGU4_S as EGU4,
EGU5_S as EGU5,
FICR_S as FICR,
FPU_S as FPU,
GPIOTE0_S as GPIOTE0,
I2S0_S as I2S0,
IPC_S as IPC,
KMU_S as KMU,
LPCOMP_S as LPCOMP,
MUTEX_S as MUTEX,
NFCT_S as NFCT,
NVMC_S as NVMC,
OSCILLATORS_S as OSCILLATORS,
P0_S as P0,
P1_S as P1,
PDM0_S as PDM0,
POWER_S as POWER,
PWM0_S as PWM0,
PWM1_S as PWM1,
PWM2_S as PWM2,
PWM3_S as PWM3,
QDEC0_S as QDEC0,
QDEC1_S as QDEC1,
QSPI_S as QSPI,
REGULATORS_S as REGULATORS,
RESET_S as RESET,
RTC0_S as RTC0,
RTC1_S as RTC1,
SAADC_S as SAADC,
SPIM0_S as SPIM0,
SPIM1_S as SPIM1,
SPIM2_S as SPIM2,
SPIM3_S as SPIM3,
SPIM4_S as SPIM4,
SPIS0_S as SPIS0,
SPIS1_S as SPIS1,
SPIS2_S as SPIS2,
SPIS3_S as SPIS3,
SPU_S as SPU,
TAD_S as TAD,
TIMER0_S as TIMER0,
TIMER1_S as TIMER1,
TIMER2_S as TIMER2,
TWIM0_S as TWIM0,
TWIM1_S as TWIM1,
TWIM2_S as TWIM2,
TWIM3_S as TWIM3,
TWIS0_S as TWIS0,
TWIS1_S as TWIS1,
TWIS2_S as TWIS2,
TWIS3_S as TWIS3,
UARTE0_S as UARTE0,
UARTE1_S as UARTE1,
UARTE2_S as UARTE2,
UARTE3_S as UARTE3,
UICR_S as UICR,
USBD_S as USBD,
USBREGULATOR_S as USBREGULATOR,
VMC_S as VMC,
WDT0_S as WDT0,
WDT1_S as WDT1,
};
}
#[cfg(feature = "_ns")]
pub use ns::*;
#[cfg(feature = "_s")]
pub use s::*;
}
/// The maximum buffer size that the EasyDMA can send/recv in one operation.

View File

@ -7,9 +7,12 @@ pub mod pac {
pub use nrf5340_net_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf5340_net_pac::interrupt;
#[doc(no_inline)]
pub use nrf5340_net_pac::{
interrupt,
Interrupt,
Peripherals,

View File

@ -7,9 +7,12 @@ pub mod pac {
pub use nrf9160_pac::NVIC_PRIO_BITS;
#[cfg(feature="rt")]
#[doc(no_inline)]
pub use nrf9160_pac::interrupt;
#[doc(no_inline)]
pub use nrf9160_pac::{
interrupt,
Interrupt,
cc_host_rgf_s as cc_host_rgf,
@ -45,122 +48,131 @@ pub mod pac {
wdt_ns as wdt,
};
#[cfg(feature = "nrf9160-ns")]
#[doc(no_inline)]
pub use nrf9160_pac::{
CLOCK_NS as CLOCK,
DPPIC_NS as DPPIC,
EGU0_NS as EGU0,
EGU1_NS as EGU1,
EGU2_NS as EGU2,
EGU3_NS as EGU3,
EGU4_NS as EGU4,
EGU5_NS as EGU5,
FPU_NS as FPU,
GPIOTE1_NS as GPIOTE1,
I2S_NS as I2S,
IPC_NS as IPC,
KMU_NS as KMU,
NVMC_NS as NVMC,
P0_NS as P0,
PDM_NS as PDM,
POWER_NS as POWER,
PWM0_NS as PWM0,
PWM1_NS as PWM1,
PWM2_NS as PWM2,
PWM3_NS as PWM3,
REGULATORS_NS as REGULATORS,
RTC0_NS as RTC0,
RTC1_NS as RTC1,
SAADC_NS as SAADC,
SPIM0_NS as SPIM0,
SPIM1_NS as SPIM1,
SPIM2_NS as SPIM2,
SPIM3_NS as SPIM3,
SPIS0_NS as SPIS0,
SPIS1_NS as SPIS1,
SPIS2_NS as SPIS2,
SPIS3_NS as SPIS3,
TIMER0_NS as TIMER0,
TIMER1_NS as TIMER1,
TIMER2_NS as TIMER2,
TWIM0_NS as TWIM0,
TWIM1_NS as TWIM1,
TWIM2_NS as TWIM2,
TWIM3_NS as TWIM3,
TWIS0_NS as TWIS0,
TWIS1_NS as TWIS1,
TWIS2_NS as TWIS2,
TWIS3_NS as TWIS3,
UARTE0_NS as UARTE0,
UARTE1_NS as UARTE1,
UARTE2_NS as UARTE2,
UARTE3_NS as UARTE3,
VMC_NS as VMC,
WDT_NS as WDT,
};
/// Non-Secure mode (NS) peripherals
pub mod ns {
#[doc(no_inline)]
pub use nrf9160_pac::{
CLOCK_NS as CLOCK,
DPPIC_NS as DPPIC,
EGU0_NS as EGU0,
EGU1_NS as EGU1,
EGU2_NS as EGU2,
EGU3_NS as EGU3,
EGU4_NS as EGU4,
EGU5_NS as EGU5,
FPU_NS as FPU,
GPIOTE1_NS as GPIOTE1,
I2S_NS as I2S,
IPC_NS as IPC,
KMU_NS as KMU,
NVMC_NS as NVMC,
P0_NS as P0,
PDM_NS as PDM,
POWER_NS as POWER,
PWM0_NS as PWM0,
PWM1_NS as PWM1,
PWM2_NS as PWM2,
PWM3_NS as PWM3,
REGULATORS_NS as REGULATORS,
RTC0_NS as RTC0,
RTC1_NS as RTC1,
SAADC_NS as SAADC,
SPIM0_NS as SPIM0,
SPIM1_NS as SPIM1,
SPIM2_NS as SPIM2,
SPIM3_NS as SPIM3,
SPIS0_NS as SPIS0,
SPIS1_NS as SPIS1,
SPIS2_NS as SPIS2,
SPIS3_NS as SPIS3,
TIMER0_NS as TIMER0,
TIMER1_NS as TIMER1,
TIMER2_NS as TIMER2,
TWIM0_NS as TWIM0,
TWIM1_NS as TWIM1,
TWIM2_NS as TWIM2,
TWIM3_NS as TWIM3,
TWIS0_NS as TWIS0,
TWIS1_NS as TWIS1,
TWIS2_NS as TWIS2,
TWIS3_NS as TWIS3,
UARTE0_NS as UARTE0,
UARTE1_NS as UARTE1,
UARTE2_NS as UARTE2,
UARTE3_NS as UARTE3,
VMC_NS as VMC,
WDT_NS as WDT,
};
}
#[cfg(feature = "nrf9160-s")]
#[doc(no_inline)]
pub use nrf9160_pac::{
CC_HOST_RGF_S as CC_HOST_RGF,
CLOCK_S as CLOCK,
CRYPTOCELL_S as CRYPTOCELL,
CTRL_AP_PERI_S as CTRL_AP_PERI,
DPPIC_S as DPPIC,
EGU0_S as EGU0,
EGU1_S as EGU1,
EGU2_S as EGU2,
EGU3_S as EGU3,
EGU4_S as EGU4,
EGU5_S as EGU5,
FICR_S as FICR,
FPU_S as FPU,
GPIOTE0_S as GPIOTE0,
I2S_S as I2S,
IPC_S as IPC,
KMU_S as KMU,
NVMC_S as NVMC,
P0_S as P0,
PDM_S as PDM,
POWER_S as POWER,
PWM0_S as PWM0,
PWM1_S as PWM1,
PWM2_S as PWM2,
PWM3_S as PWM3,
REGULATORS_S as REGULATORS,
RTC0_S as RTC0,
RTC1_S as RTC1,
SAADC_S as SAADC,
SPIM0_S as SPIM0,
SPIM1_S as SPIM1,
SPIM2_S as SPIM2,
SPIM3_S as SPIM3,
SPIS0_S as SPIS0,
SPIS1_S as SPIS1,
SPIS2_S as SPIS2,
SPIS3_S as SPIS3,
SPU_S as SPU,
TAD_S as TAD,
TIMER0_S as TIMER0,
TIMER1_S as TIMER1,
TIMER2_S as TIMER2,
TWIM0_S as TWIM0,
TWIM1_S as TWIM1,
TWIM2_S as TWIM2,
TWIM3_S as TWIM3,
TWIS0_S as TWIS0,
TWIS1_S as TWIS1,
TWIS2_S as TWIS2,
TWIS3_S as TWIS3,
UARTE0_S as UARTE0,
UARTE1_S as UARTE1,
UARTE2_S as UARTE2,
UARTE3_S as UARTE3,
UICR_S as UICR,
VMC_S as VMC,
WDT_S as WDT,
};
/// Secure mode (S) peripherals
pub mod s {
#[doc(no_inline)]
pub use nrf9160_pac::{
CC_HOST_RGF_S as CC_HOST_RGF,
CLOCK_S as CLOCK,
CRYPTOCELL_S as CRYPTOCELL,
CTRL_AP_PERI_S as CTRL_AP_PERI,
DPPIC_S as DPPIC,
EGU0_S as EGU0,
EGU1_S as EGU1,
EGU2_S as EGU2,
EGU3_S as EGU3,
EGU4_S as EGU4,
EGU5_S as EGU5,
FICR_S as FICR,
FPU_S as FPU,
GPIOTE0_S as GPIOTE0,
I2S_S as I2S,
IPC_S as IPC,
KMU_S as KMU,
NVMC_S as NVMC,
P0_S as P0,
PDM_S as PDM,
POWER_S as POWER,
PWM0_S as PWM0,
PWM1_S as PWM1,
PWM2_S as PWM2,
PWM3_S as PWM3,
REGULATORS_S as REGULATORS,
RTC0_S as RTC0,
RTC1_S as RTC1,
SAADC_S as SAADC,
SPIM0_S as SPIM0,
SPIM1_S as SPIM1,
SPIM2_S as SPIM2,
SPIM3_S as SPIM3,
SPIS0_S as SPIS0,
SPIS1_S as SPIS1,
SPIS2_S as SPIS2,
SPIS3_S as SPIS3,
SPU_S as SPU,
TAD_S as TAD,
TIMER0_S as TIMER0,
TIMER1_S as TIMER1,
TIMER2_S as TIMER2,
TWIM0_S as TWIM0,
TWIM1_S as TWIM1,
TWIM2_S as TWIM2,
TWIM3_S as TWIM3,
TWIS0_S as TWIS0,
TWIS1_S as TWIS1,
TWIS2_S as TWIS2,
TWIS3_S as TWIS3,
UARTE0_S as UARTE0,
UARTE1_S as UARTE1,
UARTE2_S as UARTE2,
UARTE3_S as UARTE3,
UICR_S as UICR,
VMC_S as VMC,
WDT_S as WDT,
};
}
#[cfg(feature = "_ns")]
pub use ns::*;
#[cfg(feature = "_s")]
pub use s::*;
}
/// The maximum buffer size that the EasyDMA can send/recv in one operation.

View File

@ -1,6 +1,8 @@
#![macro_use]
#![allow(unused_macros)]
use core::fmt::{Debug, Display, LowerHex};
#[cfg(all(feature = "defmt", feature = "log"))]
compile_error!("You may not enable both `defmt` and `log` features.");
@ -81,14 +83,17 @@ macro_rules! todo {
};
}
#[cfg(not(feature = "defmt"))]
macro_rules! unreachable {
($($x:tt)*) => {
{
#[cfg(not(feature = "defmt"))]
::core::unreachable!($($x)*);
#[cfg(feature = "defmt")]
::defmt::unreachable!($($x)*);
}
::core::unreachable!($($x)*)
};
}
#[cfg(feature = "defmt")]
macro_rules! unreachable {
($($x:tt)*) => {
::defmt::unreachable!($($x)*)
};
}
@ -223,3 +228,31 @@ impl<T, E> Try for Result<T, E> {
self
}
}
#[allow(unused)]
pub(crate) struct Bytes<'a>(pub &'a [u8]);
impl<'a> Debug for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> Display for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
impl<'a> LowerHex for Bytes<'a> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{:#02x?}", self.0)
}
}
#[cfg(feature = "defmt")]
impl<'a> defmt::Format for Bytes<'a> {
fn format(&self, fmt: defmt::Formatter) {
defmt::write!(fmt, "{:02x}", self.0)
}
}

View File

@ -86,7 +86,6 @@ pub(crate) fn init(irq_prio: crate::interrupt::Priority) {
unsafe { irq.enable() };
let g = regs();
g.events_port.write(|w| w);
g.intenset.write(|w| w.port().set());
}

View File

@ -1,5 +1,5 @@
#![no_std]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))]
#![cfg_attr(feature = "nightly", feature(async_fn_in_trait))]
#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
@ -102,6 +102,7 @@ mod chip;
#[macro_export]
macro_rules! bind_interrupts {
($vis:vis struct $name:ident { $($irq:ident => $($handler:ty),*;)* }) => {
#[derive(Copy, Clone)]
$vis struct $name;
$(

Some files were not shown because too many files have changed in this diff Show More