You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/embedded/0.Tock/index.md
+8Lines changed: 8 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,14 @@ This workshop will not work on Windows systems.
12
12
You can use the Ubuntu VM we provide [here](https://drive.google.com/file/d/1WSUo29d9Z8bmcjurvkDUmoAgq1TqaW4H/view?usp=sharing) (only works on VirtualBox).
13
13
The username and password are both `ipwembedded`.
14
14
The VM has the port 3033 forwarded for SSH connection.
15
+
16
+
If you want to have the VM home directory mounted in Windows, use the following commands (with Admin PowerShell):
17
+
18
+
```powershell
19
+
winget install -e --id WinFsp.WinFsp
20
+
winget install -e --id SSHFS-Win.SSHFS-Win
21
+
net use X: \\sshfs\ipwembedded@localhost!3033
22
+
```
15
23
:::
16
24
17
25
If you did not attend the **Tock Workshop**, please follow the [Setup Tutorial](../../tock_workshop/index.md).
Copy file name to clipboardExpand all lines: docs/embedded/1.Embassy/index.md
+45-2Lines changed: 45 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -244,7 +244,7 @@ The communication is *half-duplex*. This means that data is transmitted only in
244
244
:::
245
245
246
246
:::info I2C inner works
247
-
The `SDA` and `SCL` wires are never actually driven (set to `LOW`/`HIGH`) by the controller/peripherals. The line is controlled by either pulling the line low or releasing the line high.
247
+
The `SDA` and `SCL` wires are never actually driven (set to `LOW`/`HIGH`) by the controller/peripherals. The line is controlled by either pulling the line low or releasing the line high.
248
248
249
249
When the line is *pulled down*, this means that it is connected directly to `GND`. This electronically translates to `LOW`.
250
250
@@ -266,12 +266,13 @@ Before the transmission, both the `SCL` and `SDA` lines are set to `HIGH`. First
266
266
Depending on the command bit (R/W), either the controller or the target begins to send data over the `SDA` line. Data is sent one byte at a time, and then acknowledged by the receiver. One sequence of a data byte and `ack` is called a *frame*.
267
267
268
268
During the communication, data can be:
269
+
269
270
- written to the `SDA` line *only* when `SCL` is `LOW` or
270
271
- read from the `SDA` line *only* when `SCL` is `HIGH`.
271
272
272
273
##### End
273
274
274
-
To end the transmission, the controller signals a `stop` condition. This is done by releasing the `SCL` line to `HIGH`, and then also releasing the `SDA` line. Since data can be written *only* when `SCL` is `LOW`, the target understands that this is a special event, that means that the communication has ended.
275
+
To end the transmission, the controller signals a `stop` condition. This is done by releasing the `SCL` line to `HIGH`, and then also releasing the `SDA` line. Since data can be written *only* when `SCL` is `LOW`, the target understands that this is a special event, that means that the communication has ended.
To write data to a target, we will be using the `write`**async**functionof the I2C driver.
354
355
355
356
This functionalso takes 2 parameters:
357
+
356
358
- the address of the target we are attempting to transmit the data to
357
359
- the *transmitting* buffer that contains the data we want to send to the target
358
360
@@ -433,3 +435,44 @@ After each complete memory write transaction, the EEPROM an internally-timed wri
433
435
#### `eeprom24x` crate
434
436
435
437
To simplify the interfacing with the non-volatile memory for your **project**, you can use the [`eeprom24x`](https://crates.io/crates/eeprom24x) crate. It is a is a platform agnostic Rust driver for the 24x series serial EEPROM, based on the [`embedded-hal`](https://docs.rs/embedded-hal/1.0.0/embedded_hal/) traits. This means that you will not be able to harness the power of the async executor, and you will need to use the conventional **blocking** API.
438
+
439
+
## Asynchronous basics
440
+
441
+
Until now you've only worked with simple (almost) serial programs. However, not all programs can be designed to run serially/sequentially. Handling multiple I/O events concurrently usually requires separate parallel tasks. For example, reading a button press while blinking an LED. A single loop would block the button reading event while waiting for the timer to finish.
442
+
443
+
To address this issue, we would need to spawn a new task in which we would wait for the button press, while blinking the LED in the `main` function.
444
+
445
+
The signature of the task that toggles the LED when the button is pressed would need to receive both an `Input` and `Output` as arguments.
In the main function, tasks can be spawned using the `Spawner` provided as an argument.
460
+
461
+
```rust title="src/bin/button_task.rs"
462
+
#[embassy_executor::main]
463
+
async fn main(spawner: Spawner) {
464
+
let p = embassy_stm32::init(Default::default());
465
+
466
+
// TODO: initialize LEDs and button
467
+
468
+
spawner.must_spawn(button_task(led, btn));
469
+
470
+
loop {
471
+
// Handle other LED blink
472
+
}
473
+
}
474
+
```
475
+
476
+
To periodically blink and LED, you will need to be able to introduce a delay. You can do so manually, by introducing a `for` loop with a number of steps that takes into account the frequency of the processor. The issue with this method is that it would do a *"busy loop"* where the processor spends both time and energy doing unproductive instructions.
477
+
478
+
This approach does not benefit from the underlying `async` that could schedule another task with available work to be executed. If you want to introduce delays the *`embassy`* way, you can do it using the `Timer` interface, specifically the `Timer::after()` function which takes a `Duration`, or the more direct `after_milis`, `after_secs`, etc.
0 commit comments