Skip to content

machine/rp2040: add PWM implementation #2015

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

Merged
merged 2 commits into from
Sep 1, 2021

Conversation

soypat
Copy link
Contributor

@soypat soypat commented Jul 25, 2021

Please take a look. Tested and works with on-board LED and GPIO5. Solves #1993 .

@soypat
Copy link
Contributor Author

soypat commented Jul 25, 2021

Tests have failed probably because two functions are missing: boolToBit and umax32 which are due to be added with #2013. Below is an example of usage (PWM blinky)

PWM Blinky Example
package main

import (
	"machine"
	"time"
)

var (
	LED  = machine.GPIO25
	pin2 = machine.GPIO26
	uart = machine.UART0
)

func main() {
	// configure UART to print stuff
	{
		err := uart.Configure(machine.UARTConfig{BaudRate: 9600})
		if err != nil {
			panic(err)
		}
	}

	pin := LED

	pin.Configure(machine.PinConfig{Mode: machine.PinPWM})
	pwm, err := machine.NewPWM(pin)
	if err != nil {
		println(err.Error())
	}
	var per uint64 = 1e9 / 500
	err = pwm.Configure(machine.PWMConfig{Period: per})
	if err != nil {
		println(err.Error())
	}
	ch, err := pwm.Channel(pin)
	if err != nil {
		println(err.Error())
	}
	println("slice", pwm.Peripheral(pin), " ch:", ch)
	if !pwm.IsEnabled() {
		println("NOT ENABLED")
	}
	println("period:", pwm.Period(), "target_period:", per)
	time.Sleep(time.Millisecond)

	for {

		for i := 1; i < 255; i++ {
			pwm.Set(ch, pwm.Top()/uint32(i))
			time.Sleep(time.Millisecond * 5)
		}
	}

}

@soypat soypat marked this pull request as draft August 1, 2021 21:57
@deadprogram
Copy link
Member

Ready for resolve of merge conflicts, please. 😸

@soypat
Copy link
Contributor Author

soypat commented Aug 7, 2021

@deadprogram Done dealio

@soypat soypat marked this pull request as ready for review August 7, 2021 20:44
@soypat
Copy link
Contributor Author

soypat commented Aug 7, 2021

Hello @deadprogram, seems like I used the wrong function name for u32max. Should be fixed by now.

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.

It appears that the PWM of the RP2040 is structured a little bit differently than other chips: it groups all PWM timers into one peripheral. Most chips have multiple PWMs where each PWM instance has just one timer. However, if you look closely you can see that it is actually not that different: it's as if the RP2040 has 8 PWM peripherals that each have two channel outputs. Therefore, I would suggest exposing it like that:

var (
    PWM0 = ...
    PWM1 = ...
    PWM2 = ...
    // etc
}

In this API, you can use the PWM like this:

pwm := machine.PWM0
pwm.Configure(...)        // enables the given PWM
ch, _ := pwm.Channel(pin) // configures the pin
ch.Set(ch, value)         // set the channel value

I understand the need for a NewPWM, and I agree we should have something like that (also for other chips). However, there is one big catch: it's not clear which PWMs alias each other. For example, if you set the frequency for pin 2, it will also change the frequency for pin 3, 18, and 19. This is in fact one of the main reasons of the somewhat complex API. That's why I would suggest leaving it out for now.

(Also, I think the name NewPWM is misleading as the function doesn't create anything new: PWM resources are fixed hardware resources and can't be made on the fly).

targetPeriod := uint32(period)
periodPerCycle := getPeriod()
top := pwm.getWrap(sliceNum)
phc := pwm.getPhaseCorrect(sliceNum)
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, phase correct PWM isn't supported so I would suggest not taking this into account.
(I believe phase correct PWM is only relevant for specific motor control applications)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you mean I should leave it commented out as a TODO for when phase correct is added, if ever?

@soypat
Copy link
Contributor Author

soypat commented Aug 11, 2021

@aykevl I've applied sweeping changes inspired by your comments. There may be more use of unsafe but I think this is much cleaner. Let me know what you think!

@deadprogram
Copy link
Member

CI tests are failing, and there is a merge conflict. Can you please look at that @soypat thank you!

@soypat
Copy link
Contributor Author

soypat commented Aug 11, 2021

I changed a method to a function. One can obtain the peripheral number with machine.PWMPeripheral. I think it makes more sense than having it as a method.

@deadprogram
Copy link
Member

Was not able to get working with the PWM example in the main TinyGo examples. Some mappings are missing, and I might not have them correct for the Pico board.

add documentation

rp2040 pwm fixes and functionality added

machine/rp2040: add PWM implementation
@soypat
Copy link
Contributor Author

soypat commented Aug 17, 2021

@deadprogram I had to add a pin.Configure call inside pwm.Channel for the API to be the same as other implementations. I have tested it and it works with the on-board LED on the pico (which I added to the examples/pwm files.

soypat added a commit to soypat/tinygo-site that referenced this pull request Aug 18, 2021
Next release of TinyGo should have support for I2C+SPI+PWM.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
PWM would be supported as soon as tinygo-org/tinygo#2015 is merged.

Added some pointers on how to debug/get USB output using picoprobe.
@deadprogram
Copy link
Member

Tested and is now working as expected. Squashing/merging now, thanks for working on this @soypat

@deadprogram deadprogram merged commit a7c53cc into tinygo-org:dev Sep 1, 2021
ysoldak added a commit to ysoldak/tinygo that referenced this pull request Sep 4, 2021
* 'dev' of github.com:tinygo-org/tinygo:
  src/runtime: reset heapptr to heapStart after preinit()
  docker: use go 1.17 for docker dev build
  machine/feather-rp2040: add pin name definition for feather
  targets: add openocd configuration for rp2040
  Implement os.Executable
  board/nano-rp2040: define NINA_SPI and fix wifinina pins
  machine/rp2040: add PWM implementation (tinygo-org#2015)
deadprogram pushed a commit to tinygo-org/tinygo-site that referenced this pull request Sep 19, 2021
Next release of TinyGo should have support for I2C+SPI+PWM.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
PWM would be supported as soon as tinygo-org/tinygo#2015 is merged.

Added some pointers on how to debug/get USB output using picoprobe.
deadprogram pushed a commit to tinygo-org/tinygo-site that referenced this pull request Sep 19, 2021
Next release of TinyGo should have support for I2C+SPI+PWM.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
PWM would be supported as soon as tinygo-org/tinygo#2015 is merged.

Added some pointers on how to debug/get USB output using picoprobe.
deadprogram pushed a commit to tinygo-org/tinygo-site that referenced this pull request Sep 19, 2021
Next release of TinyGo should have support for I2C+SPI+PWM.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
PWM would be supported as soon as tinygo-org/tinygo#2015 is merged.

Added some pointers on how to debug/get USB output using picoprobe.
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