Skip to content

Conversation

rmsyn
Copy link
Contributor

@rmsyn rmsyn commented May 20, 2025

Thank you for your contribution!

We appreciate the time and effort you've put into this pull request.
To help us review it efficiently, please ensure you've gone through the following checklist:

Submission Checklist 📝

  • I have updated existing examples or added new ones (if applicable).
  • I have used cargo xtask fmt-packages command to ensure that all changed code is formatted correctly.
  • My changes were added to the CHANGELOG.md in the proper section.
  • I have added necessary changes to user code to the Migration Guide.
  • My changes are in accordance to the esp-rs developer guidelines

Extra:

Pull Request Details 📖

Description

Provides the initial skeleton for the embedded_hal::mmc::MmcOps implementation for the SDIO peripherals on the ESP32C6 microcontroller.

Testing

Doc tests for now.

Integration tests via examples program is WIP.

@rmsyn rmsyn marked this pull request as draft May 20, 2025 01:12
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch 2 times, most recently from b7eeb4c to 2142d4d Compare May 22, 2025 03:31
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch 3 times, most recently from dddf388 to c3a7b0d Compare May 30, 2025 03:17
@rmsyn
Copy link
Contributor Author

rmsyn commented May 30, 2025

Running the CI / * checks are failing, partially due to some weird dependency resolution.

As I get closer to a full implementation, I may need to bring in the embedded-hal::mmc::* stuff locally to avoid the git dependency.

What's strange is that running cargo clippy ... directly passes, but the xtask lint-packages can't resolve the embedded_hal::mmc::MmcCommon trait, and fails to build the embassy-hal-async examples.

I'll keep debugging.

@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from c3a7b0d to f017518 Compare May 30, 2025 04:14
@bugadani
Copy link
Contributor

It would be best to not block this PR on embedded-hal, as it'll likely take months to stabilize a new set of traits. You should instead demonstrate new functionality in a new crate, like embedded-sdmmc in the embedded-hal repository, so that it can be released unstably and implemented by esp-hal and one other required implementor.

That way you wouldn't have to patch around the dependency issues with multiple embedded-hal versions in the same project.

@MabezDev
Copy link
Member

To expand on @bugadani's comment, we can't merge this with git dependencies, so I would take the suggestion to split this into a separate crate and then work on upstreaming to eh proper. Feel free to iterate here in the mean time, but if you want this merged it won't be with a fork of embedded-hal.

@rmsyn
Copy link
Contributor Author

rmsyn commented May 31, 2025

It would be best to not block this PR on embedded-hal, as it'll likely take months to stabilize a new set of traits. You should instead demonstrate new functionality in a new crate, like embedded-sdmmc in the embedded-hal repository, so that it can be released unstably and implemented by esp-hal and one other required implementor.

This sounds like a good plan. I'll bring it up in next week's meeting, and see what the rest of the HAL team thinks.

To expand on @bugadani's comment, we can't merge this with git dependencies, so I would take the suggestion to split this into a separate crate and then work on upstreaming to eh proper. Feel free to iterate here in the mean time, but if you want this merged it won't be with a fork of embedded-hal.

Right, I had no intention of trying to get this PR merged with the git dependency. My original thought process was to prove the implementation here and in jh71xx-hal, iterate on the trait in embedded-hal, stabilize in embedded-hal, and take this PR out of Draft status after an embedded-hal release that includes the mmc module + traits.

However, the solution discussed above sounds like a better plan. We could do a embedded-hal-sdmmc v0.1.0-alpha.whatever release, and base the work off that crate until mmc stuff gets merged upstream (if ever).

Without trying to bikeshed too much, we would probably need to call it embedded-hal-sdmmc, since @thejpster already has embedded-sdmmc-rs. embedded-hal-sdmmc also keeps with the naming convention of embedded-hal-[async, io, nb, ...].

rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 4, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from fb552b8 to b0058c0 Compare June 4, 2025 02:06
rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 4, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 4, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from b0058c0 to a53f104 Compare June 4, 2025 02:07
rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 4, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from a53f104 to 5ec5792 Compare June 4, 2025 02:19
rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 4, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from 5ec5792 to ec42929 Compare June 4, 2025 02:29
@rmsyn
Copy link
Contributor Author

rmsyn commented Jun 26, 2025

I added the remaining functions needed for the SDIO init implementation.

Not sure about the best way to approach SOC-specific methods (i.e. the low_level_* methods). The methods do more-or-less the same thing on each SOC, but the register names are different, especially between the ESP32 and ESP32-C6 interrupt naming conventions.

One design I though of was to add a SdioLowLevel trait, and implement the trait on SOC-specific data structures, instead of the Any<Peripheral> types.

@Dominaezzz @MabezDev @bugadani thoughts?

rmsyn added a commit to rmsyn/esp-hal that referenced this pull request Jun 26, 2025
Uses the experimental `embedded-hal-sdmmc` crate for SD/MMC traits.

See discussion for reasoning:

- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
- <esp-rs#3503 (comment)>
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from 6ce6b2f to 69ec4b9 Compare June 26, 2025 23:19
@Dominaezzz
Copy link
Collaborator

Regarding the low level stuff, see #1282 . Whilst esp-idf serves as a (mostly reliable) working reference, its design decisions (which were made for a C library) shouldn't be copied directly (into a Rust hal).

Check out what the stable(izing) drivers (SPI, I2C, UART, GPIO) are doing to get an idea of what to do. Also the dev guidelines is another place to check.

imo, for chip-based differences, cfgs are more appropriate than traits. traits are more appropriate for peripheral-based differences on the same chip.

@rmsyn
Copy link
Contributor Author

rmsyn commented Jun 27, 2025

Whilst esp-idf serves as a (mostly reliable) working reference, its design decisions (which were made for a C library) shouldn't be copied directly (into a Rust hal).

Agreed, I kept the relative structure of the code the same. It should hopefully make reviewing the code easier, since the mapping from the Rust back to the esp-idf function names is pretty close. I obviously changed the functions to be idiomatic Rust.

imo, for chip-based differences, cfgs are more appropriate than traits. traits are more appropriate for peripheral-based differences on the same chip.

This is the approach I ended up going with, which can hopefully be extended pretty easily as more SDIO-having SOCs are added.

@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from f075cd5 to bc0c396 Compare June 27, 2025 04:23
rmsyn and others added 28 commits October 2, 2025 22:46
Adds DMA descriptor types based on the main DMA engine descriptors.

The main difference is the bitfield layout used in the descriptor flags.
Adds the `DescriptorFlagFields` trait to generalize field accessor
functions for descriptor flag types.

Enables using a generic parameter for `DmaDescriptor`.
Implements the `DescriptorFlagFields` trait for the relevant types.

Small refactors to handle function naming differences.
Adds some methods to the `Owner` type for better ergonomics.
Refactors the `DmaDescriptor` type to `DmaDescriptorGeneric` taking a
generic parameter for the flags field.

Creates convenience aliases for the concrete types used in the general +
SDIO dedicated DMA descriptors.
Makes the `Preparation` type generic over the `DescriptorFlagFields`
trait.
Maks `DmaLoopBuf` generic over the `DescriptorFlagFields` trait.
Makes the `DmaRxStreamingBuf` type generic over the
`DescriptorFieldFlags` trait.
Makes the `DescriptorSet` type generic over the `DescriptorFlagFields`
trait.
Makes the `DmaTxBuf` generic over the `DescriptorFlagFields` trait.
Makes the `DmaRxBuf` generic over the `DescriptorFlagFields` trait.
Makes the `DmaRxTxBuf` type generic over the `DescriptorFlagFields`
trait.
Makes the `ChannelTx` struct generic over the `DescriptorFlagFields`
trait.
Use the `EnumSetType` derive macro, and `EnumSet` type for the
`HostInterrupt` and `DeviceInterrupt` types to match current
development conventions.
Removes `Generic` suffix from generic DMA types.

Replaces default type aliases with a default concrete type in the
generic parameter declaration.

Authored-by: rmsyn <[email protected]>
Co-authored-by: Dominic Fischer <[email protected]>
Adds a generic paramter for the descriptor flags for the `ChannelRx`
type.
Makes the `DmaTxBuffer` generic over the `DescriptorFlagFields` trait.
Makes the `DmaRxBuffer` trait generic over the `DescriptorFlagFields`
trait.
Uses consistent naming + formatting for descriptor flag generic
parameters.
To avoid a semver bump, re-add the `set_length` methods to
`DmaDescriptorFlags` and `DmaDescriptor`.
Adds the `AtomicDmaDescriptor` type to enable safely storing DMA
descriptors in static variables.
Adds the `AtomicBuffer` type to allow storing byte buffers safely in
static variables.
Adds the `bitfielder` library as a more performant and ergonomic
bitfield library.
Adds SDIO commands supported by ESP SDIO controllers.
Adds the SD and SPI mode `R5` response types, and the corresponding
field types.
Adds `Sdio::read_command_raw` + `Sdio::write_response_raw` functions to
read and write raw data on the `CMD` line.

TODO: add SDIO mode implementations

NOTE: these functions may be unecessary, the controller seems to handle
command/response in hardware (at least in SPI mode).
Adds a split `qa-test` SPI-mode SDIO integration test.

The tests are split with the intention to flash each half of the test to
separate devices, allowing for concurrent execution.
@rmsyn rmsyn force-pushed the esp32c6/sdmmc-impl branch from ec263a8 to e5c9931 Compare October 2, 2025 23:18
@rmsyn
Copy link
Contributor Author

rmsyn commented Oct 7, 2025

Apologies for stalling on this, I was waiting on 10kOhm resistors to arrive, and they did last week. I added them to the bench circuit, but they didn't help. The device still returns garbage to the host using SDIO in SPI-mode.

I'm honestly at a loss for what else to even try. The communication at this phase of the SDIO protocol is all happening in hardware in the SPI and SDIO DMA engines, so it feels like even hooking something like probe-rs into the loop won't do much good. If anyone has other ideas on how to continue debugging this issue, I'm willing to try whatever approach looks most promising.

Edit: there does appear to be a GPIO IRQ firing on the SDIO device side, so maybe I need to setup a handler? From our discussions before, I thought that the low-level SDIO protocol was handled in hardware because any software would be too slow (including an IRQ handler). Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants