Giter Club home page Giter Club logo

stm32h7xx-hal's Introduction

stm32h7xx-hal

docs.rs CI Crates.io Minimum rustc version

stm32h7xx-hal contains a hardware abstraction layer on top of the peripheral access API for the STMicro STM32H7xx family of microcontrollers. The idea behind this crate is to gloss over the slight differences in the various peripherals available on those MCUs so a HAL can be written for all chips in that same family without having to cut and paste crates for every single model.

This crate relies on Adam Greig's fantastic stm32h7 crate to provide appropriate register definitions, and implements a partial set of the embedded-hal traits. Much of the implementation was adapted from other HAL crates in the stm32-rs organisation.

Collaboration on this crate is highly welcome, as are pull requests!

Supported Configurations

  • stm32h743v (Revision V: stm32h743, stm32h742, stm32h750)
  • stm32h753v
  • stm32h747cm7 (stm32h747, stm32h757)
  • stm32h7b3
  • stm32h7b0
  • stm32h7a3
  • stm32h735 (stm32h723, stm32h725, stm32h730, stm32h733, stm32h735)

STM32H7R3/7S3 are not directly supported, see #492

Old revision STM32H742/743/750/753 parts

In 2019 ST released hardware Revision V of the stm32h742, stm32h743, stm32h750 and stm32h753 (eevblog). This hardware revision makes breaking hardware changes, documented in AN5312. If you have a device purchased before mid-2019, check the revision code on your device. Parts from the previous revision (Revision Y) are supported by feature gates without the 'v' suffix. (stm32h743, stm32h753)

Dual core parts (Cortex M7 + Cortex M4)

On dual core parts, currently only the Cortex M7 core is supported.

Flash memory size

By default this crate assumes a 2Mbyte flash size. To set a smaller limit for linker errors, uncomment the correct FLASH section definition in memory.x

Getting Started

The examples folder contains several example programs. To compile them, specify the target device in a cargo feature:

$ cargo build --features=stm32h743v,rt

See the Examples README for more details.

To use stm32h7xx-hal as a dependency in a standalone project the target device feature must be specified in the Cargo.toml file:

[dependencies]
cortex-m = "0.7.4"
cortex-m-rt = "0.7.1"
stm32h7xx-hal = {version = "0.16.0", features = ["stm32h743v","rt"]}

If you are unfamiliar with embedded development using Rust, there are a number of fantastic resources available to help.

Hardware

Below is a short list of publicly available and documented STM32H7 development boards. Note that including them on this list does not mean they have been successfully tested with this crate. Some boards have a Board Support Crate (BSP) offering pin mappings and additional functionality.

Board Manufacturer BSP / Examples?
NUCLEO-H743ZI ST Examples
NUCLEO-H745ZI-Q ST BSP
STM32H743I-EVAL ST
STM32H747I-EVAL ST
STM32H747I-DISCO ST
Daisy Seed Electrosmith BSP
Portenta H7 ⚠️ Arduino
OpenH743I-C Waveshare
Toasty Webtronics

⚠️: Programming this board via its USB connector requires interacting with an unknown proprietary(?) bootloader. This bootloader may make it difficult or impossible for you to load binaries not approved by Arduino. Alternative programming interfaces are only available on the high density connectors.

Minimum supported Rust version

The Minimum Supported Rust Version (MSRV) at the moment is 1.66.1. Older versions may compile, especially when some features are not used in your application.

Changelog

See CHANGELOG.md.

License

0-Clause BSD License, see LICENSE-0BSD.txt for more details.

stm32h7xx-hal's People

Contributors

alyoshavasilieva avatar andrewgazelka avatar antoinevg avatar astraw avatar bors[bot] avatar burrbull avatar dflemstr avatar diondokter avatar dsmcfarl avatar elouanpetereau avatar glindstedt avatar hargonix avatar jarredallen avatar jlogan03 avatar jordens avatar lachlansneff-parallel avatar mattico avatar mlamoore avatar mtthw-meyer avatar newam avatar nkrackow avatar olback avatar orange-murker avatar ost-ing avatar phoracek avatar richardeoin avatar robamu avatar romixlab avatar ryan-summers avatar x37v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stm32h7xx-hal's Issues

GPIOC Unknown Field

I can compile this without any issues
cargo build --example blinky --features=stm32h750v,rt

But if I take the same code, paste it into a new crate, copying the .cargo/config and dependencies it won't compile. I've compared everything I can think of and there is just something missing that I can't figure out.

cargo build
   Compiling daisy-lib2 v0.1.0 (/home/zerikin/rust/daisy-lib2)
error[E0609]: no field `GPIOC` on type `stm32h7xx_hal::rcc::rec::PeripheralREC`
  --> src/main.rs:28:48
   |
28 |     let gpioc = dp.GPIOC.split(ccdr.peripheral.GPIOC);
   |                                                ^^^^^ unknown field
   |
   = note: available fields are: `ETH1MAC`, `DMA2`, `DMA1`, `SDMMC2`, `HASH` ... and 22 others

error: aborting due to previous error

For more information about this error, try `rustc --explain E0609`.
error: could not compile `daisy-lib2`.

To learn more, run the command again with --verbose.

DMA API

During today's embedded WG meeting James mentioned that:

If you see anyone working on DMA stuff, ping them and see if they could move their work over to the new APIs :)

Referring to these https://github.com/ra-kete/dma-poc APIs.

So @Jan561 should maybe try and look into directing his efforts towards getting DMA running towards these APIs, if enough succesul implementations show up they might be added to embedded-hal soon ™️ which would be a big plus embedded Rust.

Support for stm32h725/735

Hi,

I'd like for a project to use the stm32h725. It has ECC RAM, something the other stm32h7 boards don't have. Well except for the stm32h747/757, but I'd rather not pay the premium for features I won't use anyway.
I noticed those boards aren't supported by this library.

Is it because nobody has the μControler to test? Or is it because of an incompatibility with the hardware?

If it's because of testing or minor incompatibility I'd be willing to help. I have never worked on a HAL like this though, so if it's ok with you I'd still want instructions about how to proceed.

README on crates.io

The README on crates.io doesn't seem to be up to date as of now, at least it still states that we require nightly / beta to build which isn't the case since the stabilization of 1.37 anymore, I think we should update that.

Secondly our build for docs.rs is currently failing, however I've already been pointed at a way to fix this and will look into that in a few minutes.

As a side not as to where this is coming from I'm currently doing a PR to get our crate into the awesome-embedded-rust list: rust-embedded/awesome-embedded-rust#209

Implement tick_timer() for lptimers

Ref #114

The tick_timer method is not implemented for LPTIM[1-5]

Is there some limitation of the LPTIMs that makes it difficult?

The LPTIMs require a specific initialisation sequence (for example, CFGR must be set before enabling the timer, ARR must be set after), so it's not difficult but rather a little tedious to check against the RM that it's correct.

Cargo.toml typo

In Cargo.toml I think the line
stm32h742 = ["stm32h7/stm32h743", "device-selected", "singlecore"]
should have 742 in place of 743

Add PLL strategy for fractional clock

The fractional divisor allows setting of precise clocks during runtime using the rcc_pllxfracr register. It needs to be enabled during startup. I purpose adding two new PLL strategies that enable the fractional divisor. One for just below and just above a target value. (e.g. for audio I want a clock that is as close to possible as 48 KHz * 256 without going under).

I think the existing iterative strategy could be used to set the base clock and then tweak the rcc_pllxfracr from there.

PllConfigStrategy::FractionalGreaterThan
PllConfigStrategy::FractionalLessThan

[Proposal] Log wrapper

For my own project I wrapped the log crate to allow output via RTT or none via feature. A feature gated logger implementing several implementations sounds really useful. Could include ITM, RTT, etc. Leaving no features selected makes the macro empty and it get's compiled out.

Is this the right level of crate for this or should it go somewhere else?

Example

No implementation for SAI I2S

As far as I can tell the only implemented functionality for SAI is PDM. The daisy uses SAI I2S for audio I/O to the codec chip. If I can figure it out I may take a shot at implementing it myself.

Already existing stm32h7x3-hal project

Hey guys, I'm the owner of https://github.com/hargoniX/stm32h7x3-hal which I've been working on for the past few months and I was wondering if you'd be interested in me PRing all my implementations you don't have yet, like for example the already tested I2C and the SPI one over to you and continue my work on your repository.

EDIT: Looking at your code a little I can also provide you with a few extensions of for example the rcc with a custom sys_ck setting which I've been spending on getting to work for a few weeks in feburary.

Unused trait in Serial?

So I was just reading through our UART/USART implementation in serial.rs and there we define the trait pub trait PinCk<USART> {} in line 155. It's only ever used again in the macro that implements it en mass for all the pins that are valid clock pins for USART. However I believe the correct intention should be to implement the Pin trait for a (TX, RX, CK) triple for all USART constructors right? Otherwise the trait doesn't bring any additional safety guarantees as far as I can see (feel free to correct me on that).

Support custom SPI configurations

The existing SPI configuration assumes a lot of default configuration values (e.g. 8 bit frames, 1 frame per transaction, no delay between CS and SCK assertions).

I propose that we update the Spi constructors to accept a spi::Config structure instead of the spi::Mode parameter. This Config structure would contain all of the device-specific implementation. To construct the Config, a builder semantic can be used:

Let config = Spi::Config::new(Mode {polarity: Polarity::IdleHigh, phase: Phase::CaptureOnSecondTransition})
    .frame_size(8) // Configure 8-bit transactions
    .swap_miso_mosi() // Swap MOSI and MISO lines
    .cs_delay(100e-6) // 100uS delay from CS -> SCK
    .freeze();

let spi = spi::Spi1::new(dp.SPI1, (sck, miso, mosi), config, 10.mhz(), &clocks);

This allows us to initially provide a minimal configuration as to what users require and expand on it as needed without changing the API at all (e.g. backwards compatible).

I'd be happy to implement this and PR it, just wanted to get some feedback first.

Background

I'm currently working on a platform using SPI to talk to some ADCs and DACs where the channel is half-duplex. Some additional configurations that I need are:

  1. MSSI support (programmable delay from CS assertion to transaction)
  2. Configurable transaction length (16 bit frames)
  3. Support for swapping MOSI/MISO lines

Reincorporate stm32h7-ethernet

As per the conversation on Matrix and in #76, it has been proposed that the various stm32h7 peripheral drivers should be contained within this crate to prevent many interdependent crates in the h7 ecosystem. Instead, peripherals that are not directly related to the embedded-hal should be placed behind feature gates.

This issue encompasses re-incorporating the stm32h7-ethernet crate into this crate.

@hargoniX mentioned that he was planning on getting to this in the near future.

DMA module does not reset/enable during initialization

When DMA::split() is called, the PREC is not provided and the DMA does not set the reset/enable bits in the RCC.

Further configuration and usage of the DMA is then inoperative because the peripheral is not enabled.

Expose RCC registers for external usage

When the HAL is used in an application, there are (many) peripherals that are not yet supported by the HAL (such as ethernet, quadspi, DMA, etc.). Often, these peripherals may need a custom implementation for performance or specific use-case considerations.

The Rcc::Ccdr should expose the underlying RCC register block publicly so that other drivers may modify the necessary RCC registers to enable clocks and reset peripherals as needed. This is currently done only for the HAL crate, but it may be appropriate to allow this block to be exposed for all usage.

As currently implemented, the HAL takes exclusive ownership of the RCC registers, so it's impossible to implement application-specific drivers outside of the HAL alongside drivers that utilize the HAL implementation.

Timer first cycle is invalid

When the timer is configured, the first cycle of the timer will have an incorrect period. After the first cycle, all following periods will be correct.

This occurs because the ARR register is buffered and doesn't become "Active" (referred as the shadow register in the datasheet) until an update event occurs (either by software or hardware).

As such, the timer start() routine needs to make a call to

self.tim.egr.write(|w| w.ug.set_bit());

to force an update of the ARR register. There's another method of accomplishing this (bypassing the shadow register), but I don't think that's what we want.

More constfn!

It has finally happened! As per rust-lang/rust#72437 the following things are now allowed in const functions:

  • if, if let, and match
  • while, while let, and loop
  • the && and || operators

This should allows us to basically move all of our clock calculation optionally to compile time since for most of the peripherals we provide it's very unlikely someone will want to dynamically change the clock speed at runtime, if they instead opt in to const-fn calculation of their clock speeds we can:

  • reduce initialization time since we don't have to calculate the config while starting up anymore
  • reduce binary size since the code wanders from runtime to compile time

I'm not quite sure whether this is doable as a const fn without breaking the current API though? I'd imagine we would need to add an additional parameter clock_configuration that gets passed the result of such a config calculator function? For example an I2C init might end up looking like:

dp.I2C1.i2c((scl, sda), i2c_configuration(100.khz()), ccdr.peripheral.I2C1, &ccdr.clocks);

Because otherwise the constant functions aren't called in a constant context so the rust compiler would treat them just like normal functions, or am I mistaken about that? If the compiler was feeling really clever it could of course allow us to call the const fn inside the i2c function, see that the parameter is a constant and evaluate the const fn at compile time, but I dont think it can perform such magic? Again not quite sure, this definitely requires some further investigation but definitely provides some big benefits for the HAL once adopted.

Examples use ITM

May cause a hang when running examples, if debugger is removed or mis-configured.

Feature gating ITM usage is a possible solution.

Clocks contains wrong value of `sys_ck` when it comes from PLL1

When the system clock is set by rcc.sys_ck(), the required clock usually comes from PLL1 P CK. But in the case where the generated PLL1 P CK does not exactly match what was specified (depending on the pll strategy), then the calculated PLL1 P CK frequency should be used for sys_ck and derived clocks. Currently the specified value is used.

Flash clock and wait states

To calculate the number of wait states for the flash, we use RM0433 Rev 7. Table 17

image

This table implies the calculation should be based on the AXI Interface clock (= rcc_hclk). However the text immediately above it says it should be based on sys_ck. Indeed the block diagram (Fig. 5) shows only sys_ck entering the flash sub-system.

image

image

Which clock should we use for this calculation? (see Figure 49.)

  • sys_ck
  • sys_d1cpre_ck ( = sys_ck / 1)
  • rcc_hclk ( = sys_d1cpre / 2 by default)

Currently we use sys_d1cpre_ck, so the flash is always set to 7 wait states for sys_d1cpre_ck > 225MHz.

TODO:

  • Decide and use correct clock
  • Add flash wait state table for VOS0

SPI operates in "endless transaction" mode

When a SPI transaction occurs, the HAL operates the SPI in "endless transaction" mode, which means that the SPI peripheral is not able to detect when a transaction completes.

The SPI_CR2.TSIZE register value needs to be updated with the size of the transaction in bytes before a transaction is initiated.

ST have renamed D3 to SRD on new A3/B3 parts

Hi all,

This issue really affects the PACs but I expect it will have an impact on the HAL, and the HAL developers are probably in a good position to comment on it, so I thought I'd ask here first.

It's been pointed out that ST have started calling "SmartRun", "SmartRun Domain", and "SRD" what used to be called "D3". Our SVDs for the A3/B3/B0 parts use "D3", for example in PWR:CPUCR:RUN_D3 which is now called RUN_SRD in the reference manual. It seems like the older H7 parts are not renamed (yet?).

What do you think we should do about it? Options seemingly include:

  • Do nothing, keep D3, which maintains easier compatibility with other H7 parts for clock and memory setup, but disagrees with the reference manual
  • Rename D3 to SRD in the SVDs, so HAL and user code will have to handle these devices separately
  • Other?

I assume future H7 devices will use the new names, which might suggest we stick to the reference manuals and at some point have to rename the current SVDs.

Type-erased GPIO pin modes

I have a number of drivers where I need to change the mode of a GPIO pin during normal operation. However the type-state GPIO design makes this very annoying. For example:

enum ReadyPin {
    PullDown(gpioe::PE1<Input<PullDown>>),
    PullUp(gpioe::PE1<Input<PullUp>>),
}

pub struct Outgoing {
    i2c: i2c::I2c<pac::I2C1>,
    ready: ReadyPin,
    _aux: gpioe::PE0<Analog>,
}

I just want to store the pin in the driver struct but it's hard because its type changes all the time. I want to enable and disable interrupt generation on the pin but now I have to match every time I want to access the pin even though nothing changes but the type. It would be nice to have a GPIO pin type which erases the MODE type.

I'm also questioning the value of the MODE type-state altogether.

In user code the gpio pin is probably wrapped up in a driver which implements the desired behavior. Drivers in my experience either:

  1. Are built on top of embedded-hal, which doesn't care about our MODE types at all.
  2. Are built for a specific board which will use specific pins for specific peripherals. I found in this case it's cleaner to have your drivers just take Analog pins and do the configuration themselves to remove that pin-configuring clutter from main() and into the code that cares about it.

Am I missing something that these types help in user code?

I could only find one place in the HAL that actually used a mode type for anything. internal_pull_up(&mut self, bool) is only implemented for Output<OpenDrain> and Alternate<MODE>. I don't think it's particularly important that the type system prevents you from calling it on a push-pull output. All of the peripherals take Alternate<> pins which already erases the PushPull/OpenDrain and PullUp/PullDown/Floating types. Perhaps there are cases where the AF* typestates disambiguate things so those could be kept? If not, just have the peripherals do the pin configuration themselves and save us the trouble.

I don't have much hope that this will happen. It would be a huge breaking change in the HAL and a huge break with the other STM32 HALs, so I'll settle for adding a type-erased GPIO pin. With all the 1.0 discussions happening though, maybe I should make a last-chance push to remove the needless (?) complexity.

[Bug] ADC initialization might panic

Description and Reproduction

Currently, the ADC initialization might panic if following happens:

  • Watchdog enabled
  • ADC initialized and enabled
  • Panic occurs, causing watchdog to restart the software
  • ADC initialized again (and thus calibrated) -> fails because:
    • Reset isn't being triggered because the clock of the ADC is still running (see adc.rs, line 283)
    • Therefore, ADC is still enabled
      -> ADC calibration will panic

Possible fix

Upon initialization, check if ADC is enabled and disable it then.

UART bug

In a mail by @eeboo he brought up the following repository: https://github.com/eeboo/stm32h743zi-test/

In there you will find two examples, one tagged ok, the other tagged ko. The ko example is producing garbage on his logic analyzer.
As one can see in his example code the only difference is:

// Acquire the GPIOD peripheral. This also enables the clock for
    // GPIOD in the RCC register.
    let gpiod = dp.GPIOD.split(ccdr.peripheral.GPIOD);

    let tx = gpiod.pd8.into_alternate_af7();
    let rx = gpiod.pd9.into_alternate_af7();


    // Configure the serial peripheral.
    let serial = dp
        .USART3
        .usart(
            (tx, rx),
            serial::config::Config::default(),
            ccdr.peripheral.USART3,
            &ccdr.clocks,
        )
        .unwrap();

in the Ok example, vs

    let gpiob = dp.GPIOB.split(ccdr.peripheral.GPIOB);

    let tx = gpiob.pb9.into_alternate_af8();
    let rx = gpiob.pb8.into_alternate_af8();


    // Configure the serial peripheral.
    let mut serial = dp
        .UART4
        .usart(
            (tx, rx),
            serial::config::Config::default(),
            ccdr.peripheral.UART4,
            &ccdr.clocks,
        )
        .unwrap();

in the not working example. (and only now am I realizing that in my response I actually misread, its not pd8 being used for both but pb8 for the not working one)

We should definitely investigate on this.

[RFC] Erase pin types from HAL driver types

When implementing an application using RTFM and storing peripheral resources in the Resource structure, the type of the peripheral can be quite onerous to carry around as it contains generic parameters for the pins and peripheral instance.

Example:

let spi = hal::spi::Spi1::new(dp.SP2, (sck, miso, mosi), ...);

The spi variable has the following type:

hal::spi::Spi<
    hal::stm32::SPI2, (
        hal::gpio::gpiob::PB10<hal::gpio::Alternate<hal::gpio::AF5>>, 
        hal::gpio::gpiob::PB14<hal::gpio::Alternate<hal::gpio::AF5>>,
        hal::spi::NoMosi)
>

This type then changes based on which pins are used. This type is also required to be specified in the RTFM resource structure declaration, which results in a (fairly messy) structure definition that's non-intuitive.

Because the pin types are used only as a compile-time guarantee that they implement the necessary SPI alternate functions, I don't believe there's a need for the SPI module to carry around this type information after instantiation (although the SPI peripheral needs to maintain ownership of the pins).

I propose that we update the SPI constructor to downgrade the pins to a generic "pin" type since they are never directly controlled by the SPI peripheral. This would remove pin types from the type signature and simplify it to something like hal::spi::Spi<hal::stm32::SPI2>, which is much more manageable (and we could potentially remove the SPI2 type as well with other work, although that's beyond scope here).

No QSPI support for memories

Some of the features that would be required to communicate with memories over QSPI (instructions, dummy cycles..) are not supported

QSPI reads unstable

Due to a likely silicon bug, the QSPI peripheral (reference quartiq/stabilizer#101), QSPI reads may be incorrect when reading at the rising clock edge.

To work around this, the QSPI peripheral can be updated to read on the falling clock edge instead by setting the SSHIFT bit:
image

embedded hal digital IO v2

The embedded hal group marked the v1 of digital IO as deprecated, should we also implement a v2 version for the future already?

[Proposal] Add pwm features for power electronics

I'm working on a project using the STM32H750 for power electronics applications. I need several features of the chip that are beyond the simple interface of embedded-hal, but I'd like to do this in a way that is still compatible with the embedded-hal traits and is as generally useful as possible.

I'm an experienced embedded C developer but relatively new to Rust, especially trait/generic based libraries and macros. I'm looking for feedback on what features should be included and how they should be exposed to the user.

Here's the features I want to add:

  • Center-aligned PWM
  • PWM break input pins for overcurrent faults
  • Complementary PWM outputs with dead time

Center-aligned PWM is a different counter mode that can be set up on initialization of timers 1,2,3,4,5,8. It can be easily set up at timer initialization and ignored while running.

PWM fault input pins, complementary outputs, and dead time are all supported only on timers that have the BDTR register: timers 1,8,15,16,17. All channels use the same dead time, so I envision that being configured at timer initialization. I think it would make sense to initialize channels as standard/positive polarity and add a .into_complementary_output(complementary_pin) function that changes the PWM mode from single ended to complementary.

For the break inputs, the hardware is very flexible and configurable. I would like to use the break input functionality to turn off PWM when the break input pin goes low and not turn it back on until a function is called to clear the fault. I would like to do this by returning a separate struct that implements a trait with functions fault_active() -> bool and clear_fault(). The individual PWM channels would be completely unaware of the fault functionality: they would continue to set duty cycle, enable, or disable normally and the output would just stay inactive until a fault was cleared.

I'm thinking about two different APIs for this:

Separate functions, like this:
TIM1.pwm(pins, freq, prec, clocks) -> (channels)
TIM1.pwm_center(pins, freq, prec, clocks) -> (channels)
TIM1.pwm_deadtime(pins, freq, prec, clocks, deadtime) -> (channels)
TIM1.pwm_fault_deadtime(pins, freq, prec, clocks, fault_pin, fault_state, deadtime) -> (fault_monitor, channels)
TIM1.pwm_center_fault_deadtime(pins, freq, prec, clocks, fault_pin, fault_state, deadtime) -> (fault_monitor, channels)

Then channels could be adjusted like this:
channel.set_active_level( ActiveHigh or ActiveLow )
channel.set_fault_level( ActiveHigh or ActiveLow )
let channel = channel.into_complementary_pwm( complementary_pin, complementary_active_state, complementary_fault_state )

Or I could make a builder style API, something like this (with the same methods to adjust an individual channel mode):

TIM1.pwm(pins, freq, prec, clocks).center_aligned(),deadtime(500.ns()).fault( fault_pin, fault_state, complementary_fault_state ).freeze() -> (fault_monitor, channels)

The downside is that breaks existing code using TIM1.pwm(), so I could keep TIM1.pwm() as is and add TIM1.advanced_pwm() for the builder.

Does anybody have an opinion on whether I should implement the first API, the second API, or something else? And are there other PWM related functions people would like to see or other places I should make this more flexible for others?

Implementing peripherals which arent in embedded hal yet

If somebody was to use this project as a basis for peripherals which aren't defined (and maybe never will be because they are too specific to this or the stm32 series) he would probably fail at the simple fact that he cannot use the RCC registers (rb) in the Ccdr at the moment. Is there any workaround to this which comes to mind (apart from the two obvious ones, setting the RCC from pub (crate) to pub or just PRing it in, which brings up the question, are peripherals which aren't defined in embedded hal supposed to live here as well?)

Ethernet

  • ETH_MACMIIAR_CR is only valid for HCLK 150-250 MHz
  • MDIO interface only supports PHYs with address 0 - #130
  • Add documentation explaining how to use PHY feature flags - #130
  • Add ethernet to CI - #130

See also #121

ResetEnable trait methods require ownership

The ResetEnable trait is implemented for Peripheral Reset Enable Control (PREC) ZSTs. However, its methods require self, so it cannot be used when we only have a &mut- reference to the PREC.

Proposal:

Change the ResetEnable trait to implement these methods for &mut self instead.

Advantages:

  • Usability, see #116

Downsides:

  • Allows the PREC to be reset/enabled when we only hold a &mut- reference to it. Currently if the PREC is part of a struct, we can be sure the peripheral will not be reset / disabled until that struct's destructor.

PWR needs to be updated to support vos0 (480Mhz).

Looking at how VOS0 scaling needs to be implemented the current structure is going to need to be broken a bit I opted to create a new freeze_vos0 function to not break all the existing code.

RM0433 rev 7

VOS0 activation/deactivation sequence
The system maximum frequency can be reached by boosting the voltage scaling level to
VOS0. This is done through the ODEN bit in the SYSCFG_PWRCR register.
The sequence to activate the VOS0 is the following:

Ensure that the system voltage scaling is set to VOS1 by checking the VOS bits in
PWR D3 domain control register (PWR D3 domain control register (PWR_D3CR))

Enable the SYSCFG clock in the RCC by setting the SYSCFGEN bit in the
RCC_APB4ENR register.

Enable the ODEN bit in the SYSCFG_PWRCR register.

Wait for VOSRDY to be set.
Once the VCORE supply has reached the required level, the system frequency can be
increased. Figure 31 shows the recommended sequence for switching VCORE from VOS1 to
VOS0 sequence.

Setup PWR...
Setup RCC...

stm32h7xx-hal example - RCC

hclk = 240 MHz
sys_ck = 480 MHz

#96

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.