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

Support multiple tone(), analogWrite(), and Servo #4640

Merged
merged 13 commits into from
Jun 8, 2018

Commits on Apr 13, 2018

  1. Move to shared TIMER1 infrastructure, add Steppers

    Remove and rewrite all the parts of the core/libraries using TIMER1
    and consolidate into a single, shared waveform generation interrupt
    structure.  Tone, analogWrite(), Servo all now just call into this
    shared resource to perform their tasks.
    
    This setup enables multiple tones, analogWrites, servos, and stepper
    motors to be controlled with reasonable accuracy.  It uses both TIMER1
    and the internal ESP cycle counter to handle timing of waveform edges.
    TIMER1 is used in non-reload mode and only edges cause interrupts.  The
    interrupt is started and stopped as required, minimizing overhead when
    these features are not being used.
    
    Adds in control of DRV8825 or A4988 interfaces stepper motors to the
    timer infrastructure.  The interrupt handles acceleration and velocity
    of stepper pulses including jerk (dA/dt) calculations, but it is up
    to the user application to do path planning and generate S-curve
    accelerations.  All stepper DIR pins are connected together, and then
    the STEP from each stepper interface board is routed to an individual
    pin.  For motions which involve multiple steppers, there is an option
    to wait before beginning the next stepper motion until all active
    steppers have completed their moves (i.e. moving to an X, Y where there
    may be 1-2us delay between the X arrival and Y arrival).
    
    A generic "startWaveform(pin, high-US, low-US, runtime-US)" and
    "stopWaveform(pin)" allow for further types of interfaces.
    
    Using a simple USB DSO shows that with only a single channel running,
    a "tone(1000)" generates a waveform of 999.8Hz (500.1us per high/low).
    Running additional generators or steppers will potentially increase the
    jitter.
    
    The implementation also is limited in the time of the shortest pulse
    it can generate (mostly an issue for analogWrite at values <1% or
    >99% of the scale).  Presently measurements of ~2-3us are seen on
    the shortest of pulses.  There is no optimization to allow generating
    two edges on a single interrupt, which leads to this minimum pulse
    width.
    
    The current implementation was written focusing on readability and
    flexibility, not squeezing every cycle out of interrupt loops. There
    are probably many places where the code could be optimized (after it's
    fully validated!) to reduce CPU load and timing errors.
    earlephilhower committed Apr 13, 2018
    Configuration menu
    Copy the full SHA
    d48b3ba View commit details
    Browse the repository at this point in the history

Commits on Apr 14, 2018

  1. Configuration menu
    Copy the full SHA
    6bf48a8 View commit details
    Browse the repository at this point in the history

Commits on Apr 17, 2018

  1. Support busy-looping for small phase resolution

    The closest time between interrupts is about 3us, so rework the waveform
    generator to support phases down to 1us, while limiting the time in the
    IRQ handler to avoid WDT or WiFi errors.
    
    Waveforms now are based off of absolute cycle, not delta-cycles, and
    the GPIOs are converted from a bit to a mask (to save clocks in the IRQ)
    costing about 40 more bytes in global storage and reducing the minimum
    period down from 3.5us to 1.20us at 160MHz.
    
    Steppers still based off of delta-times.
    earlephilhower committed Apr 17, 2018
    Configuration menu
    Copy the full SHA
    2b1c0f0 View commit details
    Browse the repository at this point in the history

Commits on Apr 18, 2018

  1. Save 88 bytes, make 1us period exact, allow GP16 stepper

    Remove unneeded curTimeHigh/curTimeLow from the waveform structure,
    saving 88 bytes (11 pins x 8bytes) of heap.  Also reduces inner loop
    in the IRQ by an couple stores.
    
    Also add measured offset to the waveform generation request, enabling
    a 1/1000 reqest to produce a 1.083us high pulse, and a 999/1000 to
    give a 1.083 low period, and the cycle time to be exactly 1.00ms over
    the range.
    
    IRQ doesn't need to be disabled on waveform changes as the code order
    between the irq and start/stop is safe.
    
    Allow GPIO16 as a stepper out pin
    earlephilhower committed Apr 18, 2018
    Configuration menu
    Copy the full SHA
    330f9cd View commit details
    Browse the repository at this point in the history

Commits on Apr 22, 2018

  1. Configuration menu
    Copy the full SHA
    9bcb761 View commit details
    Browse the repository at this point in the history

Commits on Apr 25, 2018

  1. Remove stepper control, add callback function

    Remove the stepper code due to its size.  If it's included here it will
    take a large amount of IRAM in *all* sketches, even those which do not
    use it.
    
    Add in a traditional callback option, which will allow Stepper to be put
    in as a library, only being linked when necessary.
    earlephilhower committed Apr 25, 2018
    Configuration menu
    Copy the full SHA
    dfc7a72 View commit details
    Browse the repository at this point in the history

Commits on May 15, 2018

  1. Configuration menu
    Copy the full SHA
    b1395dd View commit details
    Browse the repository at this point in the history
  2. Configuration menu
    Copy the full SHA
    cd8de43 View commit details
    Browse the repository at this point in the history

Commits on May 23, 2018

  1. Configuration menu
    Copy the full SHA
    39d6cb3 View commit details
    Browse the repository at this point in the history

Commits on May 24, 2018

  1. Add a tone(float) method, set pin to out in tone()

    Allow tone to take a double/float as wekk as an integer frequency.
    Set the pin to an output on a tone() call to match original code.
    earlephilhower committed May 24, 2018
    Configuration menu
    Copy the full SHA
    fcb9c05 View commit details
    Browse the repository at this point in the history

Commits on May 31, 2018

  1. Configuration menu
    Copy the full SHA
    cdabb52 View commit details
    Browse the repository at this point in the history

Commits on Jun 5, 2018

  1. Configuration menu
    Copy the full SHA
    d545884 View commit details
    Browse the repository at this point in the history

Commits on Jun 8, 2018

  1. Configuration menu
    Copy the full SHA
    a56fe18 View commit details
    Browse the repository at this point in the history