diff --git a/.gitignore b/.gitignore index b71c776..a63335e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ Cargo.lock .vscode/ *.DS_Store +.idea \ No newline at end of file diff --git a/advanced/common/consts/src/lib.rs b/advanced/common/consts/src/lib.rs index d9f78db..7e1edf6 100644 --- a/advanced/common/consts/src/lib.rs +++ b/advanced/common/consts/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] -pub const VID: u16 = 0x2020; -pub const PID: u16 = 0x0717; +// using the "working" IDs of nRF board +pub const VID: u16 = 0x1366; +pub const PID: u16 = 0x1015; \ No newline at end of file diff --git a/advanced/host/print-descs/Cargo.toml b/advanced/host/print-descs/Cargo.toml index ed9c1ef..c17ca86 100644 --- a/advanced/host/print-descs/Cargo.toml +++ b/advanced/host/print-descs/Cargo.toml @@ -6,6 +6,6 @@ name = "print-descs" version = "0.0.0" [dependencies] -rusb = "0.5.5" +rusb = "0.8" anyhow = "1.0.31" consts = { path = "../../common/consts/" } diff --git a/embedded-workshop-book/src/SUMMARY.md b/embedded-workshop-book/src/SUMMARY.md index 1e79ec4..0f93712 100644 --- a/embedded-workshop-book/src/SUMMARY.md +++ b/embedded-workshop-book/src/SUMMARY.md @@ -26,7 +26,7 @@ - [Starting a Project from Scratch](./from-scratch.md) - [Advanced Workbook](./advanced-workbook.md) - [Code Organization](./code-organisation.md) - - [Listing USB Devices](./listing-usb-devices.md) + - [Workshop goal](./workshop-goal.md) - [Hello, world!](./hello-world.md) - [Checking the API documentation](./api-documentation.md) - [RTIC hello](./rtic-hello.md) diff --git a/embedded-workshop-book/src/api-documentation.md b/embedded-workshop-book/src/api-documentation.md index 6bfc276..d99bd6a 100644 --- a/embedded-workshop-book/src/api-documentation.md +++ b/embedded-workshop-book/src/api-documentation.md @@ -9,4 +9,4 @@ $ cargo doc -p dk --open ``` -> NOTE: If you are using Safari and the documentation is hard to read due to missing CSS, try opening it in a different browser. \ No newline at end of file +> ❗️ If you are using Safari and the documentation is hard to read due to missing CSS, try opening it in a different browser. \ No newline at end of file diff --git a/embedded-workshop-book/src/event-handling.md b/embedded-workshop-book/src/event-handling.md index 8d0608f..7c95337 100644 --- a/embedded-workshop-book/src/event-handling.md +++ b/embedded-workshop-book/src/event-handling.md @@ -6,4 +6,11 @@ Below the `idle` function you'll see a `#[task]` handler, a function. This *task Note that all tasks will be prioritized over the `idle` function so the execution of `idle` will be interrupted (paused) by the `on_power_event` task. When the `on_power_event` task finishes (returns) the execution of the `idle` will be resumed. This will become more obvious in the next section. -Try this: add an infinite loop to the end of `init` so that it never returns. Now run the program and connect the USB cable. What behavior do you observe? How would you explain this behavior? (hint: look at the `rtic-expansion.rs` file: under what conditions is the `init` function executed?) \ No newline at end of file +Try this: add an infinite loop to the end of `init` so that it never returns. Now run the program and connect the USB cable. What behavior do you observe? How would you explain this behavior? (hint: look at the `rtic-expansion.rs` file: under what conditions is the `init` function executed?) + +
+Click me to see hint + +You may observe that nothing happens when you plug in the USB cable to J3. The `init` function is called once inside the `main` but `init` in this case has an infinite loop. + +
\ No newline at end of file diff --git a/embedded-workshop-book/src/hello-world.md b/embedded-workshop-book/src/hello-world.md index 43cfaa5..c203dd4 100644 --- a/embedded-workshop-book/src/hello-world.md +++ b/embedded-workshop-book/src/hello-world.md @@ -4,7 +4,7 @@ In this section, we'll set up the integration in VS Code and run the first progr ✅ Open the `advanced/firmware` folder in VS Code and open the `src/bin/hello.rs` file. -> Note: To ensure full rust-analyzer support, do not open the whole `embedded-trainings-2020` folder. +> ❗️ To ensure full rust-analyzer support, do not open the whole `embedded-trainings-2020` folder. Give rust-analyzer some time to analyze the file and its dependency graph. When it's done, a "Run" button will appear over the `main` function. If it doesn't appear on its own, type something in the file, delete and save. This should trigger a re-load. @@ -12,11 +12,11 @@ Give rust-analyzer some time to analyze the file and its dependency graph. When If you are not using VS code run the `cargo run --bin hello` command from the `advanced/firmware` folder. -> NOTE if you run into an error along the lines of "Debug power request failed" retry the operation and the error should disappear +> ❗️ If you run into an error along the lines of "Debug power request failed" retry the operation and the error should disappear -The `firmware` workspace has been configured to cross-compile applications to the ARM Cortex-M architecture and then run them using the `probe-run` custom Cargo runner. The `probe-run` tool will load and run the embedded application on the microcontroller and collect logs from the microcontroller. +The `firmware` workspace has been configured to cross-compile applications to the ARM Cortex-M architecture and then run them using the `probe-run` custom Cargo runner. This is set in `.cargo/config.toml`. The `probe-run` tool will load and run the embedded application on the microcontroller and collect logs from the microcontroller. The `probe-run` process will terminate when the microcontroller enters the "halted" state. From the embedded application, one can enter the "halted" state using the `asm::bkpt` function. For convenience, an `exit` function is provided in the `dk` Hardware Abstraction Layer (HAL). This function is divergent like `std::process::exit` (`fn() -> !`) and can be used to halt the device and terminate the `probe-run` process. -Note that when the `probe-run` tool sees the device enter the halted state it will proceed to *reset-halt* the device. This is particularly important when writing USB applications because simply leaving the device in a halted state will make it appear as an unresponsive USB device to the host. Some OSes (e.g. Linux) will try to make an unresponsive device respond by power cycling the entire USB bus -- this will cause all other USB devices on the bus to be re-enumerated. Reset-halting the device will cause it to be electrically disconnected from the host USB bus and avoid the "power cycle the whole USB bus" scenario. +>🔎 When the `probe-run` tool sees the device enter the halted state it will proceed to *reset-halt* the device. This is particularly important when writing USB applications because simply leaving the device in a halted state will make it appear as an unresponsive USB device to the host. Some OSes (e.g. Linux) will try to make an unresponsive device respond by power cycling the entire USB bus -- this will cause all other USB devices on the bus to be re-enumerated. Reset-halting the device will cause it to be electrically disconnected from the host USB bus and avoid the "power cycle the whole USB bus" scenario. diff --git a/embedded-workshop-book/src/img/host-and-device.jpg b/embedded-workshop-book/src/img/host-and-device.jpg new file mode 100644 index 0000000..7837b1a Binary files /dev/null and b/embedded-workshop-book/src/img/host-and-device.jpg differ diff --git a/embedded-workshop-book/src/listing-usb-devices.md b/embedded-workshop-book/src/listing-usb-devices.md index a6173d1..f5f5c68 100644 --- a/embedded-workshop-book/src/listing-usb-devices.md +++ b/embedded-workshop-book/src/listing-usb-devices.md @@ -1,26 +1 @@ # Listing USB Devices - -✅ To list all USB devices, run `cargo xtask usb-list` from the `advanced` folder. - - -``` console -$ cargo xtask usb-list -Bus 002 Device 001: ID 1d6b:0003 -Bus 001 Device 002: ID 0cf3:e300 -Bus 001 Device 003: ID 0c45:6713 -Bus 001 Device 001: ID 1d6b:0002 -Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit -``` - -The goal of this workshop is to get the nRF52840 SoC to show in this list. The embedded application will use the vendor ID (VID) and product ID (PID) defined in `advanced/common/consts`; `cargo xtask usb-list` will highlight the USB device that matches that VID PID pair. - -``` console -$ # expected output -$ cargo xtask usb-list -Bus 002 Device 001: ID 1d6b:0003 -Bus 001 Device 002: ID 0cf3:e300 -Bus 001 Device 003: ID 0c45:6713 -Bus 001 Device 001: ID 1d6b:0002 -Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit -Bus 001 Device 059: ID 2020:0717 <- nRF52840 on the nRF52840 Development Kit -``` diff --git a/embedded-workshop-book/src/usb-enumeration.md b/embedded-workshop-book/src/usb-enumeration.md index 8f0802d..f5f8e01 100644 --- a/embedded-workshop-book/src/usb-enumeration.md +++ b/embedded-workshop-book/src/usb-enumeration.md @@ -1,16 +1,24 @@ # USB Enumeration -Check this miro board for an [overview](https://miro.com/app/board/uXjVObcQhcc=/?invite_link_id=467100096053). +![Labeled Diagram of the nRF52840 and Host interaction](img/host-and-device.jpg) -A USB device, like the nRF52840, can be one of these three states: the Default state, the Address state or the Configured state. After being powered the device will start in the Default state. The enumeration process will take the device from the Default state to the Address state. As a result of the enumeration process the device will be assigned an address, in the range `1..=127`, by the host. +[Screenshot taken from miro board](https://miro.com/app/board/uXjVObcQhcc=/?invite_link_id=467100096053) -The USB protocol is complex so we'll leave out many details and focus only on the concepts required to get enumeration and configuration working. There are also several USB specific terms so we recommend checking chapter 2, "Terms and Abbreviations", of the USB specification (linked at the bottom of this document) every now and then. +A USB device, like the nRF52840, can be one of these three states: + +- the Default state, +- the Address state, or +- the Configured state + +After being powered the device will start in the Default state. The enumeration process will take the device from the Default state to the Address state. As a result of the enumeration process the device will be assigned an address, in the range `1..=127`, by the host. + +The USB protocol is complex so we'll leave out many details and focus only on the concepts required to get enumeration and configuration working. There are also several USB specific terms so we recommend checking chapter 2, "Terms and Abbreviations", of [the USB specification](https://www.usb.org/document-library/usb-20-specification) every now and then. Each OS may perform the enumeration process slightly differently but the process will always involve these host actions: -- USB reset. This will put the device in the Default state, regardless of what state it was in. -- GET_DESCRIPTOR request to get the device descriptor. -- SET_ADDRESS request to assign an address to the device. +- USB reset: put the device in the Default state, regardless of what state it was in. +- GET_DESCRIPTOR: request to get the device descriptor. +- SET_ADDRESS: request to assign an address to the device. These host actions will be perceived as *events* by the nRF52840. During this workshop, we will gradually parse and handle these events and learn more about Embedded Rust along the way. diff --git a/embedded-workshop-book/src/usb-events.md b/embedded-workshop-book/src/usb-events.md index a575901..1f2fa99 100644 --- a/embedded-workshop-book/src/usb-events.md +++ b/embedded-workshop-book/src/usb-events.md @@ -12,7 +12,7 @@ In this starter code the USBD peripheral is initialized in `init` and a task, na This code will panic because `USBRESET` is not implemented yet. -✅ Go to `fn on_event`, line 39. In this section you'll need to implement the following USB events `USBRESET` and `EP0SETUP` so that your log output will look like this: +✅ Go to `fn on_event`. In this section you'll need to implement the following USB events `USBRESET` and `EP0SETUP` so that your log output will look like this: ``` console USBD initialized diff --git a/embedded-workshop-book/src/workshop-goal.md b/embedded-workshop-book/src/workshop-goal.md new file mode 100644 index 0000000..ad97f8d --- /dev/null +++ b/embedded-workshop-book/src/workshop-goal.md @@ -0,0 +1,31 @@ +# Workshop goal + +The goal of this workshop is to get the nRF52840 SoC to show in this list. The embedded application will use the vendor ID (VID) and product ID (PID) defined in `advanced/common/consts`. + +`cargo xtask usb-list` will highlight the USB device that matches that VID PID pair. + +``` console +$ # expected output +$ cargo xtask usb-list +Bus 002 Device 001: ID 1d6b:0003 +Bus 001 Device 002: ID 0cf3:e300 +Bus 001 Device 003: ID 0c45:6713 +Bus 001 Device 001: ID 1d6b:0002 +Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit +Bus 001 Device 059: ID 2020:0717 <- nRF52840 on the nRF52840 Development Kit +``` + + +## Listing USB Devices + +✅ To list all USB devices, run `cargo xtask usb-list` from the `advanced` folder. + + +``` console +$ cargo xtask usb-list +Bus 002 Device 001: ID 1d6b:0003 +Bus 001 Device 002: ID 0cf3:e300 +Bus 001 Device 003: ID 0c45:6713 +Bus 001 Device 001: ID 1d6b:0002 +Bus 001 Device 010: ID 1366:1015 <- J-Link on the nRF52840 Development Kit +```