Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

esp32c3 how to change SPI bus clock speed #204

Closed
jeancf opened this issue Sep 30, 2022 · 4 comments
Closed

esp32c3 how to change SPI bus clock speed #204

jeancf opened this issue Sep 30, 2022 · 4 comments

Comments

@jeancf
Copy link
Contributor

jeancf commented Sep 30, 2022

Some time ago I wrote an SD Card driver for the Longan Nano to provide filesystem access through the fatfs crate. I am now porting it to the esp32c3.

I am running into an issue when I want to change the clock speed of the SPI bus. For the initialization of the card, the SPI bus clock rate must be set between 100 kHz and 400 kHz. Then the SCLK frequency should be changed to 20-25 MHz to maximize the read/write performance.

My driver Card struct receives ownership of the SPI peripheral, the pins, the SPIMode variant, &Clocks and &mut SystemClockControl from the user through this call:

pub fn new(
        p_spi: pac::SPI2,
        cs: Gpio14<Output<PushPull>>,
        sck: Gpio15<Alternate<PushPull>>,
        miso: Gpio17<Input<Floating>>,
        mosi: Gpio16<Alternate<PushPull>>,
        clocks: &Clocks,
        pcc: &mut PeripheralClockControl,
    ) -> Self

and then creates the esp32c3_hal::spi::Spi struct with a bus frequency of 400 KHz by calling Spi::new_no_cs(). So far so good.

Now, to increase the bus speed to 20 MHz I tried to Spi::free() the Spi and recreate a new one by calling Spi::new_internal() BUT the driver struct I no longer has the &mut PeripheralClockControl that is required for that call. How can I solve this issue?

I see 2 options:

  • The easiest from my perspective would be to have a method in esp32c3_hal::spi::Spi to change the bus clock speed. That is what the gd32vf103xx_hal does.I think it would need to call the spi::Instance::setup() method in hal-common.
  • Spi::free() could also return &mut PeripheralClockControl so that it can be re-injected in a following call to Spi::new_internal(). This approach has the disadvantage that I have to keep the &Clocks around in the Card struct, which contaminates the crate with lifetimes everywhere.
@jeancf jeancf changed the title esp32c3 changing SPI bus clock speed esp32c3 how to change SPI bus clock speed Sep 30, 2022
@bjoernQ
Copy link
Contributor

bjoernQ commented Sep 30, 2022

Thanks for bringing this up! I think having this feature would be quite useful

Option 1 seems to be the right thing but it also needs the &Clocks or at least the SPI driver needs to hold a copy of apb_clock

Option 2 is a problem since the driver doesn't hold &mut PeripheralClockControl (since that would prevent anyone else from using PeripheralClockControl)

@jeancf
Copy link
Contributor Author

jeancf commented Oct 4, 2022

OK. I am not sure if I can implement it but I will give it a try.

@jessebraham jessebraham moved this to Todo in esp-rs Oct 4, 2022
@bjoernQ
Copy link
Contributor

bjoernQ commented Oct 5, 2022

Sounds great! In case you get stuck or have questions - we are happy to help

@bjoernQ
Copy link
Contributor

bjoernQ commented Oct 28, 2022

Fix by #235

@bjoernQ bjoernQ closed this as completed Oct 28, 2022
Repository owner moved this from Todo to Done in esp-rs Oct 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

2 participants