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

Adding VCOM GPIO and USART pin exmple for the stm32l479disco board #30

Merged
merged 2 commits into from
Jan 24, 2019

Conversation

mathk
Copy link
Contributor

@mathk mathk commented Jan 14, 2019

VCOM is working as expected. No framing error.

@mathk mathk force-pushed the master branch 2 times, most recently from b76d1e8 to 0750519 Compare January 14, 2019 22:57
@mathk
Copy link
Contributor Author

mathk commented Jan 14, 2019

I fixed my mistake on the alternate function register for GPIOE

src/serial.rs Outdated Show resolved Hide resolved
@mathk
Copy link
Contributor Author

mathk commented Jan 15, 2019

Recent rcc change need a recent version of stm32l4. I have a PR for the stm32l4x6: stm32-rs/stm32-rs#141

@mathk
Copy link
Contributor Author

mathk commented Jan 16, 2019

I have fix also the clock requirement to select the correct one on chip that does not have HSI48
My other PR on stm32-rs/stm32-rs is now a requirement.

@mathk mathk force-pushed the master branch 3 times, most recently from 373b992 to 1e227e3 Compare January 16, 2019 09:56
@MabezDev
Copy link
Member

Can you link me to the board you are using, I can only find a STM32L476 not stm32l479 board?

Copy link
Member

@MabezDev MabezDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work so far, could you take a look at the review notes and see what you think?

@@ -52,6 +52,7 @@ stm32l4x2 = ["stm32l4/stm32l4x2"]
stm32l4x3 = ["stm32l4/stm32l4x3"]
stm32l4x5 = ["stm32l4/stm32l4x5"]
stm32l4x6 = ["stm32l4/stm32l4x6"]
stm32l47x = ["stm32l4x6"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the moment there aren't any plans to support boards by themselves

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I should add, mainly because it's quite time consuming to get everything behind a feature gate. If you could get some more stuff behind feature gates for your board (usarts, gpio etc), I would definitely be interested in having your board as the first one! :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok the idea here is not board specific. The stm32l476 and stm32l475 does not have the HSI48 clock. Looking a the datasheet the HSI48 clock seems to be mainly for the USB, RNG, ... clock source. So Mi idea was to abstract this mater of fact so that we chose the best clock source depending on the MCU capability.

src/rcc.rs Outdated
@@ -15,6 +15,8 @@ pub trait RccExt {
}

impl RccExt for RCC {

#[cfg(not(feature = "stm32l47x"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to only feature gate specific fields, instead of the whole RccExt impl.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

crrcr does not exit for stm3247x how do you see implementation of the constrain ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using #[cfg(not(feature = "stm32l47x"))] on the fields instead of the entire impl, e.g

    fn constrain(self) -> Rcc {
        Rcc {
            ahb1: AHB1 { _0: () },
            ahb2: AHB2 { _0: () },
            ahb3: AHB3 { _0: () },
            apb1r1: APB1R1 { _0: () },
            apb1r2: APB1R2 { _0: () },
            apb2: APB2 { _0: () },
            bdcr: BDCR { _0: () },
            csr: CSR { _0: () },
            #[cfg(not(feature = "stm32l47x"))]
            crrcr: CRRCR { _0: () },
            cfgr: CFGR {
                hclk: None,
                usb48: false,
                lsi: false,
                pclk1: None,
                pclk2: None,
                sysclk: None,
                pllcfg: None,
            },
        }
    }

src/rcc.rs Outdated
@@ -28,7 +30,31 @@ impl RccExt for RCC {
crrcr: CRRCR { _0: () },
cfgr: CFGR {
hclk: None,
hsi48: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HSI48, should stay as it is a valid clock for other L4 chips, and calling it usb48 doesnt quite fit in my mind as it can be used for rng, sdio etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about naming it clk48 ? The idea here is that some MCU does not have the HSI48 clock. A more generic naming would allow use to have the same user code and be able to run it on different L4 MCU.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not that HSI48 is used only for USB, RNG SDMMC clock or MCO output. It look to me that it has been design for USB,RNG SDMMC purose in mind.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like the idea of treating hsi48 and msi as one 48mhz field, I think the clocks returned from the rcc should be as close to what the hardware is as possible, and then it should be left up to the peripherals to check it either has hsi48 or msi or pll etc when initializing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, so to me there is input clock and output clock. Maybe the idea is to configure a pair of clock:

(in, out, [scale]) ?

may be for now I will just feature gate the HSI48 and add the MSI clock.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may be for now I will just feature gate the HSI48 and add the MSI clock.

That sounds good to me :).

src/rcc.rs Outdated
// p. 180 in ref-manual
rcc.crrcr.modify(|_, w| w.hsi48on().set_bit());
// Wait until HSI48 is running
while rcc.crrcr.read().hsi48rdy().bit_is_clear() {}
}



if cfg!(feature = "stm32l47x") && self.usb48 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So for MSI selection, I was thinking about maybe an Enum that has all possible pre configurable speeds, or taking the speed from an Into<Hertz> value, this would allow future users to use the MSI easily.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that would be intresting to have it. We need to solve how to enforce 48Mh if MSI is selected for the USB, RNG and SDMMC clock source. The enum seems a better choise as there is a fix set of speed that can be selected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think your right, the enum method makes sense. Using the enum allows peripherals easily to check what speed the MSI is running at.

src/serial.rs Outdated
@@ -181,7 +184,9 @@ macro_rules! hal {
// NOTE(unsafe) atomic read with no side effects
let isr = unsafe { (*$USARTX::ptr()).isr.read() };

Err(if isr.pe().bit_is_set() {
Err(if isr.rtof().bit_is_set() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I notice this error has been added, for time out detection, but I don't see any code that configures the relevant registers? Could you explain what this does and how it fixes the framing error issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No actually this was an attempt to solve framing error but it seems not link to that change. I can either add the timeout support or remove this branch. Let me know. BTW I didn't saw framing error happening so far.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As were not really sure what it does, I think its best to remove it. We can always add it back later if its required :).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap reverted

src/rcc.rs Outdated
@@ -28,7 +30,31 @@ impl RccExt for RCC {
crrcr: CRRCR { _0: () },
cfgr: CFGR {
hclk: None,
hsi48: false,
usb48: false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would renaming usb48 to usbRngSDMMC48 be better ? As this is that same clock line?
clocktree

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think my other comments address this.

@mathk
Copy link
Contributor Author

mathk commented Jan 23, 2019

@MabezDev I have address your comment let me know if you need some change.

src/rcc.rs Outdated
hsi48: bool,
msi: MsiFreq,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we have Option instead? That way we can remove the need for a NOMSI variant

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

@MabezDev MabezDev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is coming along nicely, I think we're nearly there.

src/rcc.rs Outdated
RANGE32M = 10,
#[doc = "range 11 around 48 MHz"]
RANGE48M = 11,
#[doc = "no msi selected"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove after changing to Option in Clocks

src/rcc.rs Outdated
@@ -456,27 +503,73 @@ impl CFGR {
while rcc.csr.read().lsirdy().bit_is_clear() {}
}

// Turn on HSI48 if required
if self.hsi48 {
if self.msi != MsiFreq::NOMSI {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the enum is changed, if self.msi is not None we can just write the enum as a u8 to the register

pub fn freeze(self, acr: &mut ACR) -> Clocks {

let (hclk, pclk1, pclk2, ppre1, ppre2, sysclk) = self.common_freeze(acr);
let mut usb_rng = false;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I right in saying these extra freeze function just set usb_rng? If so what is useful about knowing usb_rng is enabled? I think most peripherals need to know what is providing the clock, so it can set its source appropriately.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No the both freeze set the usb_rng boolean. The idea here is because of the RNG. The Rng need a clock source at 48Mhz (proven by stm to work correctly) (usb and rng clock share the same line IIUC). But on some mcu you do have HSI48 that once enable will clock the rng source by default. On the other hand if you do not have HSI48 you can always back to the PLL48 clock source or the MSI possibly other clock source but that need to respect the 48Mhs constrain. So I can only enable the usb_rng with MSI (clk48sel register) if the MSI is 48Mhz.

To conclude I need to feature gate this 2 branch in separate freeze as it have to take 2 different decision depending on the HSI48 being available or not.

@MabezDev MabezDev merged commit a72e4c5 into stm32-rs:master Jan 24, 2019
@MabezDev
Copy link
Member

Looks good, thanks for your contribution :)

@nickray
Copy link
Member

nickray commented Feb 1, 2019

I'm sorry, I missed this activity. Some late comments:

  • Why is common_freeze public? Doesn't seem like it should be in the public API.
  • The duplicated flag usb_rng feels wrong. RngExt should know what clock to check depending on the device. Whereas Clocks in my opinion should have actual clocks.
  • Generally there seems a bit too much if/then and not enough types.
  • Leftover check for !cfg!(feature = "stm32l47x") in the "first" freeze.

Generally, reconsidering whether mixing L4x2 and L47x (aka L4x6?) is a good idea:

  • aggressively feature-flagging is not much different to a C-style #ifdef maze
  • leaving in all possible peripherals makes the API confusing for the user of a specific device

A more specific case in point:

  • RM0394 covers 412, 422, 431, 432, 433, 442, 443, 451, 452, 462
  • RM0351 separately covers 475, 476, 486, 496, 4A6
  • RM0392 has 471

What are the other options?

  • a magic macro? Hard to write, harder to debug
  • a HAL generator, somewhat similar to svd2rust/stm32-rs, that emits actual, minimal HALs for each specific device?

Thoughts?

MabezDev added a commit that referenced this pull request Feb 1, 2019
@mathk
Copy link
Contributor Author

mathk commented Feb 3, 2019

@nickray usb_rng is not a duplicate flags. The clock line is independent from msi or hs48.

@mathk
Copy link
Contributor Author

mathk commented Feb 3, 2019

If you check the reference manual this is all about whether HSI48 is available or not. only 476 475 471 does not posses this clock

MabezDev added a commit that referenced this pull request Feb 8, 2019
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.

3 participants