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

Multiple improvements for stm32wle targets #2309

Merged
merged 1 commit into from
Nov 26, 2021

Conversation

ofauchon
Copy link
Contributor

This PR provide multiple improvements for STM32WLE5 targets:

  • board/stm32: Add STM32 Nucleo WL55JC board
  • board/lorae5,nucleo-wl55jc: Add SubGhz SPI3 interface
  • stm32/stm32wl: Set 48Mhz HSE32/PLL as default Clock, SubGhz Radio device init

Copy link
Member

@kenbell kenbell left a comment

Choose a reason for hiding this comment

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

Thanks for improving the support - suggest just a small amount of replacing magic values with symbolics (where possible) - and needs some thought about how (and when) to initialize the radio peripheral.

Also - looks like a change may be missing based on the compile errors?

README.md Show resolved Hide resolved
func initCLK() {

// Set Power Voltage Regulator Range 2
//stm32.PWR.CR1.ReplaceBits(0b10, stm32.PWR_CR1_VOS_Msk, stm32.PWR_CR1_VOS_Pos)
Copy link
Member

Choose a reason for hiding this comment

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

Should either un-comment, or completely remove

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed

}

// Set Flash Latency of 2 and wait until it's set properly
stm32.FLASH.ACR.ReplaceBits(0b010, 0b111, stm32.Flash_ACR_LATENCY_Pos)
Copy link
Member

Choose a reason for hiding this comment

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

Can use symbolic constants for these values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All binaries replaced with symbolic constants.

}

// Configure PLL
stm32.RCC.PLLCFGR.Set(0x23020613)
Copy link
Member

Choose a reason for hiding this comment

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

Can use symbolic constants here? E.g. other STM32 worked on recently tend to have something like this:

	// Configure the PLL
	stm32.RCC.PLLCFGR.ReplaceBits(
		(1)| // 1 = RCC_PLLSOURCE_MSI
			(PLL_M-1)<<stm32.RCC_PLLCFGR_PLLM_Pos|
			(PLL_N<<stm32.RCC_PLLCFGR_PLLN_Pos)|
			(((PLL_Q>>1)-1)<<stm32.RCC_PLLCFGR_PLLQ_Pos)|
			(((PLL_R>>1)-1)<<stm32.RCC_PLLCFGR_PLLR_Pos)|
			(PLL_P<<stm32.RCC_PLLCFGR_PLLPDIV_Pos),
		stm32.RCC_PLLCFGR_PLLSRC_Msk|stm32.RCC_PLLCFGR_PLLM_Msk|
			stm32.RCC_PLLCFGR_PLLN_Msk|stm32.RCC_PLLCFGR_PLLP_Msk|
			stm32.RCC_PLLCFGR_PLLR_Msk|stm32.RCC_PLLCFGR_PLLPDIV_Msk,
		0)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could rewrite the PLL init with symbolic constants . Done


}

// SubGhzInit() enables SX126x radio module
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 think this should be in the runtime package - runtime is really about setting up clocks and time.

Should probably think about this as an optional peripheral that apps may (or may not) use - with it either:
1 - being in machine package
2 - being supported in the tinygo drivers repo

I'm not sure which is best - it's not a SPI/I2C peripheral - and might be a bit 'specialized' for the machine package? Perhaps @aykevl or @deadprogram have some thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SX126x Radio (which is part of STM32WL) will have its own tinygo driver soon, so the code can be reused when using SX126x standalone module.

But this function is specific to STM32WL series (as SX126x radio unit and MCU are on the same die)

IMHO it's entirely part of the whole chipset initialisation process.

I'm not sure moving this function to tinygo-driver makes sense (I don't see other situations you might need this)

But having it in machine package instead, would not hurt.

Other comments welcome .

Copy link
Member

Choose a reason for hiding this comment

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

machine package is a good place for this. Perhaps it should be exported so users who want to turn on this functionality can do so, but it is not always turned on by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SubGhzInit function moved in "src/machine/machine_stm32wle5.go" and exported so users can use it or not

@deadprogram
Copy link
Member

Once you have updated from any changes from feedback, @ofauchon can you please rebase against the latest dev branch? Hopefully that will get CI to build successfully.


// UART init
machine.Serial.Configure(machine.UARTConfig{})

// Timers init
initTickTimer(&machine.TIM1)

// Radio init
subGhzInit()
Copy link
Member

Choose a reason for hiding this comment

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

CI is now passing @ofauchon will you move subGhzInit() to machine package now, change to SubGhzInit(), and remove this call here so initialization is optional to the developer? 😸

@ofauchon ofauchon force-pushed the stm32wl-pllclock-spi-subghz branch 2 times, most recently from eebf58c to b4ec351 Compare November 25, 2021 10:19
@ofauchon
Copy link
Contributor Author

@deadprogram @aykevl @kenbell .
I made all the suggested changes.

The final PR Code was tested on both LoraE5 and nucleo-wl55jc:

  • Simple timers tests OK ,
  • UART OK,
  • Radio module SX126x simple tests (Continuous TX checked with a SDR)

Olivier

@ofauchon ofauchon force-pushed the stm32wl-pllclock-spi-subghz branch 3 times, most recently from 66beb62 to 3928d7e Compare November 25, 2021 14:02
Copy link
Member

@aykevl aykevl left a comment

Choose a reason for hiding this comment

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

Generally looks good to me.
I'm a little bit unsure about the SubGhzInit function. IIRC it's on the same chip, but connected through an (on-chip) SPI bus?
I'm almost inclined to say it should be implemented entirely in a driver package, not in the machine package. Not sure. On the other hand, it does need some special initialization so it's not just any other SPI peripheral.

Comment on lines +12 to +13
// We assume a LED is connected on PB5
LED = PB5 // Default LED
Copy link
Member

Choose a reason for hiding this comment

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

It looks like this change is unrelated to the PR. Was it intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This board don't actually have a LED.
So I thought I would be a good idea to remove it.

But, that breaks blinky1 , so I rolled-back the change.

Copy link
Member

Choose a reason for hiding this comment

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

FWIW in the LoRa-e5 schematic, PB5 is connected to a RED LED through a jumper (see bottom right of the schematic): https://files.seeedstudio.com/products/113990934/LoRa-E5%20Dev%20Board%20v1.0.pdf

It certainly blinked the LED for me :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

image

I understand why i've never seen this led blinking and why I connected an external LED (hopefully on PB5)

Copy link
Member

Choose a reason for hiding this comment

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

:-) the official dev board does look a little less artisanal.

Comment on lines +249 to +257
switch spi.Bus {
case stm32.SPI1:
clock = CPUFrequency()
case stm32.SPI2, stm32.SPI3:
clock = CPUFrequency()
}
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 understand this part. In all cases the clock equals the CPU frequency? Why not write clock := CPUFrequency() instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIRC, this code was (quickly) borrowed from STM32F405

I guess the lines are the same because the both SPI1 and SPI2/SPI3 's bus use a 1:1 Prescaler.
(in the current STM32WL setup)

In the future, we may improve / tune the clocks, and the lines may turn into :

	switch spi.Bus {
	case stm32.SPI1:
		clock = CPUFrequency() /2 
	case stm32.SPI2, stm32.SPI3:
		clock = CPUFrequency() /4
	}

So we have two solutions:

  • Add comments to explain the PRESCALERs are 1:1 in the current configuration
  • Review and complete the work on SYSCLK/BUS/SPI clocks , prescalers... but that will take time

As I plan to work on Power Saving for this chip in a near future,
i'd prefer not spending too much time on the clocks right now, and juste add
some comment.

Tell me what you feel the most confortable with .

Olivier

Copy link
Member

Choose a reason for hiding this comment

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

Add comment about keeping separate to support future improvements, and IMO its all good.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the comment.
Thank you all for the time spend on this PR !

@ofauchon
Copy link
Contributor Author

Generally looks good to me. I'm a little bit unsure about the SubGhzInit function. IIRC it's on the same chip, but connected through an (on-chip) SPI bus? I'm almost inclined to say it should be implemented entirely in a driver package, not in the machine package. Not sure. On the other hand, it does need some special initialization so it's not just any other SPI peripheral.

Yes, SPI3/SubGhz Is an internal SPI bus dedicated to SX126X Radio Submodule communication.

I agree this SubGhzInit is not ideal it looks like an ugly quirk in machine code.

I'll remove this function for the moment, and try to implement this in the tinygo-driver.

- board/stm32: Add STM32 Nucleo WL55JC board
- stm32/stm32wl: Set 48Mhz HSE32/PLL as default Clock, SPI implementation
@deadprogram
Copy link
Member

Thanks for responding to all the feedback @ofauchon

Now merging.

@deadprogram deadprogram merged commit b0fce80 into tinygo-org:dev Nov 26, 2021
@ofauchon ofauchon deleted the stm32wl-pllclock-spi-subghz branch November 26, 2021 13:45
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