aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/timers.rst
diff options
context:
space:
mode:
authorbnewbold <bnewbold@robocracy.org>2014-08-27 17:36:11 -0400
committerbnewbold <bnewbold@robocracy.org>2014-08-27 17:42:22 -0400
commit34b766c9d5f778762069938c71e052fa40455d1c (patch)
tree3a2b77e636b222fecff6366218cf7845029afecf /docs/source/timers.rst
parent746d6fecf86572c9fe95dbbffdf541a8d3875dd0 (diff)
parentadd7e54ccaf61859874527feda2b51ea172ce697 (diff)
downloadlibrambutan-34b766c9d5f778762069938c71e052fa40455d1c.tar.gz
librambutan-34b766c9d5f778762069938c71e052fa40455d1c.zip
merge libmaple docs ("leaflabs-docs") into ./docs
In the past, libample documentation was forked out of this repository because the documentation had increased in scope. For the librambutan, and the rambutan project in general, we will try to keep documentation closer to the source code, so the librambutan-specific documentation should live here. Other sections of leaflabs-docs will be culled in a following commit. This merge attempts to maintain history by using a subtree strategy. Followed directions at: http://nuclearsquid.com/writings/subtree-merging-and-you/ Full history for files should be accessible using the "--follow" flag to git log, eg: git log --follow docs/source/adc.rst It should be possible to pull patches from leaflabs-docs with: git pull -s subtree leaflabs-docs master ... at least until the docs in this repository diverge significantly.
Diffstat (limited to 'docs/source/timers.rst')
-rw-r--r--docs/source/timers.rst123
1 files changed, 123 insertions, 0 deletions
diff --git a/docs/source/timers.rst b/docs/source/timers.rst
new file mode 100644
index 0000000..0fa0976
--- /dev/null
+++ b/docs/source/timers.rst
@@ -0,0 +1,123 @@
+.. highlight:: cpp
+
+.. _timers:
+
+Timers
+======
+
+There are four general purpose timers in the Maple microcontroller
+that can be configured to generate periodic or delayed events with
+minimal work done by the microcontroller. For example, the :ref:`PWM
+<pwm>` channels can generate regular square-wave signals on specific
+output pins without consuming extra clock cycles. By attaching
+interrupt handlers to these channels (instead of just changing the
+voltage on an external pin), more complex events can be scheduled.
+
+.. contents:: Contents
+ :local:
+
+Introduction
+------------
+
+.. _timers-prescale:
+
+The four timers each have four separate compare channels. Each channel
+has an associated 16-bit counter that can be configured with a 16-bit
+prescaler and a 16-bit overflow value. The prescaler determines how
+fast the counter changes, while the overflow value determines when it
+gets reset.
+
+The prescaler acts as a divider of the 72MHz system clock. That is,
+with a prescaler of 1, the channel's counter increments with a
+frequency of 72MHz, rolling over (passing the maximum 16-bit unsigned
+integer value of 65,535) more than a thousand times a second. With a
+prescaler of 7200, it has a frequency of (72/7200) MHz = 10 KHz,
+rolling over approximately every 6.55 seconds.
+
+The overflow value is the maximum value the counter will go up to. It
+defaults to the full 65,535; smaller values will cause the counter to
+reset to zero more frequently.
+
+Whenever a channel's counter reaches its overflow value, an "update
+event" interrupt is generated. You can configure the Maple to notify
+you when this takes place, by registering an interrupt handler, which
+is a function that will be called when the update event occurs.
+
+By default, different compare values only change the relative offsets
+between events on a single timer ("phase"). They don't control the
+frequency with which they occur. However, a common trick is to
+increment the compare value manually in the interrupt handler so that
+the event will fire again after the increment period. There can be a
+different increment value for each channel, so this trick allows
+events to be programmed at 4 different rates on a single timer. Note
+that function call overheads mean that the smallest increment rate is
+at least a few microseconds.
+
+Library Documentation
+---------------------
+
+See the :ref:`HardwareTimer <lang-hardwaretimer>` reference for more
+information on controlling the built-in timers.
+
+Caveats
+-------
+
+Working with timers and interrupts can be tricky; they are a somewhat
+"advanced" topic. The following subsections explain some common
+problems associated with using timers and timer interrupts.
+
+In general: start simple, test with :ref:`lang-assert`, and don't try
+to do too much in your interrupt handlers! Make sure that what you're
+trying to do in a handler isn't going to block other interrupts from
+firing, if those other interrupts are important for your program.
+
+.. _timers-pwm-conflicts:
+
+PWM Conflicts
+^^^^^^^^^^^^^
+
+Because PWM functionality on a given pin depends on the configuration
+of the timer and channel, you must chose your channels carefully if
+you want to use both timer interrupts and PWM in the same program.
+Refer to your board's timer pin map to match up timer channels and pin
+numbers:
+
+* :ref:`Maple <maple-timer-map>`
+* :ref:`Maple RET6 Edition <maple-ret6-timer-map>`
+* :ref:`Maple Mini <maple-mini-timer-map>`
+* :ref:`Maple Native Beta <maple-native-b-timer-map>`
+
+Overhead
+^^^^^^^^
+
+There is some overhead associated with function and interrupt calls
+(loading and unloading the stack, preparing state, etc.) and this
+overhead can fudge your timing. Imperfect code branching also means
+that, e.g., channel 1 interrupts may get called a couple clock cycles
+sooner than a channel 4 interrupt, all other configuration being the
+same.
+
+Jitter
+^^^^^^
+
+Other interrupts can and will get called before or during the timer
+interrupt routines, causing pseudorandom delays and other
+frustrations.
+
+Disabling the :ref:`USB <usb>` port (by calling ``SerialUSB.end()``,
+or just running off a battery) helps a lot, but then you lose the
+auto-reset and communications functionality. This will require that
+you put your Maple into :ref:`perpetual bootloader mode
+<troubleshooting-perpetual-bootloader>` before uploading a new program
+to it (or somehow causing your program to re-enable serial over USB
+using :ref:`SerialUSB.begin() <lang-serialusb-begin>`).
+
+The :ref:`SysTick <systick>` peripheral another way to perform
+periodic or delayed events. Its separate timer does not conflict with
+any other peripherals, but the associated 1 kHz interrupt can jitter
+the general purpose timer interrupts. The SysTick peripheral can be
+disabled by calling :ref:`systick_disable()
+<libmaple-systick-disable>`, and re-enabled using
+:ref:`systick_enable() <libmaple-systick-enable>`. However, be aware
+that calling ``systick_disable()`` will stop the values coming from
+:ref:`lang-micros` and :ref:`lang-millis` from increasing.