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

Unable to Use PWM & GPIO.PULSE Concurrently #2494

Closed
jmd13391 opened this issue Sep 20, 2018 · 10 comments
Closed

Unable to Use PWM & GPIO.PULSE Concurrently #2494

jmd13391 opened this issue Sep 20, 2018 · 10 comments

Comments

@jmd13391
Copy link

jmd13391 commented Sep 20, 2018

Expected behavior

Use PWM and GPIO.PULSE modules concurrently.

Actual behavior

Coding for both (first PWM then GPIO.PULSE) causes PWM output to stop (output remains HIGH), GPIO.PULSE output works as expected.

Test code

gpio.mode(1, gpio.OUTPUT)  -- D01:GPIO05 PWM Stream 1
pwm.setup(1, 100, 512)  -- PWM Stream 1 - 100Hz, 50% Duty Cycle
pwm.start(1)  -- Start PWM Stream 1

gpio.mode(11, gpio.OUTPUT)  -- D11:GPIO09 Pulse 1
gpio.mode(12, gpio.OUTPUT)  -- D12:GPIO10 Pulse 2

-- Pulse two square waves [just about] forever
-- Frequency of each square wave is ~4.5Khz.
-- Square waves are 180° out of phase with a 10uS state change delay.
-- delay=(90+10) [100uS] + delay=(90+10) [100uS] = .0002 sec
-- count=-1 is treated as an unsigned 32 bit integer with a value of 2^32
-- Total loop duration is ~117 million years (.0002 sec * 2^32 [L1] * 2^32 [L2])

pulser = gpio.pulse.build( {
  { [11] = gpio.HIGH, [12] = gpio.LOW, delay=90 },
  { [11] = gpio.LOW, [12] = gpio.LOW, delay=10 },
  { [11] = gpio.LOW, [12] = gpio.HIGH, delay=90 },
  { [11] = gpio.LOW, [12] = gpio.LOW, delay=10 },
  { loop=1, count=-1 }, { loop=1, count=-1 }
})

pulser:start(function() end)

NodeMCU version

NodeMCU 2.2.0.0 built with Docker provided by frightanic.com
branch: master
commit: 3661b8d
SSL: false
Build type: float
LFS: disabled
modules: adc,bit,file,gpio,gpio_pulse,i2c,net,node,pwm,rtctime,tmr,uart,websocket,wifi
build created on 2018-09-20 09:40
powered by Lua 5.1.4 on SDK 2.2.1(6ab97e9)

Hardware

Amica / AI-Thinker ESP8266 ESP-12E Development Board

Attachments

PWM1 Code Only - PWM1 Output:
pwm1_code_only-pwm1

PULSE Code Only - PULSE1 Output:
pulse1_code_only-pulse1

PWM+PULSE Code - PWM1 Output:
pwm pulse_code-pwm1

PWM+PULSE Code - PULSE1 Output:
pwm pulse_code-pulse1

[ ping @pjsg ]

@sonaux
Copy link
Contributor

sonaux commented Sep 20, 2018

As far as I understand: pwm, pcm, sigma-delta, switec, somfy, perf modules and gpio.pulse.*, gpio.serout functions of gpio module share the same hardware timer (FRC1) available in esp8266. There is a second timer (see FRC2_COUNT_ADDRESS in eagle_soc.h), but it is not documented, except in app/pm/swtimer.c and app/include/rtc/rtctime_internal.h.
P.S. Found FRC2 registers map in xls file:
https://bbs.espressif.com/download/file.php?id=1701&sid=2e9edcea5c7d2c697611f5149fd68aef
(found at https://bbs.espressif.com/viewtopic.php?t=2537)
May be there is a reason it is not documented - for example, SDK probably uses it for WiFi...

@jmd13391
Copy link
Author

@pjsg Is there any way possible to use gpio.pulse and pwm concurrently as in the test code example above or do we need to add an "Important" cautionary text block to the gpio.pulse doc such as seen in the switec module?

Not being able to generate a variable PWM signal and a set of fixed frequency PULSE signals using the ESP8266 is a real show stopper for me.

@pjsg
Copy link
Member

pjsg commented Sep 21, 2018

The problem here is that there is a single hardware timer that is used for both of these modules. The current code does not support more than one use of the timer at the same time, so one module wins and the other loses. [There are also other modules that make use of the hardware timer that run into the same problem.]

Having said that, it ought to be reasonably easy to build a layer on top of the existing hardware timer to allow use by multiple modules. When we started out on using the hardware timers, we decided not to build this layern -- mostly to keep the code simple. I would certainly look favorably on a PR to fix this.

The relevant code is in app/platform/hw_timer.c -- there are probably five APIs that would need to be changed: platform_hw_timer_arm_*, platform_hw_timer_set_func, platform_hw_timer_get_delay_ticks, platform_hw_timer_init, platform_hw_timer_close. Happily, each of them takes a module ID as an argument, so the implementation could be changed to support multiple modules without needing to change any of the modules.

@jmd13391
Copy link
Author

@pjsg

The problem here is that there is a single hardware timer that is used for both of these modules.

-- Understood.

The current code does not support more than one use of the timer at the same time, so one module wins and the other loses. [There are also other modules that make use of the hardware timer that run into the same problem.]

-- This statement needs to be expressed in the docs for each of the modules in scope.

it ought to be reasonably easy to build a layer on top of the existing hardware timer to allow use by multiple modules

-- Would it be possible for you or one of the other crack firmware collaborators / contributors to whip this up? I lack the intimate firmware knowledge and C skills to pull it off myself.

@pjsg
Copy link
Member

pjsg commented Sep 23, 2018

It also turned out that gpio.pulse and pwm used the same 'unique' timer id which caused other problems.

@jmd13391
Copy link
Author

@pjsg You rock. This is very much appreciated. I anxiously await the dev merge so I can test it.

@jmd13391
Copy link
Author

@pjsg FYI: I grabbed a copy of gpio_pulse.c and hw_timer.c from your PR and I am happy to report that PWM and GPIO.PULSE modules now work concurrently (at least for me). Nice job!

PWM+PULSE_Code-PULSE1+PULSE2
pwm pulse_code-pulse1 pulse2

PWM+PULSE_Code-PWM+PULSE2
pwm pulse_code-pwm pulse2

@pjsg
Copy link
Member

pjsg commented Sep 23, 2018

Thank you for that test. It implies that the code works on at least two boards! Seriously, if you find any strangeness, then please let me know.

@jmd13391
Copy link
Author

jmd13391 commented Dec 6, 2018

@marcelstoer @pjsg Did this make the latest master drop?

@jmd13391 jmd13391 reopened this Dec 6, 2018
@marcelstoer
Copy link
Member

The drop is still in the making, not been merged yet: #2582. The PR to address this issue didn't make the cut, it's still open: #2497.

@jmd13391 jmd13391 mentioned this issue May 13, 2019
4 tasks
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

No branches or pull requests

4 participants